网络分区引发的 oplog 乱序问题

OplogOutOfOrder problem

线上一个Secondary节点crash,错误原因是出现了 OplogOutOfOrder 错误,也就是说Secondary 重放了一条比『已经重放过最新的 oplog』更早的操作,经过分析,发现问题是因网络分区导致出现2个 Primary 的问题导致,详细的过程如下表分析。

说明:Node2、Node1、Node0分别是优先级为2、1、0的复制集成员。

Timestamp Node2 Node1 Node0 Notes
t1 Primary Secondary Secondary Node2被选为主
t2 Primary write A Seconary sync A Secondary sync A Node2上写入A,并同步到 Node1、Node0
t3 Primary write B Secondary Secondary Node2上写入 B,但未同步到 Node1、Node0
t4 Primary Secondary Secondary Node2网络与 Node1、Node0隔离,发生新的选举
t5 Primary Primary Secondary Node1被选为主
t6 Primary Primary WRITE C Secondary SYNC C Node1上写入 C,同步到 Node0
t7 Primary Primary WRITE D Secondary SYNC D Node1上写入 D,同步到 Node0
t8 Primary Write E Primary Secondary Node2上写入 E, a实际上是一个耗时很长的建索引操作结束
t9 Secondary Primary Secondary network recovered, Node1发现 Node2的选举时间戳更早,请求Node2降级
t10 Secondary Secondary Secondary Node1发现 Node2优先级更高,并且oplog 足够,主动降级
t11 Primary Secondary Secondary Node2赢得新的选举
t12 Priamry Secondary Secondary Node1 Node0 从 Node2同步,先回滚 C D
t13 Primary Secondary Secondary Node1从 Node2 同步 B E
t14 Primary Secondary Secondary Node0从 Node2 同步 B E ,因为 Node0已经同步过 C D,时间戳比 B 更新,触发oplogOutOfOrder 错误 crash

上述问题也提给了MongoDB 官方团队,参考https://jira.mongodb.org/browse/SERVER-25838,这个问题在『3.0及以前的版本』或『使用 protocol version 为0的3.2版本』都有可能发生,但几率很小,使用 MongoDB 的同学不用担心,我们也是因为MongoDB云数据库 用户比较多,才触发了一例;MongoDB 3.2引入了 raft 协议,避免了上述场景发生,遇到类似问题的用户可以升级到 MongoDB-3.2,并使用复制集协议protocoal version 1

作者简介

张友东,阿里巴巴技术专家,主要关注分布式存储、Nosql数据库等技术领域,先后参与TFS(淘宝分布式文件系统)Redis云数据库等项目,目前主要从事MongoDB云数据库的研发工作,致力于让开发者用上最好的MongoDB云服务。

网络分区引发的 oplog 乱序问题》有1个想法

发表评论