From 5be1de31ae1664917cd36141d743b5e8fd95cac6 Mon Sep 17 00:00:00 2001
From: David Rothstein <drothstein@gmail.com>
Date: Fri, 31 Jan 2014 15:27:33 -0500
Subject: [PATCH] Issue #2174551 by David_Rothstein, mikeytown2, hswong3i:
 Taxonomy_update_7011 runs out of memory.

---
 CHANGELOG.txt                     |  3 +++
 modules/taxonomy/taxonomy.install | 25 +++++++++++++++++++++++--
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 68bcd4f44e0f..6baf6254c140 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,6 +1,9 @@
 
 Drupal 7.27, xxxx-xx-xx (development version)
 -----------------------
+- Fixed up a bug in the Taxonomy module update function introduced in Drupal
+  7.26 that caused memory and CPU problems on sites with very large numbers of
+  unpublished nodes.
 
 Drupal 7.26, 2014-01-15
 ----------------------
diff --git a/modules/taxonomy/taxonomy.install b/modules/taxonomy/taxonomy.install
index e3603e1accfd..ebd0084a5196 100644
--- a/modules/taxonomy/taxonomy.install
+++ b/modules/taxonomy/taxonomy.install
@@ -903,13 +903,34 @@ function taxonomy_update_7010() {
 /**
  * Drop unpublished nodes from the index.
  */
-function taxonomy_update_7011() {
-  $nids = db_query('SELECT nid from {node} WHERE status = :status', array(':status' => NODE_NOT_PUBLISHED))->fetchCol();
+function taxonomy_update_7011(&$sandbox) {
+  // Initialize information needed by the batch update system.
+  if (!isset($sandbox['progress'])) {
+    $sandbox['progress'] = 0;
+    $sandbox['max'] = db_query('SELECT COUNT(DISTINCT n.nid) FROM {node} n INNER JOIN {taxonomy_index} t ON n.nid = t.nid WHERE n.status = :status', array(':status' => NODE_NOT_PUBLISHED))->fetchField();
+    // If there's no data, don't bother with the extra work.
+    if (empty($sandbox['max'])) {
+      return;
+    }
+  }
+
+  // Process records in groups of 5000.
+  $limit = 5000;
+  $nids = db_query_range('SELECT DISTINCT n.nid FROM {node} n INNER JOIN {taxonomy_index} t ON n.nid = t.nid WHERE n.status = :status', 0, $limit, array(':status' => NODE_NOT_PUBLISHED))->fetchCol();
   if (!empty($nids)) {
     db_delete('taxonomy_index')
       ->condition('nid', $nids)
       ->execute();
   }
+
+  // Update our progress information for the batch update.
+  $sandbox['progress'] += $limit;
+
+  // Indicate our current progress to the batch update system, if the update is
+  // not yet complete.
+  if ($sandbox['progress'] < $sandbox['max']) {
+    $sandbox['#finished'] = $sandbox['progress'] / $sandbox['max'];
+  }
 }
 
 /**
-- 
GitLab