node_delete "leaks memory" due to deleted nodes cached
mkalkbrenner - July 25, 2008 - 09:23
| Project: | Drupal |
| Version: | 6.x-dev |
| Component: | node system |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | reviewed & tested by the community |
Description
If you use node_delete() for mass deletion of nodes it wastes memory due to the fact that every node gets cached via node_load() before deletion. I created a patch to change that behavior.
I additionally changed the order of deleting rows form node and node_revisions tables and calls to hooks. From my point of view additional node related data from other modules should be deleted first. In other words, deleting the master data set (row in node table) should be the last step.
This change also allows to set up foreign keys in the database against the tables node an node_revisions to increase data integrity.
| Attachment | Size | Status | Test result | Operations |
|---|---|---|---|---|
| node_delete_5_8.patch | 1.19 KB | Idle | Failed: Failed to apply patch. | View details | Re-test |

#1
I found a related feature request and bug report but without patches:
#285484: Adjust node_delete
#181816: node_delete should invoke hooks before deleting rows
#2
Attached you'll find a patch against drupal 6.3 because the same issues still exist there.
But it would be nice if you also accept the patch for drupal 5.x because this is still our current production environment ;-)
#3
+1 I want this fix as well.
#4
+1 as well.
Given what I wanted too, this seems more of a feature request. That is why in my original post I think this should be farmed out to D7. New features are usually not put onto stable releases, unless absolutely necessary.
Just make a 7.x patch and have the community review it. Hopefully it'll get in.
#5
+1. I independently made the node_load($nid, NULL, TRUE) change and found it made a huge difference when deleting thousands of nodes in bulk (from a rate of about 2000 nodes deleted/minute to 45,000).
#6
+1, changed version so it has a small chance of being seen by the core developers
#7
The last submitted patch failed testing.
#8
My thoughts:
In that light, I'm providing a patch against 6.10 that addresses the memory leak only. This change is small and safe - all it does is prevent caching of nodes that are about to be deleted anyway.
#9
You stand a whole lot better chance of having this see the light of day by posting it against 7.x and noting that is also a serious bug in 6.x, but it's you call.
#10
Subscribed
#11
The patch is against Drupal 6, I haven't set up a Drupal 7 environment yet... Could someone on Drupal 7 see if the patch applies against it (or generate a patch for Drupal 7)?
#12
Subscribed
#13
Bugs are fixed in the current development branch first, then backported.
#14
The last submitted patch failed testing.
#15
In Drupal 7 this is not really fixable as we load all nodes at once with node_load_multiple and there is only one copy of them and then we pass around objects. For Drupal 6 we could try fixing it but given the behaviour in D7 I am inclined to won't fix this... if you want to delete that many nodes, batch it. Otherwise when updating to D7 your code will break again.
#16
actually, i see this as completely harmless for d6 and it fixes a bug. why would you ever cache a node that you are deleting? d7 has some big changes here but they aren't really relevant for this patch. lets let gabor and others decide.
#17
The patch actually clears off the whole runtime node cache on each node_load() called from node_delete(). The node is still cached, but all previous nodes caches are removed. So on subsequent node_delete()'s, the only cached node will be the one cached in the previous node_delete() (if there are no other node operations inbetween). Although Dave Reid suggests this as a workaround to fix memory issues at http://api.drupal.org/api/function/node_load/6#comment-69 I'm not sure people on this issue fully understand that this is what happens.
#18
Retitled to the current focus of the issue.
#19
I ran into this quirk in D6.
Besides the performance issues, it also seems to me to be incorrect behavior that it's possible to load a node which should have been explicitly deleted earlier in the session. In other words:
<?phpnode_delete($nid);
$node = node_load($nid);
?>
…gives you a node! Is it possible that there's security implications to that?