线上一个secondary节点crash,错误原因是出现了 oplogoutoforder 错误,也就是说secondary 重放了一条比『已经重放过最新的 oplog』更早的操作,经过分析,发现问题是因网络分区导致出现2个 primary 的问题导致,详细的过程如下表分析。
说明:node2、node1、node0分别是优先级为2、1、0的复制集成员。
timestamp
node2
node1
node0
notes
t1
primary
secondary
node2被选为主
t2
primary write a
seconary sync a
secondary sync a
node2上写入a,并同步到 node1、node0
t3
primary write b
node2上写入 b,但未同步到 node1、node0
t4
node2网络与 node1、node0隔离,发生新的选举
t5
node1被选为主
t6
primary write c
secondary sync c
node1上写入 c,同步到 node0
t7
primary write d
secondary sync d
node1上写入 d,同步到 node0
t8
primary write e
node2上写入 e, a实际上是一个耗时很长的建索引操作结束
t9
network recovered, node1发现 node2的选举时间戳更早,请求node2降级
t10
node1发现 node2优先级更高,并且oplog 足够,主动降级
t11
node2赢得新的选举
t12
priamry
node1 node0 从 node2同步,先回滚 c d
t13
node1从 node2 同步 b e
t14
node0从 node2 同步 b e ,因为 node0已经同步过 c d,时间戳比 b 更新,触发oplogoutoforder 错误 crash