mongodb数据量比较大,有上亿数据,在建索引时使用了命令:db.collection.createIndex({"key":'hashed'},{"background":true}),以为在后台执行就可以高枕无忧,结果在有的分片集上就出现了异常,分片集的复制集还挂掉了,时间一长,重启之后就有可能跟不上,日志中会报错:too stale to catch up -- entering maintenance mode,表示已经太过久远,无法跟上primary的节奏,进入了保持状态,这个状态在rs.stats()表示为recovering,不过很有可能无法完全恢复,所以没有试过,另一个复制集日志中出现了回滚的异常,我擦,真是祸不单行,该分片集一共就3个复制集,只剩下primary还在扛着,1个在recovering,1个在rollback,writeconcern还设置为2,导致数据写到primary上无法同步到secondary,一直报wait for replicaset timeout,其实数据都在primary上,没有丢失,只是由于无法同步到secondary,所以才会超时
如何解决的?
后来我们直接将有问题的复制集的dbpath内容清空,重新启动,这样做类似于全量同步。启动后复制集的状态由startup2变成secondary,这样就满血复活了,不过在startup2的过程中操作时间比较长,它会根据复制集的oplog先恢复数据,之后建索引,然后有个btree的过程,然后就是secondary,如果在建索引的过程中有数据还在插入,那么在索引建完后会再次同步数据,如果数据不一致还会先同步数据,然后再次重新开始建索引,我建了2次索引之后就变成secondary了,比较幸运,觉得应该是当时数据量差别不太大,如果真的数据差异太大,这肯定就会变成一个同步数据--->建立索引-->同步数据-->建立索引的死循环
若是想使用全量同步,需要保证数据都在primary上没有丢失,否则就麻烦了