I have not been able to get to the root cause of this, but I have a database that returns some unusual results for very simple queries:
SELECT COUNT(nid) FROM node;
# returns 21019
SELECT COUNT(DISTINCT nid) FROM node;
# returns 0
explain SELECT COUNT(DISTINCT nid) FROM node;
# returns 1 SIMPLE node index NULL node_changed 4 NULL 20276 Using index
SELECT COUNT( vid) FROM node;
# returns 21019
SELECT COUNT(DISTINCT vid) FROM node;
# returns 21019
SELECT DISTINCT nid FROM node;
# returns a list of 21019 nids (starting at 10000)
SELECT COUNT( nid), COUNT( vid) FROM node;
# returns 21019 21019
SELECT COUNT(DISTINCT nid), COUNT(vid) FROM node;
# returns 0 21019
SELECT COUNT(DISTINCT vid) FROM node;
# returns 21019
SELECT COUNT(DISTINCT nid), COUNT(DISTINCT vid) FROM node;
# returns 0 0
The query SELECT COUNT(DISTINCT nid) FROM node; is of particular interest, because it is used in _node_access_rebuild_batch_operation(), which is the batch operation for rebuilding node access permissions. Since this query may return 0 here, and the batch process uses this for the max value, the batch gets stuck in an infinite loop because it tries to compute the completion percentage, but it's dividing by zero instead.
Since nid is the primary key in the node table , it should already be unique, so why does DISTINCT need to be used here at all? I suggest removing it. Otherwise the workaround is to use hook_batch_alter() to replace the _node_access_rebuild_batch_operation() with your own re-implementation with a corrected query. Patch fixing the query to follow.
I have not been able to replicate this in a fresh install. The database I'm working with is from a site that's been around for a while, which previously migrated from D6 by another team of developers who I don't know. So I don't rule out any oddities in database quality, but I haven't encountered any issues in collation etc., This operation has been completely re-written in D8, so presumably it's not an issue there, but I have not tested it.
Misc details:
- Drupal 7.39
- PHP 5.4.45
- MySQL Server version: 5.5.45-37.4-log Percona Server (GPL), Release 37.4, Revision 042e02b
| Comment | File | Size | Author |
|---|---|---|---|
| #2 | node_access_rebuild_distinct-2596899-2.patch | 596 bytes | bburg |
Comments
Comment #2
bburgPatch removes the DISTINCT qualifier from the query.
Comment #3
David_Rothstein commentedYeah, the DISTINCT doesn't seem like it should be necessary. However it also seems like it should be harmless, and:
These results definitely look crazy :) When I run it on my own site all three give the same number of rows. I really don't get how those could give three different results unless there's something really weird going on with the database, but I can't even imagine what...
Comment #4
bburgPossibly a database encoding issue? I didn't get that deep when debugging the problem, and have since moved on.
Comment #5
bburgI was discussing this bug with some of my colleagues, and we found this bug report against MySQL: http://bugs.mysql.com/bug.php?id=30402.
So that's a good explanation of what might be driving this issue. The bug seems to have been verified in versions 5.6.12, and the issue itself is still just a "verified" state.
Comment #6
David_Rothstein commentedHm, interesting. Well, the patch is harmless (and node access rebuilds still work correctly with it) so I guess we can just do it, even if it is working around someone else's bug.
Looks from https://api.drupal.org/api/drupal/core!modules!node!node.module/function... like Drupal 8 won't need this, only Drupal 7.
Comment #7
David_Rothstein commentedCommitted to 7.x - thanks!