PHP 5.2.13 MongoCursorException 'дубликат индекса ошибки ключа' - PullRequest
1 голос
/ 01 июля 2011

Я получаю дубликаты _ids при вставке документов в нашу базу данных mongo. Это периодически возникающая проблема, которая возникает только при некоторой нагрузке (воспроизводится с помощью некоторых тестовых сценариев).

Вот некоторый тестовый код, поэтому вы не думаете, что я пытаюсь дважды вставить один и тот же объект (я знаю, что драйвер PHP mongo добавляет поле _id):

// Insert a job
$job = array(
    'type'      =>  'cleanup',
    'meta'      =>  'cleaning the data',
    'user_id'   =>  new MongoId($user_id),
    'created'   =>  time(),
    'status'    =>  'pending'
);
$this->db->job->insert($job, array('safe' => true));      // <-- failz here

Я пришел в бешенство и установил последний стабильный (1.1.4) драйвер Монго, но безрезультатно. Это не под большой нагрузкой. Возможно, мы выполняем 5 запросов в секунду на одном сервере, поэтому ограничение в 16 миллионов записей в секунду для значения inc, вероятно, не является проблемой.

Любые идеи будут с благодарностью. Я надеюсь, что кто-то где-то использовал mongo с PHP и вставил более 5 документов в секунду и имел эту проблему;).

-EDIT-
На CentOS 5.4 x86_64, linux 2.6.18-164.el5xen, Apache рабочий 2.2.15, PHP 5.2.13, MongoDB 1.8.1

-EDIT2-
Как отмечено в комментариях, я использую последнюю версию драйвера PECL на данный момент (1.2.0), и проблема все еще происходит.

-EDIT3-
Забыл опубликовать точную ошибку:

Uncaught exception 'MongoCursorException' with message 'E11000 duplicate key error index: hannibal.job.$_id_ dup key

Ответы [ 2 ]

1 голос
/ 08 сентября 2015

Для этого есть другое решение (MPM преформа / рабочий не помог в моем случае, мы работали как prefork, который в любом случае используется по умолчанию).

Проблема в том, что массив вставок передаетсяпо ссылке и модифицируется библиотекой PHP MongoDB для включения идентификатора.Вам необходимо очистить идентификатор.

Итак, представьте следующий код:

$aToInsert = array('field'=>$val1);
$collection->insert($aToInsert);   << This will have '_id' added
$aToInsert['field'] = $val2
$collection->insert($aToInsert);  << This will fail with the above error

Почему?Что происходит с библиотекой:

$aToInsert = array('field'=>$val1);
$collection->insert($aToInsert);

// $aToInsert has '_id' added by PHP MongoDB library
// Therefore $aToInsert = array('field'=>$val1, '_id'=>MongoID() );

$aToInsert['field'] = $val2
// Therefore $aToInsert = array('field'=>$val2, '_id'=>MongoID() );

$collection->insert($aToInsert);
// This will not add '_id' as it already exists. But will now fail.

Решение состоит в том, чтобы повторно инициализировать массив

$aToInsert = array('field'=>$val1);
$collection->insert($aToInsert);
$aToInsert = array('field'=>$val2);
$collection->insert($aToInsert);

или сбросить идентификатор

$aToInsert = array('field'=>$val1);
$collection->insert($aToInsert);
unset($aToInsert['_id']);
$aToInsert['field'] = $val2
$collection->insert($aToInsert);  << This will now work
0 голосов
/ 13 июля 2011

Похоже, это было связано с установленной версией Apache (рабочий).После установки apache prefork мы не увидели больше повторяющихся ошибок _id на сервере.

Я предполагаю, что это как-то связано с глобальным счетчиком, который использует драйвер Mongo.Я думаю, что причиной может быть отсутствие связи между потоками ... возможно, один пул имеет счетчики экземпляров для каждого потока, но, поскольку PID одинаков, возникают конфликты.

Не знаюзнаю внутренности, но это, кажется, наиболее вероятное объяснение.Не используйте Apache Worker MPM с драйвером PHP MongoDB.Пожалуйста, прокомментируйте и исправьте меня, если это не так, или если вам известно об исправлении.

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