Утечка памяти или проблемы с wp_insert_post()
Написал плагин импорта записей со стороннего API. Новые записи кастомный тип постов.
Всё работает хорошо и без проблем в случаях когда записи на создание/обновление приходило в пределалах 150.
Возник случай когда записей пришло 1500 и выделенные 512Мб на сервере стало не хватать.
С помощью:
memory_get_usage()
Выявил момент когда возникает рост памяти.
wp_insert_post(); // обновляем/сохраняем пост рост на 0,1 wp_update_post(); // привязываем картинку рост на 0,3
После сохранения/обновления поста и картинки к нему потребление памяти возростает на 0,1 - 0,4 Мb.
В итоге с начала работы скрипта 42Mb постепенно обходя записи в цикле память заполняется и вылетает ошибка.
Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 319488 bytes) in /home/soaresmendonca/web/soaresmendonca.pt/public_html/wp-includes/wp-db.php on line 2984 Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 266240 bytes) in /home/soaresmendonca/web/soaresmendonca.pt/public_html/wp-includes/wp-db.php on line 2033
Сталкивался ли кто с такой проблемой или знаете как устранить этот дефект?
Вот еще вариант, технически для WP самый подходящий в этом случае. См. функцию wp_suspend_cache_addition() в частности второй пример:
Допустим, мы импортируем большой массив данных в WordPress. К примеру, нам нужно заполнить таблицу записей из другой базы данных...
Проблема тут в том, что ВП очень многое, в частности записи, всегда кэширует в память - вот и переполняется.
Хорошее решение, и переделать быстро.
Так и должно быть.
Вам надо разбивать операции и обрабатывать порциями.
Например по 100 постов.
Так почему так быть должно? Почему после вставки записи, когда всё уходит в БД в памяти остаётся что-то и копится.
Вариант разбвики на пачки по 100 записей даже пока и не знаю как задачу что выполняет cron разбить на мелкие части, но если решения не найдётся, то буду переделывать.
А если вы еще работаете с картинками то вообще надо разбивать операции по каждому посту отдельно, генерация всех миниатюр дело затратное...
В общем буду разбираться.
Добавил принудительный вызов GC после вставки каждого поста.
Ни чего не поменялось.
Возможно проблема в том, что запись после добавления попадает в объектный кеш.
Можно попробовать после добавления записи удалять ее из кеша
Оно! Спасибо!
Память перестала расти.
Увы, не помогло
Решение этой проблемы описал Kama, оно и отмечено как решение этой для этой темы. Сам переделал так и уже долгое время работает без проблем.
При выполнении операций импорта с большим количеством данных стоит использовать библиотеку
https://github.com/deliciousbrains/wp-background-processing
она позволит запустить процедуру импорта каждого элемента как отдельный процесс, при этом сама задача будет работать в фоновом режиме.
Спасибо! Попробую обсудить с проджектом этот момент, может и переделаю. А на будущее уже буду рассматривать сразу эту библиотку.