MongoDB - PHP - MongoCursorException «Курсор не найден» - PullRequest
6 голосов
/ 24 июля 2011

У меня есть 2 коллекции: A (3,8 млн документов) и B (1,7 млн ​​документов)

У меня есть PHP-скрипт, который я запускаю из оболочки, который:

  1. циклынад каждой записью в A
  2. ~ 60% времени он выполняет findOne для B (используя _id)
  3. выполняет некоторые базовые вычисления, создавая массив php

как только цикл по всем документам в a завершен:

4) цикл по массиву php

5) вставка в коллекцию C

во время (1), я последовательноget: PHP Неустранимая ошибка: необработанное исключение «MongoCursorException» с сообщением «Курсор не найден» Последний обработанный элемент был # 8187 из 3872494.

real    1m25.478s
user    0m0.076s
sys     0m0.064s

Повторный запуск без изменения в коде, исключение полученоброшенный в предмет # 19826/3872495

real    3m19.144s
user    0m0.120s
sys     0m0.072s

И снова # 8181/387249

real    1m31.110s
user    0m0.036s
sys     0m0.048s

Да, я понимаю, что могу (и, вероятно, должен) поймать исключение ...но ... почему его даже бросают?Особенно в такое разное время / глубину в базу данных.

Если это поможет, моя установка - это набор из трех узлов (2 + arb).Я перевел вторичное устройство в автономный режим и попыталось запустить только основное.Те же результаты (различное количество обработанных результатов и раз, но всегда выдает исключение Cursor Not Found).

Ответы [ 3 ]

10 голосов
/ 24 июля 2011

Да, я понимаю, что могу (и, вероятно, должен) поймать исключение ...

Да, это определенно первое, что нужно сделать.Есть десятки законных причин для исключения?Черт, что, по вашему мнению, происходит, когда основной объект отключается и становится недоступным?

... почему его даже выбрасывают?

Есть паравозможные причины, но давайте обратимся непосредственно к коду ошибки, который вы видите.

  • Официальные документы по PHP здесь .
  • Цитата с этой страницы: Драйвер пытался получить больше результатов из базы данных, но в базе данных не было записи запроса.Обычно это означает, что время ожидания курсора на стороне сервера ...

Драйвер PHP MongoDB имеет два разных времени ожидания:

  • Время ожидания подключения
  • Время ожидания курсора

Время нажатия курсора.Вы можете подключиться к БД, но ваш запрос «не хватает времени».

Возможные исправления:

  1. Расширить курсор timeout .Или вы можете установить его на ноль и сделать так, чтобы он длился вечно.
  2. Делайте эту работу партиями.Получите первые 1000 _ids от A, обработайте их и отметьте, что вы сделали это.Затем получите следующую 1000 _ids больше, чем ваш последний запуск и т. Д.

Я бы предложил # 2 наряду с обработкой исключения.Даже если это не решит проблему полностью, она поможет вам изолировать и смягчить проблему.

4 голосов
/ 18 октября 2011

Я знаю, что уже поздно, и, возможно, это не ваше решение, но вы можете попробовать использовать immortal (). Как отметил вице-президент Gates, эта страница описывает исключение.

Драйвер пытался получить больше результатов из базы данных, но в базе данных не было записи запроса. Обычно это означает, что время ожидания для курсора на стороне сервера истекло: после нескольких минут бездействия база данных прекратит работу курсора (см. MongoCursor :: immortal () , чтобы узнать, как это предотвратить).

Я подумал, что выложу полное описание для других пользователей, достигших этой страницы, и так как timeout () и immortal () различаются. timeout () устанавливает время ожидания ответа. immortal () не позволяет курсору умереть из-за неактивности.

0 голосов
/ 24 июля 2011

Это может быть проблема с ограничением памяти. Попробуйте поэкспериментировать с предоставлением большего объема памяти и посмотрите, будут ли отличаться ваши результаты, что можно сделать с помощью опции -d: php -d memory_limit = 256M yourscript.php

Это много документов, и кажется, что вы делаете довольно большой массив объектов. Существуют также различные функции php, например memory_get_usage (), которые вы можете использовать для профилирования распределения памяти во время выполнения, а также для отладки расширений, таких как xdebug или что предоставляет zend.

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