溢出sorting阶段缓冲的数据使用超过内部限制
使用代码:
all_reviews = db_handle.find().sort('reviewDate', pymongo.ASCENDING) print all_reviews.count() print all_reviews[0] print all_reviews[2000000]
计数打印2043484
,并打印all_reviews[0]
。
但是,当打印all_reviews[2000000]
,我得到的错误:
pymongo.errors.OperationFailure:数据库错误:运行器错误:溢出sorting阶段缓冲数据使用量33554495字节超过内部限制33554432字节
我该如何处理?
您正在运行内存中的32MB限制:
https://docs.mongodb.com/manual/reference/limits/#Sort-Operations
将索引添加到sorting字段。 这允许MongoDB以sorting顺序将文档stream式传输给您,而不是尝试将它们全部加载到服务器上的内存中,并在将它们发送到客户端之前将其sorting在内存中。
正如评论部分的kumar_harsh
所说,我想补充一点。
您可以使用以下命令在admin
数据库上查看当前的缓冲区使用情况:
> use admin switched to db admin > db.runCommand( { getParameter : 1, "internalQueryExecMaxBlockingSortBytes" : 1 } ) { "internalQueryExecMaxBlockingSortBytes" : 33554432, "ok" : 1 }
它有一个32 MB(33554432字节)的默认值。在这种情况下,您正在运行的缓冲区数据不足,因此您可以使用您自己定义的最佳值(例如50 MB)来增加缓冲区限制,如下所示:
> db.adminCommand({setParameter: 1, internalQueryExecMaxBlockingSortBytes:50151432}) { "was" : 33554432, "ok" : 1 }
希望这可以帮助 !!!
Note
:这个命令只支持3.0 +以后的版本
用索引解决
db_handle.ensure_index([("reviewDate", pymongo.ASCENDING)])
如果您想要避免创build索引(例如,您只需要快速检查数据),则可以使用磁盘使用情况下的聚合:
all_reviews = db_handle.aggregate([{$sort: {'reviewDate': 1}}], {allowDiskUse: true})
(不知道如何做到这一点在pymongo,虽然)。
在我的情况下,有必要修复代码中的重要索引并重新创build它们:
rake db:mongoid:create_indexes RAILS_ENV=production
由于存在需要的字段索引时不会发生内存溢出。
PS在此之前,我不得不在创build长索引时禁用错误:
# mongo MongoDB shell version: 2.6.12 connecting to: test > db.getSiblingDB('admin').runCommand( { setParameter: 1, failIndexKeyTooLong: false } )