描述:

Request processing failed; nested exception is org.springframework.data.mongodb.UncategorizedMongoDbException: Query failed with error code 17144 and error message 'Plan executor error during find: Overflow sort stage buffered data usage of 33554768 bytes exceeds internal limit of 33554432 bytes' on server mongodb:27017; nested exception is com.mongodb.MongoQueryException: Query failed with error code 17144 and error message 'Plan executor error during find: Overflow sort stage buffered data usage of 33554768 bytes exceeds internal limit of 33554432 bytes' on server mongodb:27017

请求处理失败; 嵌套的异常是org.springframework.data.mongodb.UncategorizedMongoDbException:查询失败,错误代码17144,错误消息“查找期间计划执行器错误:服务器上mongodb:27017上的33554768字节的溢出排序阶段缓冲的数据使用量超过了33554432字节的内部限制” ; 嵌套异常为com.mongodb.MongoQueryException:服务器mongodb:27017在查询中失败,错误代码为17144,错误消息“查找期间计划执行程序错误:33554768字节的溢出排序阶段缓冲的数据使用量超过了33554432字节的内部限制”

 

原因:

在使用 db.collection.find({}).sort({"update_time" : "-1"}).skip(20000).limit(20); 这种方式查询的时候,mongoDB先是按照字段"update_time"全库排序,然后再跳过前面20000条记录,再返回20条数据;其中skip操作需要将文档全部加载到缓存中,然后再抛弃这部分数据,而mongDB的缓存是有大小限制的,超过限制就会报错;

 

解决:

一:给排序字段添加索引:

  给对应的排序条件添加索引,然后skip操作就可以在索引上完成,然后不需要再加载全文档到缓存中;

db.collection.createIndex({"update_time" :  -1}, {background : true});

二:修改缓存大小限制:

use admin
db.runCommand({getParameter : 1, "internalQueryExecMaxBlockingSortBytes" : 1});  // 查询当前缓存区大小,默认是32M
db.runCommand({setParameter : 1, internalQueryExecMaxBlockingSortBytes : 335544320});    // 将当前缓存区大小设置为320M
此命令仅在3.0 +版之后支持

三:使用 aggregate() 方法查询:

  在执行一个更大规模排序时,即使已经加了索引依然超过限制,可以使用aggregate()方法的 allowDiskUse 参数设置将数据写到临时文件进行排序;

//语法:pipeline -> array, options -> document
db.collection.aggregate(pipeline, options)

//举例:
db.getCollection("topic_log").aggregate(
[
 {$sort : {"createTime" : -1}}
],
 {allowDiskUse: true}
);

 

posted on 2020-04-10 15:19  布咚嘞  阅读(914)  评论(0编辑  收藏  举报