I'm using the dev version dated 2008-Aug-05. On trying to delete 2500 articles, I get the error message:

Fatal error: Allowed memory size of 25165824 bytes exhausted (tried to allocate 1190 bytes) in /mypath/public_html/includes/database.mysql-common.inc on line 41

I had already increased my PHP memory allocation, by adding the following line to my .htaccess file:
php_value memory_limit 24M

I suspect that if I increased the memory allocation further, this error would disappear, though it would be nice if the error was (a) caught (b) the program deleted the nodes a small batch at a time.

For anyone interested, it took 1 minutes and 20 seconds to process the removal 2370 records, leaving just 130, which were deleted without problem.

Comments

iantresman’s picture

I can confirm that by increasing my PHP memory limit to 32M, prevented the error message.

kbahey’s picture

Status: Active » Fixed

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

gabor_h’s picture

I leave the "closed" status of this issue, although in my experience the deletion of tens of thousands of nodes results in "Fatal error: Allowed memory size exhausted". No matter what the PHP memory limit is, sooner or later it is reached.

So for those who would like to regularly delete a huge number of nodes , here is the solution I used:

1. Take the code of node_delete(), see e.g. http://api.drupal.org/api/function/node_delete/6
2. Copy/paste this function to delete_all.module, and rename it to _modified_node_delete()
3. Uncomment the function calls of watchdog and drupal_set_message in this _modified_node_delete() function.
4. Modify _delete_all_normal() in delete_all.module to call this _modified_node_delete() instead of node_delete().
5. Additionally I also removed cache_clear_all() from _modified_node_delete(), and moved it to the end of _delete_all_normal(), I put it just before "return $deleted".

This way I can delete over 100000 nodes without timeout or memory exhaustion.

Here is the result of the above steps:

function _modified_node_delete($nid) {

  // Clear the cache before the load, so if multiple nodes are deleted, the
  // memory will not fill up with nodes (possibly) already removed.
  $node = node_load($nid, NULL, TRUE);

  if (node_access('delete', $node)) {
    db_query('DELETE FROM {node} WHERE nid = %d', $node->nid);
    db_query('DELETE FROM {node_revisions} WHERE nid = %d', $node->nid);

    // Call the node-specific callback (if any):
    node_invoke($node, 'delete');
    node_invoke_nodeapi($node, 'delete');

    // Clear the page and block caches.
// MODIFIED LINE:    
//    cache_clear_all();

    // Remove this node from the search index if needed.
    if (function_exists('search_wipe')) {
      search_wipe($node->nid, 'node');
    }
// MODIFIED LINE:    
//    watchdog('content', '@type: deleted %title.', array('@type' => $node->type, '%title' => $node->title));
// MODIFIED LINE:    
//    drupal_set_message(t('@type %title has been deleted.', array('@type' => node_get_types('name', $node), '%title' => $node->title)));
  }
}

function _delete_all_normal($all, $types) {
  if ($all) {
    $result = db_query('SELECT nid FROM {node}'. $where);
  }
  else {
    $placeholders = implode(',', array_fill(0, count($types), "'%s'"));
    $result = db_query('SELECT nid FROM {node} WHERE type IN ('. $placeholders .')', $types);
  }

  $deleted = 0;
  while ($data = db_fetch_object($result)) {
    set_time_limit(30);
// MODIFIED LINE:    
    _modified_node_delete($data->nid);
    $deleted ++;
  }
  // Clear the page and block caches.
// MODIFIED LINE:    
  cache_clear_all();
  return $deleted;
}

Personally, I do not ask the maintainers to modify the delete_all.module, it is up to them, but I am happy to share this with those who need to delete many many many nodes.