So this past day I have been responding to a bizarre sudden loss of the ability to edit or create nodes on our site. Restoring to an earlier database snapshot resolved the problem, so I set to nailing down what table exactly was the bad egg. It turned out to be Role. It turned out that creating any additional role past the last db snapshot would cause any attempt to create or edit a node to reach the PHP timeout and abort.
After identifying role as the table, I then proceeded through elimination to identify advcache as the module killing the server. And then I discovered this code in advcache.module (lines 46-39 of advcache.module)
function advcache_nodeapi($node, $op) {
switch ($op) {
case 'update':
case 'insert':
case 'delete':
global $user;
$int = advcache_array2int($user->roles);
if (!in_array($node->type, variable_get('advcache_node_exclude_types', array('poll')))) {
$maxrole = pow(2, (int)db_result(db_query("SELECT MAX(rid) FROM {role}")) - 1);
for ($i = 1; $i < $maxrole; $i++) {
cache_clear_all($node->nid. '::'. $i, 'cache_node');
}
}
// It is unfortunate that we have to use the wildcard here, but it
// comes from the fact that the signature to taxonomy_node_get_terms
// has a $key parameter which goes into building the cache key, which
// we can't reliably reconstruct here.
cache_clear_all('node::'. $node->nid, 'cache_taxonomy', TRUE);
if ($node->type == 'forum') {
cache_clear_all('*', 'cache_forum', TRUE);
}
break;
}
}
More specifically, lines 54-57:
$maxrole = pow(2, (int)db_result(db_query("SELECT MAX(rid) FROM {role}")) - 1);
for ($i = 1; $i < $maxrole; $i++) {
cache_clear_all($node->nid. '::'. $i, 'cache_node');
}
I could not believe what I was seeing. The max of role.rid on my site is 31. so we are seeing a loop from 1 to 2^31 which is 1073741824!!! This strikes me as obviously a deliberate decision. I just cannot for the life of me understand how this came to be. And in such a place as hook_nodeapi!
I have never in all my days as a developer come across a bug so bizarre. Again, this was obviously a deliberate choice. I cannot for the life of me begin to grasp why. And I can't understand why there is no other issue about this (insofar as I have seen, at least)
There must be some brilliant idea behind this. I should like very much to hear it. I'm sure I could learn something.
Comments
Comment #1
reubenavery commentedthis is so truly astonishing to me, i feel inclined to print it out and paste it on my refrigerator. truly, i am impressed. i have dealt with many an other programmer's bug in my day.. this one takes the cake.
Comment #2
firebus commentedhttp://drupal.org/node/199465 is the one with the most discussion
http://drupal.org/node/188085 is also germane