昨晚将收藏品转换为封顶收藏品时,我的二级运动时间开始落后于初级。它慢慢地前进,每隔几分钟几秒钟,最终落在主要的oplog窗口之外。根据说明here我在辅助节点上停止了mongod,删除了所有数据文件,然后重新启动它,尽管我忘了锁定主数据库。辅助设备经历了初始化阶段,这需要花费大量时间,最终重新开始运营,但是当我登录时,复制现在甚至落后了。
因为这是云,毕竟我创建了一个我的主映像(应该复制所有数据),虽然我当时无法运行db.fsyncLock(),因为它正在服用一些写道。新图像完成,我基于该图像启动一个新的服务器,将它添加到我的副本集,删除旧的二级,生活是好的,对吧?不完全 - 新的中学落后了大约一个小时,并且在一天中(和今晚)最终达到了落后14小时的程度(尽管在oplog窗口内仍然非常奇怪)。 / p>
我从"重新定位陈旧的成员页面"开始下一步。关闭两台服务器上的mongod,gzip并将我的数据文件夹从主数据库复制到辅助服务器,解压缩,将它们都解压缩,db.fsyncLock()我的主服务器。让我感到震惊的是,即使使用相同数据,在初始化之后,我的中学也说它落后了1个小时。我将它添加回副本集中,它很快赶上了5分钟。
一切都好,对吗?不 - 闪现前锋,中学正在向前推进,现在落后20分钟。 Mongostat次要挂钩95%锁定%,iostat -xm 2并没有显示出任何疯狂的内容 - 主要是因为没有写入而空闲,次要绝对没有做多少(.04 wMB /秒)。不确定它是否值得一提,但是主要目前感觉 dog slow 没有响应登录到mongo shell等。
什么给了,Mongo?为什么你不能赶上?我试图让我的二手陷入困境我做错了什么?
修改 回答问题:
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util xvda 1.00 2564.50 243.50 282.50 8986.00 11388.00 77.47 11.32 21.46 2.36 37.93 0.50 26.50
那个以11 wMB / s特别突破,看到util%在7 wMB / s时达到34%,在52 rMB / s时达到72%。所以没有饱和,但绝对是早上读取繁重的工作量。尽管有obj,但它很有趣。大小〜5GB,以及~1GB索引(见下文),磁盘活动如此之多。难道不应该都在RAM中吗?
"collections" : 21, "objects" : 15540092, "avgObjSize" : 325.26198326238995, "dataSize" : 5054601144, "storageSize" : 5874327552, "numExtents" : 132, "indexes" : 43, "indexSize" : 864366720, "fileSize" : 10666115072, "nsSizeMB" : 16, "ok" : 1
我无法想象那8块内存的压倒性优势,但我可能错了。
insert query update delete getmore command flushes mapped vsize res faults locked % idx miss % qr|qw ar|aw netIn netOut conn set repl time *0 *0 *0 *0 0 1|0 0 22.2g 44.9g 912m 0 99.2 0 0|0 0|1 2k 303b 151 mySet SEC 03:47:54 *0 *0 *0 *0 0 1|0 0 22.2g 44.9g 1.85g 0 101 0 0|0 0|1 3k 303b 151 mySet SEC 03:48:04
修改
尝试了更多的事情。我关闭了主要(现在称为A,辅助将是B),删除了它的数据,并解压缩了它的快照(现在已经有几个小时了,但是在这一点上,我们并没有写任何新的东西)。开始使用--fastsync,它仍然比B(现在的主要)optime落后45秒,后者在02:19:52UTC大约停留。最后大约一个小时后,A赶上,所以我在B上调用rs.stepDown()。当然,rs.status()告诉我两台服务器在04:08 UTC时都有运行时间,但B(现在是次要的)再次落后17秒......然后30秒......现在7分钟......
修改
在获取@matulef建议并在我的上限集合上重新创建索引几分钟后,以及重新启动二级mongod进程,其optime仅增加了几秒钟。来自mongostat的次要锁定%仍然在95-104%之间徘徊,有趣的是,res大小从100M大幅摆动到2GB并再次回到1GB左右。
编辑(第二天晚上)
故事的结论 - @matulef走在正确的轨道上,我应该更加谨慎地将复制的集合转换为上限集合。接下来是发生了什么,虽然我不会将其宣传为数据安全 - 我自由地承认我可能在这个过程中丢失了一些数据,所以YMMV。
为主要(A)上的上限集合创建索引并没有传播到次要(B),而A恰好是故障转移(非故意)。一旦B是主要的,我手动在那里的上限集合上创建了索引,并且使A与B一致的再同步操作开始快速移动。不幸的是,我的oplog窗口不再排队,所以我最终不得不将数据从B快照到A。一旦我用相同的数据集重新启动mongo,A& B再次感到高兴,从那时起复制就一直在恢复。
答案 0 :(得分:6)
这里的问题是,上限集合默认情况下没有_id索引(并且“convertToCapped”命令实际上删除了该集合的所有索引)。这是一个问题,因为辅助节点通过从oplog应用ops来执行更新,oplog通过_ids引用文档。如果缺少_id索引,则每次更新都需要对辅助索引进行全表扫描,导致它们远远落后。
解决方案是在上限集合上创建_id索引。但是,如果您在主服务器上创建索引,但是您的辅助服务器已经落后,那么它们将不会足够快地接收索引创建操作。相反,解决问题的最佳方法是首先逐个修复每个滞后的辅助设备。对于每一个,将其关闭并以独立模式重新启动(在不同的端口上,不使用--replSet选项),构建_id索引,然后将其添加回集合中。最后,一旦修复了辅助副本,您就可以降低主要部分,并使用它重复该过程。
更新:在mongoDB 2.0.x及更早版本中,默认情况下,上限集合没有_id索引。但是,默认行为计划在mongoDB 2.2中更改,因此在2.2+中创建的上限集合将自动创建_id索引,就像使用非上限集合一样。对于在2.2之前创建的上限集合,您仍然需要使用上面列出的步骤手动创建_id索引,但新集合不应受到上述问题的影响。