我正在尝试将文档保存到mongoDB集群(分片副本集),并且遇到了一个奇怪的问题。我使用的是pymongo 2.7.2和TokuMX 1.5 mongodb 2.4.10。
当我尝试保存(覆盖)现有文档时,我收到的异常看起来像我保存的文档太大了:
doc = db.collection.find_one()
db.collection.save(doc)
pymongo.errors.OperationFailure: BSONObj size: 18798961 (0x71D91E01) is invalid. Size must be between 0 and 16793600(16MB) First element: op: "u"
然而,这很好用:
doc = db.collection.find_one()
db.collection.remove({'_id': doc['_id']})
db.collection.save(doc)
有问题的文件约为9mb,所以看起来当我试图更换文件时,它会以某种方式加倍文件的大小,超过16mb的限制。
关于什么可能导致这种行为的任何想法?
答案 0 :(得分:1)
显然这是与TokuMX的known issue。 Oplog条目的大小是文档的两倍,因此替换9mb文档将导致18mb的oplog条目 - 这会引发异常。
解决方案是将文档写入限制在8mb以下,以便oplog条目永远不会超过16mb。
答案 1 :(得分:0)
我认为这是在PyMongo中如何实现保存的副作用。
如果文档中包含_id
,那么保存(doc)将变为更新(doc,doc)。这是加倍发挥作用的地方,因为查询+更新是18MB。
删除_id后,您将保存(doc)更改为带有新_id
的新文档的插入(doc)。我认为这不是你想要的。
而不是使用保存我建议只使用原始文档中的_id
字段构建查询并手动执行更新调用。我甚至会进入Jira票,让PyMongo为你做这件事。
HTH, 罗布。