MongoDB的主从节点上都有一个Oplog的集合(collection)。Oplog是一个固定大小的集合,当这个集合写满数据时,新的数据会覆盖掉最老的数据。在MongoDB的主节点上增删改数据后,这个操作会写到主节点的Oplog里。这些写到Oplog里的操作都是幂等的操作,也就是说不管你执行这个操作一次还是多次,得到的结构都是一样的。
假设我们有三个节点的复制集A、B和C。A是主节点,B是从节点,C为仲裁节点。B从A上同步数据。在A宕机后,B成为新的主节点。A再次启动后变成从节点,并尝试从B上同步数据。
在同步数据时,A会检查自己的Oplog里最新的操作的时间戳,在B上找到对应的时间戳的操作然后同步该时间戳后面的操作。但如果A宕机后,B上进行了很多的操作,B的Oplog里老的操作被覆盖掉了。当A再次启动后,A的Oplog里最新的时间戳比B上最老的时间戳还老,说明A已经无法从B上同步数据了,这个时候就会报“too stale to catch up”的错误。这个时候只能从主节点上重新同步所有的数据。