Problem/Motivation
Code runs out of memory when entity indexing runs after deleting and creating about 5000 nodes.
After custom code has created all the nodes and saved the user, console starts to throw these warnings:
[warning] Could not load the following items on index Employees: "entity:user/49:en-x-simple", "entity:user/49:und", "entity:user/49:zxx", "entity:user/50:en-x-simple", "entity:user/50:und"......
After about 2000 warnings later, OOM happens:
PHP Fatal error: Allowed memory size of 1073741824 bytes exhausted (tried to allocate 20480 bytes) in /Users/myuser/www/docker-sites/some-drupal-site/web/core/lib/Drupal/Core/Field/FieldItemBase.php on line 109
Since the loop to create content in my code creates all the content and warnings start to appear after that, I suspect the error to be somewhere else.
Details about the issue
Site has a content type "contracts".
User has a multi-value entity reference field to the "contract".
Then there is a custom code, executed via Drush that fails with OOM:
- Deletes all content of a type "contract" (using the entityTypeManager, loadMultiple->delete()).
- LOOP STARTS to go through an array of data for contract creation
- Creates contract (
using Node::create()) - Attaches contract to the user (by setting target_id on a user contract reference field)
- Saves the user (
$user->save()) - All contracts are successfully created
- LOOP ENDS
- Now console starts showing these mentioned warnings
- With each warning memory usage increases
- After about 2000 warning messages, script dies with OOM error
I've added a quick memory usage dump to the place where the warning is coming from (file: web/modules/contrib/search_api/src/Entity/Index.php, line 903):

- Memory usage when the first warning came: 385654 kB
- Memory usage when the script failed: 1032739 kB
- With each warning, memory usage increased around 3952 kB (+- 1000 kB).
Any ideas are appreciated and I'm open to help with debugging to trace it down.
| Comment | File | Size | Author |
|---|---|---|---|
| #4 | 3321677-4--indexing_memory_exhaustion.patch | 929 bytes | drunken monkey |
| #3 | search_api-post-request-indexing-memory-1.patch | 930 bytes | david.muffley |
| Screenshot 2022-11-15 at 21.57.50.png | 108.34 KB | adroid |
Comments
Comment #2
adroid commentedComment #3
david.muffley commentedI had a similar issue and I resolved it by resetting the cache of each indexed entity in PostRequestIndexing.php. My solution is just a bandaid to get past the issue I was having and has several holes in its implementation. Specifically it only resets the cache of the top-level indexed entities, any child entities that were loaded during the indexing action are not cleared. I'll attach it anyway as a starting point for further development.
Comment #4
drunken monkeyThanks for reporting this problem!
If it’s custom code that is creating those items then a very simple solution would be to just call
$search_api_index->startBatchTracking()at the start of the process, which prevents all the new items from being indexed in the same page request.Also, we already have a very similar solution to #3 in our indexing code, namely at the bottom of
\Drupal\search_api\Entity\Index::indexSpecificItems(). However, it currently only applies during indexing via Drush, but that could easily be changed – see the attached patch.As only very few places in our code call this method, I think it should be safe to just do this generally. Worst case, some page request which do indexing in the middle (not at the end, with
PostRequestIndexing) will be slowed down a bit – I think. No real way to be certain, I fear.Comment #5
sonnyktIt seems that Drush detection in the issue #3036504 no longer works with both Drush 11 and 12.
When running cron with Drush 11/12, the memory usage keeps increasing and OOM is inevitable:
Applying the patch from #4 seems to fix the OOM issue.
Comment #6
sonnyktComment #8
drunken monkeyThanks for this additional information. If it also fixes Drush indexing, then I guess I’d really say we should go forward with it. “Normal” page requests should never index items during the request, anyways, so I don’t think there is a high potential for this breaking anything.
Merged. Thanks again, everyone!