文档长度不等于缓冲区

时间:2016-02-19 21:57:26

标签: php mongodb buffer document

尝试使用PHP脚本浏览我的某个集合中的所有文档时遇到问题。该集合有大约500k文件。该数据库运行的是Mongo 2.6.9,在Ubuntu 14.04上运行。我使用这种语法来搜索collecton:

$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
}

长度变化。我看过十几种不同的长度。每次运行此脚本时,它都会获得不同百分比的集合。有时它会在4k文档之后抛出此异常,有时是180k。我确信我一直在对集合进行更改,它是一个不断更新的生产数据库

1 个答案:

答案 0 :(得分:0)

对于将来可能遇到此问题的任何人,我会发布我认为是导致问题的原因以及我采取的解决问题的步骤。

首先,最后重新启动我的mongodb服务器一次解决了我的问题。如果您正在运行功能复制集,那么首先尝试这一点(在我下面概述的所有工作之前)。

问题是由在我们的复制集的PRIMARY节点上创建索引的人创建的,而没有明确指示“在后台”创建索引(这是有问题的)。然后我创建了各种索引,并设置了“背景”选项(不是问题的一部分)。当我开始收到此错误消息时,我删除了所有索引,但它们仍保留在内存中(甚至可能在PRIMARY上的文件锁定 - 未经验证)。

要解决此问题,我将每个成员(逐个)脱机,并将其带到另一个(随机)端口上(因此他们不会与该设备通信):

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服务并在正常情况下重新启动它,以便它再次成为副本集的一部分。

这些步骤应足以解决问题,但我发现每个节点(特别是PRIMARY)的完全重启是我的错误消息最终消失的必要条件。这可能是值得尝试的。