求助:Mongo服务器与Meteor查询匹配文档数量不一致问题
问题重现
以下是遇到的报错信息及对应翻译:
原始错误1:
Error: The Mongo server and the Meteor query disagree on how many documents match your query. Maybe it is hitting a Mongo edge case? The query is: {}
翻译1:错误:Mongo服务器与Meteor查询对匹配该查询的文档数量意见不一致。可能遇到了Mongo边缘情况?查询语句为:{}
原始错误2:
Exception in defer callback: Error: The Mongo server and the Meteor query disagree on how many documents match your query. Maybe it is hitting a Mongo edge case? The query is: {} I20180319-12:18:14.344(5.5)? at packages/mongo/oplog_observe_driver.js:881:15 I20180319-12:18:14.345(5.5)? at Object.Meteor._noYieldsAllowed (packages/meteor.js:730:12) I20180319-12:18:14.345(5.5)? at OplogObserveDriver._publishNewResults (packages/mongo/oplog_observe_driver.js:851:12) I20180319-12:18:14.345(5.5)? at Op...
翻译2:延迟回调异常:错误:Mongo服务器与Meteor查询对匹配该查询的文档数量意见不一致。可能遇到了Mongo边缘情况?查询语句为:{} I20180319-12:18:14.344(5.5)? at packages/mongo/oplog_observe_driver.js:881:15 I20180319-12:18:14.345(5.5)? at Object.Meteor._noYieldsAllowed (packages/meteor.js:730:12) I20180319-12:18:14.345(5.5)? at OplogObserveDriver._publishNewResults (packages/mongo/oplog_observe_driver.js:851:12) I20180319-12:18:14.345(5.5)? at Op...
解决方案
我之前在处理Meteor和Mongo集成的时候也碰到过一模一样的问题,结合社区经验和自己的调试,整理了几个有效的解决办法,你可以逐一尝试:
检查Mongo Oplog的同步状态
这个错误大概率和Meteor依赖的Oplog同步机制有关(报错里的oplog_observe_driver.js就是关键线索)。首先确认你的Mongo实例已经开启Oplog:如果是单节点Mongo,需要以--replSet参数启动并初始化副本集;如果是集群,确保副本集同步正常。然后在Meteor服务器控制台执行OplogObserveDriver._ensureConnected(),验证Oplog连接是否正常。如果存在同步延迟或者连接异常,修复后就能解决计数不匹配的问题。限制无过滤查询的订阅范围
报错里的查询是{},也就是无过滤的全集合查询。当集合数据量较大时,Meteor的Oplog驱动很难精准同步所有文档的变化。建议给查询添加合理的过滤条件(比如按时间范围、状态筛选),或者使用limit()和skip()实现分页,减少单次订阅的数据量,能有效降低这种计数不一致的概率。强制刷新Meteor订阅缓存
如果已经确认Oplog正常,那可能是Meteor本地缓存和数据库不同步。你可以在客户端调用subscription.stop()后重新订阅对应的数据集;或者在服务器端谨慎使用内部APIOplogObserveDriver._reset()(注意:生产环境使用前要充分测试),强制让Meteor重新从Mongo拉取数据并同步计数。排查Mongo边缘场景
按照错误提示,确实可能碰到Mongo的特殊边缘情况。你可以先在Mongo Shell里执行db.yourCollection.count({}),再和Meteor里的YourCollection.find({}).count()对比,确认是否真的存在计数差异。如果有,检查集合里是否存在_id格式异常的文档(比如非ObjectId类型),或者是否有复合索引导致统计偏差,尝试修复异常文档或者重建索引来解决问题。
内容的提问来源于stack exchange,提问作者Akshat Gupta

