Я запускаю консольную команду, которая извлекает все объекты одного типа (и считывает из них некоторые данные).
$q = $this->em->createQuery(/** @lang DQL */'select u from App\Entity\DataSample u order by u.creationDate ASC');
Обе стратегии итерации:
foreach ($q->getResult() as $d) {
}
а также
$iterableResult = $q->iterate();
foreach ($iterableResult as $onerow) {
/* @var $d DataSample */
$d = $onerow[0];
}
привести к ошибке сегментации!
Обратите внимание, я на самом деле ничего не делаю внутри цикла!
Второй цикл выполняется в течение нескольких десятков тысяч итераций и сегментных сбоев, а первый — в течение getResult().
Доступной памяти также достаточно, программа прерывается при использовании примерно 200 МБ памяти.
Моя трассировка xdebug мне не очень полезна, она заканчивается следующим образом:
240.2365 489614864 -> str_pad() /var/www/rrr/vendor/ramsey/uuid/src/Codec/StringCodec.php:167
240.2365 489614904 -> Ramsey\Uuid\Builder\DefaultUuidBuilder->build() /var/www/rrr/vendor/ramsey/uuid/src/Codec/StringCodec.php:84
240.2365 489615000 -> Ramsey\Uuid\Uuid->__construct() /var/www/rrr/vendor/ramsey/uuid/src/Builder/DefaultUuidBuilder.php:52
240.2365 489614448 -> Doctrine\ORM\Internal\Hydration\ObjectHydrator->hydrateColumnInfo() /var/www/rrr/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php:270
240.2365 489614448 -> Ramsey\Uuid\Doctrine\UuidType->convertToPHPValue() /var/www/rrr/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php:315
Я проверил все идентификаторы (ramsey/uuid) в соответствующей таблице, и все они возвращают true Uuid::isValid()
Забавный факт: При выводе всех id обнаружил, что это всегда происходит на одном и том же DataSample!?
Я просто обновился с 7.1.26 до 7.1.29, но не повезло.





Хорошо, я нашел "решение":
Я вставил вызов $em->clear(), а также gc_collect_cycles каждые 100 итераций, теперь он завершается (и на самом деле намного быстрее!).
$i = 0;
$iterableResult = $q->iterate();
foreach ($iterableResult as $onerow) {
/* @var $d DataSample */
$d = $onerow[0];
if ($i % 100 === 0){
$this->em->clear();
gc_collect_cycles();
}
$i++;
}
Но, очевидно, это работает только для iterableResult, использование getResult теоретически тоже должно работать??
На самом деле это не способ отладки, но попробуйте сначала обновить PHP до последней версии с исправлением ошибок - возможно, segfault исчезнет сам по себе.