Я сталкиваюсь с проблемой при попытке просмотреть все документы в одной из моих коллекций, используя скрипт PHP. В коллекции около 500 тыс. Документов. База данных работает под управлением Mongo 2.6.9, работает под управлением Ubuntu 14.04. Я использую этот синтаксис для поиска по коллекции:
$mongo = new MongoClient("mongodb://192.168.2.2:27017,192.168.2.3:27017/products?replicaSet=preplset");
$products = $mongo->products->content;
$cursor = $products->find();
while($cursor->hasNext() !== false) {
echo "some information";
}
Я получаю следующее сообщение об ошибке (дамп стека):
object(MongoCursorException)#24 (8) {
["message":protected]=> string(61) "Document length (74 bytes) is not equal to buffer (219 bytes)"["string":"Exception":private]=> string(0) ""["code":protected]=> int(42)
["file":protected]=> string(41) "...script.php"["line":protected]=> int(29)
["trace":"Exception":private]=>
array(1) {
[0]=> array(6) {
["file"]=> string(41) "...value.php"["line"]=> int(29)
["function"]=> string(7) "getNext"["class"]=> string(11) "MongoCursor"["type"]=> string(2) "->"["args"]=> array(0) {}
}
}
["previous":"Exception":private]=> NULL
["host":"MongoCursorException":private]=> NULL
}
Длина меняется. Я видел дюжину разных длин. Каждый раз, когда я запускаю этот скрипт, он проходит через различный процент коллекции. Иногда выдает это исключение после 4 тыс. Документов, иногда 180 тыс. Я уверен, что в коллекцию постоянно вносятся изменения, это производственная база данных, которая постоянно обновляется
Для тех, кто может столкнуться с этой проблемой в будущем, я опубликую то, что я назвал причиной моей проблемы, и шаги, которые я предпринял для ее решения.
Прежде всего, перезапуск серверов mongodb по одному решил мою проблему. Если вы используете функциональный набор репликации, возможно, стоит сначала попробовать (перед всей работой, которую я опишу ниже).
Проблема была создана кем-то, кто создавал индекс на ПЕРВИЧНОМ узле нашего набора репликации, не указав специально для создания индекса «в фоновом режиме» (это проблематично). Затем я создал множество индексов с опцией «background» (не является частью проблемы). Когда я начал получать это сообщение об ошибке, я удалил все индексы, но они остались в памяти (и, возможно, даже при блокировке файла в PRIMARY —unverified).
Чтобы решить эту проблему, я перевел каждого участника (одного за другим) в автономный режим и перевел их в оперативный режим на другом (случайном) порту (чтобы они не связывались с набором):
sudo mongod --port 44444 --dbpath /path/to/mongodb/files/ #default is /data/db
(путь был нужен, потому что мой находится не в месте по умолчанию)
Как только каждый сервер был загружен сам по себе, я удалил все индексы и воссоздал только те, которые мне действительно нужны (а затем повторно проиндексировал, чтобы убедиться, что они чистые):
db.collection.dropIndexes() #this drops all indexes except _id index
db.collection.createIndex( { *indexfield*: 1 } ) #1 or -1 for ASC or DESC
db.collection.reIndex() #probably not necessary
Затем я вышел из службы mongodb и перезапустил ее в обычных условиях, чтобы она снова стала частью набора реплик.
Этих шагов должно быть достаточно для решения проблемы, но я обнаружил, что полная перезагрузка каждого из узлов (в частности, ПЕРВИЧНОГО) была необходима для того, чтобы мои сообщения об ошибках наконец исчезли. Это может стоить попробовать в первую очередь.
Других решений пока нет …