为什么在MongoDB中找不到文档,但读取重试有帮助?

为什么在MongoDB中找不到文档,但读取重试有帮助?,mongodb,pymongo,database-migration,database-replication,sharding,Mongodb,Pymongo,Database Migration,Database Replication,Sharding,有时我们会观察下一种情况: 我们通过mongos路由器向MongoDB插入一个带有写入问题的文档w:1,该路由器向primary碎片a的副本写入 我们使用默认的local读取关注点,通过mongos路由器从MongoDB读取本文档,该路由器应读取碎片A的primary副本 此findOne返回null,就好像找不到文档一样 (实际上它是Python驱动程序pymongo-find_one(),并返回None) 我们睡眠0.1秒,然后重试读取 在步骤2-5中,文档最终被成功读取 我们发现:

有时我们会观察下一种情况:

  • 我们通过
    mongos
    路由器向MongoDB插入一个带有写入问题的文档
    w:1
    ,该路由器向
    primary
    碎片a的副本写入
  • 我们使用默认的
    local
    读取关注点,通过
    mongos
    路由器从MongoDB读取本文档,该路由器应读取碎片A的
    primary
    副本
  • findOne
    返回
    null
    ,就好像找不到文档一样
  • (实际上它是Python驱动程序
    pymongo-find_one()
    ,并返回
    None
  • 我们睡眠0.1秒,然后重试读取
  • 在步骤2-5中,文档最终被成功读取
我们发现:

  • 当大量文档快速插入到该集合中时,这种情况会更常见
  • 我们怀疑这样的插入会导致分块和分块从碎片A迁移到碎片B
  • 当文档正在迁移时,是否会在短时间内无法读取
  • 但是在
    db.oplog.rs
    中只有一个插入到一个shard,没有来自migrate标志的
为什么会这样?如何正确处理

这些假阳性“未找到”-s可能会通过
$setOnInsert
导致错误的原子查找或创建