Ошибки сегментации во время гидратации доктрины - как отладить? - PullRequest
0 голосов
/ 16 мая 2019

Я запускаю консольную команду, которая выбирает все объекты одного типа (и считывает некоторые данные из них).

$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()

Интересный факт: При выводе всех идентификаторов я обнаружил, что это всегда происходит в одном и том же образце данных!?

1 Ответ

0 голосов
/ 17 мая 2019

Хорошо, я нашел «решение»:

Я вставил вызов $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 ??

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...