刘兴起

I am coder. Currently doing more in backend, focused in Ruby and Python.

Mongodb 常见问题处理

02 Jul 2018 » mongodb, database

1. How to kill slow query?

db.currentOp()
# find opid
db.killOp(opid)

2. Mongo::Error::OperationFailure: Cursor not found

什么是 cursor?

cursor 并不是查询结果,可以理解成是数据在遍历过程中的内部指针,其返回的是一个资源或者说是数据读取的接口. db.collection.find() 会返回一个 cursor,为了获取文档,你需要去遍历这个 cursor.

iterate-a-cursor

Mongodb server 会批量返回查询结果,其数据量不能超过 maximum BSON document size(默认 16 M). find()aggregate() 操作会默认批量的返回 101 个文档。

cursor-batches

为什么 cursor 会找不到?

Mongodb server 会自动关闭10分钟后不活跃的 cursor,或者是客户处理完的所有的 cursor。所以如果一个 batch 内的 文档在10分钟内没有处理完,当前 cursor 会被关闭,之后处理完了,再用同一个 cursor 向服务器获取下一个 batch 的 cursor 时,这个 cursor 已经过期了,所以会报 cursor 找不到的错误。

closure-of-inactive-cursors

解决方案

  1. 使用 cursor.noCursorTimeout() 方法,去掉时间限制;
  2. 使用 batch_size() 方法,减少批量返回的数据,避免单个 batch 处理时间过长;