有网友反馈py-mongo-sync同步异常,检查发现curosr[0]取查询结果第一个文档时报错”no such item for Cursor instance”。

这里的逻辑是,根据timestamp查询oplog起始位置,cursor类型是TAILABLE,然后取出第一条oplog,验证timestamp是否一致。

对方mongo版本是v3.4,同步工具在v3.2及更早版本的MongoDB上还没出过类似问题。
使用pymongo 3.5.1(最新版本)分别用v3.2和v3.4跑同步测试,在query结果非空的情况下,v3.2正常,v3.4报错,怀疑是不是v3.4做了什么改动,导致dirver不兼容。

进一步排查,cursor[0]读取文档,db端返回了一个错误,意思说tailable和singleBatch两个选项冲突。

{'number_returned': 1, 'data': [SON([(u'ok', 0.0), (u'errmsg', u"cannot use tailable option with the 'singleBatch' option"), (u'code', 2), (u'codeName', u'BadValue')])], 'starting_from': 0, 'cursor_id': 0}

cursor.__getitem__(self, index)方法,如果取单个文档,首先对当前cursor进行clone,将limit设置为-1(db返回一条文档并关闭cursor,可参考ntoreturn vs batchSize),表示只读取一条文档。

 577         if isinstance(index, integer_types):
578 if index < 0:
579 raise IndexError("Cursor instances do not support negative "
580 "indices")
581 clone = self.clone()
582 clone.skip(index + self.__skip)
583 clone.limit(-1) # use a hard limit
584 for doc in clone: 大专栏  pymongo bugfix后记
585 return doc
586 raise IndexError("no such item for Cursor instance")
587 raise TypeError("index %r cannot be applied to Cursor "
588 "instances" % index)

cursor类型是TAILABLE或TAILABLE_AWAIT,所以query的tailable选项为True;
cursor.limit设置为-1,导致query的singleBatch选项为True;
二者皆为True,引发冲突。

因为只读取一条文档,limit必须为-1,所以需要把TAILABLE和TAILABLE_AWAIT设置为0,避免选项冲突。

clone.limit(-1)  # use a hard limit
clone.__query_flags &= ~CursorType.TAILABLE_AWAIT # PYTHON-1371

至此,问题解决,说说几点收获:

  1. 尽量不要使用cursor索引访问文档,除非是一次性操作

     # 以下是原代码逻辑
    coll = self._src_mc['local'].get_collection('oplog.rs', codec_options=bson.codec_options.CodecOptions(document_class=bson.son.SON))
    cursor = coll.find({'ts': {'$gte': oplog_start}}, cursor_type=pymongo.cursor.CursorType.TAILABLE_AWAIT, no_cursor_timeout=True) if cursor[0]['ts'] == oplog_start: # 这里对原始cursor进行clone,执行查询(第一次),然后关闭cursor_cloned # 之前在跑同步时,时间戳一致,但此处可能仍有时间长短不一的等待,始终不明所以
    # 原因是下面在调用cursor.next()时会重新执行查询 while True:
    oplog = cursor.next() # 这里使用原始cursor,执行查询(第二次)
    # handle oplog
  2. 提交PR前,确保本地跑通test case,当时仅考虑到TAILABLE的情况,而忽略了TAILABLE_AWAIT
  3. 掌握PR流程:提交PR后,如果review未通过,需要修改代码,在你的local分支下继续commit并push到GitHub,新commit会自动追加到该PR,最后由项目维护者完成merge,可以参考collaborating-with-issues-and-pull-requests
  4. 最后,很高兴PR能被官方merge :)

pymongo bugfix后记的更多相关文章

  1. pymongo "ServerSelectionTimeoutError: No servers found yet" 错误的解决

    系统转移过程中,擅自把aptitude安装的mongoengine换成了pip安装,系统启动以后,报这个错误 报错提示: File "/usr/local/lib/python2.7/dis ...

  2. 使用PyMongo访问需要认证的MongoDB

    Windows 10家庭中文版,Python 3.6.4,PyMongo 3.7.0,MongoDB 3.6.3,Scrapy 1.5.0, 前言 在Python中,使用PyMongo访问Mongod ...

  3. 《C编译器剖析》后记

    这本书的序言.后记写的都让我很有感触!mark: 后 记 总有曲终人散时,不知不觉我们已经完成了对UCC 编译器的剖析,一路走来,最深的体会仍然是“纸上得来终觉浅,绝知此事要躬行”.按这个道理,理解U ...

  4. Python: Windows 7 64位 安装、使用 pymongo 3.2

    官网tutorial:  http://api.mongodb.com/python/current/tutorial.html 本教程将要告诉你如何使用pymongo模块来操作MongoDB数据库. ...

  5. 2.0 (2)测试pymongo

    在数据库中创建数据库.表,插入数据. from pymongo import MongoClient host = "localhost" port = 27017 client ...

  6. Windows平台下为Python添加MongoDB支持PyMongo

    到Python官网下载pymongo-2.6.3.win-amd64-py2.7.exe 安装pymongo-2.6.3.win-amd64-py2.7.exe 参照官方的用例进行测试 打开命令提示符 ...

  7. 【Python】pymongo使用

    官方文档:http://api.mongodb.com/python/current/index.html MongoReplicaSetClient:http://api.mongodb.com/p ...

  8. SpringMVC学习系列-后记 解决GET请求时中文乱码的问题

    SpringMVC学习系列-后记 解决GET请求时中文乱码的问题 之前项目中的web.xml中的编码设置: <filter> <filter-name>CharacterEnc ...

  9. 【mongo】pymongo通过_id删除数据

    来源:http://www.educity.cn/wenda/361741.html pymongo 根据 objectId _id 来删除数据想要删除数据,根据_id ,是最靠谱的,具体方法因为 _ ...

随机推荐

  1. 题解-------P4053 [JSOI2007]建筑抢修

    传送门 贪心+左偏树 贪心思路:先修快炸的楼 所以我们可以按照$T2$从大到小做一遍排序,然后从$1\cdots n$一个一个去修,如果这栋楼不能修(也就是当前时间已经超过$T2_{i}$),那我们就 ...

  2. textField 总结

    /* 通知使用,可以通过接受系统通知来做一些事情 UITextField派生自UIControl,所以UIControl类中的通知系统在文本字段中也可以使用.除了UIControl类的标准事件,你还可 ...

  3. Please select an empty folder to install Android Studio

    原因 当前安装的Android Studio的文件夹不是空的 解决 把路径改成一个空文件夹即可

  4. Andorid Studio 3.1 引入第三方jar包的方法

    今天手痒,把android studio 从3.0升级到3.1.2 发现很多问题 1.发现编译会下载好多东西,等半天 2.之前的jar包导不进来了 针对jar包导入不成功,我查了一下说是不支撑comp ...

  5. react webpack配置

  6. Win10控制桌面图标显示

    1.桌面鼠标右键,进入个性化 2.进入主题: 3.

  7. 关于TensorFlow2的tf.function()和AutoGraph的一些问题解决

    在使用TensorFlow的AutoGraph的时候出现了一些问题,特此记录 AutoGraph did not convert this function. Try decorating it di ...

  8. Trying to find the anti-derivative of $\tan x$ unsuccessfully by using Euler's formula

    We know that$$\tan t=\frac{e^{it}-e^{-it}}{i(e^{it}+e^{-it})}=\frac{e^{2i    t}+1-2}{i(e^{2it}+1)}=- ...

  9. 迅为IMX6Q开发板提供原理图_底板PCB_驱动程序源码_芯片和LCD数据手册_开发板环境_使用手册

      迅为IMX6开发板: Android4.4/6.0系统  Linux + Qt5.7系统  Ubuntu12.04系统 部分案例:HMI:3D打印机:医疗设备:工控机:触控一体机:车载终端 核心板 ...

  10. Docker系列二: docker常用命令总结

    https://docs.docker.com/reference/  官方命令总结地址 容器生命周期管理 1.docker run 创建一个新的容器并运行一个命令 docker run [optio ...