在将文档插入我们的mongo数据库时,我得到重复的_ids。这是一个间歇性问题,只在某些负载下发生(可以通过某些测试脚本重现)。
这是一些测试代码,所以你不认为我试图双重插入同一个对象(我知道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)mongo驱动程序无济于事。这不是重负荷。我们在一台服务器上执行的操作可能是5 req / s,因此inc值的16M rec / s限制可能不是问题。
任何想法都将不胜感激。我希望有人在某处使用mongo和PHP并插入超过5个docs / s并且遇到了这个问题;)。
CNC中
在CentOS 5.4 x86_64,linux 2.6.18-164.el5xen,Apache worker 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
答案 0 :(得分:1)
对此有一个不同的解决方案(预制棒/工人MPM在我的情况下没有帮助,我们以prefork的形式运行,无论如何都是默认的。)
问题是插入数组是通过引用传递的,并由PHP MongoDB库修改以包含ID。您需要清除ID。
想象一下下面的代码:
$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);
或取消设置ID
$aToInsert = array('field'=>$val1);
$collection->insert($aToInsert);
unset($aToInsert['_id']);
$aToInsert['field'] = $val2
$collection->insert($aToInsert); << This will now work
答案 1 :(得分:0)
看起来它与安装的Apache版本(worker)有关。安装apache prefork之后,我们发现服务器上没有更多重复的_id错误。
我的猜测是这与Mongo驱动程序使用的全局计数器有关。我认为线程之间缺乏通信可能是原因...也许一个池有每个线程的实例计数器,但由于PID是相同的,你会遇到冲突。
我不知道内部,但这似乎是最可能的解释。不要将Apache Worker MPM与PHP MongoDB驱动程序一起使用。如果不是这样,或者您知道修复,请发表评论并纠正我。