mongo MongoCursorNotFoundException在长时间运行的查询循环中



我有一个简单的查询循环,在大约93分钟内处理了96945个文档中的44000个文档后,它会得到MongoCursorNotFoundException。

MongoIterable<MasterDocument> query = masterCollection.find().noCursorTimeout(true);
for (MasterDocument masterDocument : query) { ... do some stuff ... }

";做一些事情";部分需要一段时间,这就是为什么整个循环需要这么长时间。

我的问题是,在处理了集合中可能一半的文档后,我会出现此异常。

我在Windows10笔记本电脑上本地运行客户端应用程序和mongod服务器,通过localhost访问服务器。

服务器日志显示了很多这样的消息:

{"t":{"$date":"2021-01-04T20:21:35.510-08:00"},"s":"I",  "c":"COMMAND",  "id":51803,   "ctx":"conn27","msg":"Slow query","attr":{"type":"command","ns":"master_database.MasterCollection","command":{"find":"MasterCollection","filter":{"hashCode":1753339282},"$db":"master_database","lsid":{"id":{"$uuid":"6a252f51-2c6e-4c01-ae03-1a80aab109e0"}}},"planSummary":"COLLSCAN","keysExamined":0,"docsExamined":96944,"cursorExhausted":true,"numYields":96,"nreturned":0,"queryHash":"DBC59907","planCacheKey":"DBC59907","reslen":121,"locks":{"ReplicationStateTransition":{"acquireCount":{"w":97}},"Global":{"acquireCount":{"r":97}},"Database":{"acquireCount":{"r":97}},"Collection":{"acquireCount":{"r":97}},"Mutex":{"acquireCount":{"r":1}}},"storage":{},"protocol":"op_msg","durationMillis":147}}

最后一条消息后面跟着:

{"t":{"$date":"2021-01-04T20:21:35.521-08:00"},"s":"I",  "c":"NETWORK",  "id":22944,   "ctx":"conn27","msg":"Connection ended","attr":{"remote":"127.0.0.1:58990","connectionId":27,"connectionCount":14}}

{"t":{"$date":"2021-01-04T20:21:35.522-08:00"};s":"I"c":"网络"id":22944;ctx":"conn26"msg":"连接结束"attr":{"远程":"127.0.0.1:58989","连接ID":26,"连接计数":13}}{"t":{"$date":"2021-01-04T20:21:35.922-08:00"};s":"I"c":&quot-&"id":20883;ctx":"conn25"msg":"由于其客户端断开连接而中断操作"attr":{"opId":310196}}

我试过:

  • 使用";noCursorTimeout(true(";在查询光标上(如上所示(
  • 用"0"启动服务器;mongod--setParameter localLogicalSessionTimeoutMinutes=240";。这最后一个似乎引起了附加的日志消息;错误":"Location13111:字段(expireAfterSeconds(长度的类型错误!=int">

我使用的是mongod4.4和最新的mongojavaapi。

您可能需要将所有碎片和mongos:中的默认光标空闲超时值增加到更大的值

检查参数(默认值为10分钟=600000毫秒(:

use admin
db.runCommand({getParameter:1, cursorTimeoutMillis: 1})

并更新为更大的值:

use admin
db.runCommand({setParameter:1, cursorTimeoutMillis: 600000000 })

日志中的COLSCAN也表明您在查询中不使用索引,也许您需要在"上创建一个索引;hashCode"。。

感谢您的回复。

事实证明,一旦我开始用"--setParameter localLogicalSessionTimeoutMinutes=240,尽管我在控制台日志中看到了错误消息。

你说得对,我应该在";hashCode";。(我以前有一个,但在重新创建集合后忘记了重新创建。(

最新更新