MongoDB副本集回滚那些事

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: 回滚(rollback)操作是MongoDB副本集发生一些异常主备切换后可能发生的现象。回滚操作会撤销在当前节点上已执行的一些修改操作。 什么时候会触发回滚 MongoDB副本集节点上有个同步线程,负责拉取需要同步的oplog。被拉取oplog的节点称作同步源。那么,要回滚,首先要有一个同步源。

回滚(rollback)操作是MongoDB副本集发生一些异常主备切换后可能发生的现象。回滚操作会撤销在当前节点上已执行的一些修改操作。

什么时候会触发回滚

MongoDB副本集节点上有个同步线程,负责拉取需要同步的oplog。被拉取oplog的节点称作同步源。那么,要回滚,首先要有一个同步源。

同步源

链式复制

平时我们都说主备同步主备同步,那同步源肯定是主节点了?其实不一定,MongoDB很早就支持了链式复制,即备节点可以从另外一个备节点拉取oplog,而不只从主节点拉取。这样一来可以减少主节点的负载,二来各节点可以选择离自己近的节点进行同步。当然,在某些情况下,这可能会导致一些备节点的延迟变大。链式复制可以通过以下命令来打开或关闭:

cfg = rs.config()
cfg.settings.chainingAllowed = true/false
rs.reconfig(cfg)

Secondary节点如何选择同步源

Secondary节点会根据以下原则选择一个同步源:

  1. 如果之前有通过命令replSetSyncFrom指定了同步源,那么使用此同步源
  2. 由于后续需要根据到其他节点的ping值(通过心跳进行统计)信息进行选择,这里会判断一下是否已有足够的信息,需要等待更多的心跳包,如果不需要,继续,否则直接返回,等下次需要选择时再看
  3. 如果没有开启Chained Replication(链式复制),那么选择Primary
  4. 通过两轮选择,基于以下规则选择一个ping值最低的节点:

    1. 如果自己可以建索引,那么只能从同样可以建索引的节点同步
    2. oplog的时间戳比我新(这里是获取该节点上次心跳包里带的appliedOpTime的时间戳进行比较)
    3. 不在黑名单中(注:何时将同步节点加进黑名单?1. 连接不上该节点,加10s黑名单;2. 落后该节点太多无法继续同步,加1min黑名单)

其中在第一轮选择中,会额外考虑以下条件:

  1. 拥有投票权的节点只能从同样拥有投票权的节点同步
  2. 不能从hidden节点同步
  3. 不能从落后Primary太多(超过配置的maxSyncSourceLagSecs)的节点同步
  4. 不能从配置了比自己拥有更大delay的节点同步

如果第一轮没有选出合适的节点,那么再进行第二轮选择,放宽上述条件的限制。

什么时候会触发回滚(续)

回到回滚触发条件。同步线程已经选择出了一个同步源,它向同步源发起一个find请求,查询大于等于其最新的oplog时间戳的oplog。如果发生以下两种情况,那么需要回滚:

  1. 在同步源上没有查到比其更新的oplog(我们刚刚通过一系列麻烦的规则选出它作为同步源,但是我们的oplog却比它还新)
  2. 返回的的第一条oplog和其最新的oplog的OpTime和hash都不同,注意这里是比较整个OpTime,即除了时间戳之外还包括term,首先会比较term,如果term不同,那就不同

回滚具体流程

回滚之前会获取minvalid集合的数据进行判断当前节点是否处于一致的状态,如果不是则直接assert结束进程。关于minvalid集合的作用,可参见MongoDB中local.replset.minvalid集合的作用。如果允许进行回滚,则执行以下步骤:

  1. 记录日志『rollback 0』
  2. 进入ROLLBACK状态
  3. 记录日志『rollback 1』
  4. 向同步源发送一个replSetGetRBID的命令获取一个rollbackId,这个rollbackId是用来在后面判断在rollback过程中同步源自身是否发生回滚,每个节点如果发生rollback,会修改自己的rollbackId。
  5. 记录日志『rollback 2 FindCommonPoint』
  6. 查找自己和同步源的oplog的commonPoint,这里是从同步源最新的oplog开始逆向查找,比较自己和同步源的最新的oplog的时间,计算相差的秒数,如果超过30分钟,那么放弃rollback;如果本地的oplog时间戳比对方的更新,往前继续找,直到找到时间戳相等的那条。这里每比较一条本地的oplog,都会对oplog的内容进行解析,从而得到回滚所需执行的操作集(包括需要重新从同步源获取的文档、需要重新同步的集合、需要drop的集合、索引等。这里同时也会进行一些判断,如果有发现某条oplog的大小大于512MB,放弃回滚。如果有dropDatabase操作,放弃回滚。)。找到了时间戳相等且hash一致的oplog,就找到了commonPoint。
  7. 记录日志『rollback 3 fixup』
  8. 自增rollbackId
  9. 接下来根据刚刚解析oplog得到的需要重新从同步源获取其最新版本的文档集,从同步源逐个获取,并保存在一个map中。这里会对要回滚的数据总大小进行判断,不能超过300MB。所有文档处理完毕后,从同步源获取其最新的oplog的时间备用
  10. 记录日志『rollback 3.5』
  11. 再次获取同步源的rollbackId,如果和刚刚得到的不一样,那说明同步源自身也发生了回滚,放弃这次回滚操作
  12. 记录日志『rollback 4 n:需要更新的文档个数』
  13. 将刚才第9步从同步源得到的最新的oplog的时间戳作为结束时间,插入一个时间戳区间到minvalid集合,表明当前数据处于不一致状态。
  14. 如果有需要重新同步整个集合数据或元数据的的,逐个处理(重新同步集合数据的,先drop然后copyCollection;重新同步集合元数据的,获取元数据并更新到本地),此处会记录日志『rollback 4.1.1 coll resync』或『rollback 4.1.2 coll metadata resync』。这里由于可能比较费时,记录日志『rollback 4.2』,然后再一次获取同步源最新的oplog时间戳记录到minvalid集合,并再次判断同步源是否自身发生回滚。如果一切正常,记录日志『rollback 4.3』。
  15. 记录日志『rollback 4.6』
  16. 处理需要drop的集合(如果有),这里会做collScan将要drop的集合的文档的内容写到rollback目录里的文件中
  17. 处理需要drop的索引(如果有)
  18. 记录日志『rollback 4.7』
  19. 处理刚刚从同步源获取的最新版本的文档集,先将本地的文档写到rollback目录里的文件中,然后删除或更新
  20. 记录日志『rollback 5 d:删除的文档数 u:更新的文档数』
  21. 记录日志『rollback 6』
  22. 清除本地oplog集合中在commonPoint之后的oplog
  23. reload本地的最新oplog
  24. 记录日志『rollback done』
  25. 再次自增自己的rollbackId
  26. 记录日志『rollback finished』

3.2.11以前回滚的bug

需要注意的是,当执行完最后一步记录日志『rollback finished』,其实回滚还没真正结束。此时节点会进入RECOVERING状态,minvalid集合中还记录了一个时间戳区间。即节点在回滚过程中记录了需要同步到哪个OpTime,后续等同步线程追上这个时间点后才能变成SECONDARY状态。如果在这时候,发生了同步源切换,比如切换到另外一个同样需要回滚的节点,并且又将刚刚已清除掉的commonPoint之后的oplog给同步回来,那么就可能触发第二次回滚触发assert退出。关于这个bug,MongoDB官方已在3.2.11版本中修复SERVER-25145,修复方法是在选择同步源的时候增加是否包含minvalid中OpTime的判断。我们阿里云数据库MongoDB也已merge了这个bugfix。

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
NoSQL MongoDB 索引
MongoDB副本集同步原理
MongoDB的同步原理,官方文档介绍的比较少,网上资料也不是太多,下面是结合官方文档、网上资料和测试时候的日志,整理出来的一点东西。
3535 0
|
2月前
|
存储 NoSQL MongoDB
MongoDB 复制(副本集)
10月更文挑战第17天
37 2
MongoDB 复制(副本集)
|
3月前
|
存储 NoSQL Shell
MongoDB复制(副本集)总结
这篇文章是关于MongoDB副本集的总结,包括复制原理、设置副本集、案例分析等内容。
46 1
|
4月前
|
NoSQL MongoDB Windows
MongoDB 读写分离——Windows MongoDB 副本集配置
MongoDB 读写分离——Windows MongoDB 副本集配置
83 0
|
7月前
|
监控 NoSQL MongoDB
【MongoDB 专栏】MongoDB 的副本集故障转移与恢复
【5月更文挑战第11天】MongoDB的副本集是高可用性关键,提供数据冗余和自动故障转移。由主节点和从节点组成,主节点处理写操作,从节点同步数据。当主节点故障,副本集通过选举产生新主节点,确保服务不间断。故障转移涉及节点优先级和数据同步状态的考量。恢复阶段解决数据不一致,重点包括节点部署监控、数据同步策略、选举机制和备份恢复计划。网络延迟和大规模数据可能带来挑战,需优化网络、性能调优和定期演练。随着技术进步,副本集的故障转移与恢复将更高效、智能,保障数据安全,支撑业务系统的稳定运行。
354 3
【MongoDB 专栏】MongoDB 的副本集故障转移与恢复
|
7月前
|
NoSQL MongoDB 数据库
国内唯一 阿里云荣膺MongoDB“2024年度DBaaS认证合作伙伴奖”
阿里云连续第五年斩获MongoDB合作伙伴奖项,也是唯一获此殊荣的中国云厂商。一起学习MongoDB副本集的选举机制以及可能会出现的特殊情况。
国内唯一 阿里云荣膺MongoDB“2024年度DBaaS认证合作伙伴奖”
|
6月前
|
存储 监控 NoSQL
MongoDB 副本集:构建可靠的数据备份与高可用性系统
MongoDB 副本集:构建可靠的数据备份与高可用性系统
112 0
|
NoSQL MongoDB
MongoDB分片+副本集高可用集群的启停步骤
MongoDB分片+副本集高可用集群的启停步骤
288 0
|
7月前
|
监控 NoSQL 算法
【MongoDB】 MongoDB的副本集是什么?
【4月更文挑战第1天】【MongoDB】 MongoDB的副本集是什么?
|
存储 NoSQL Ubuntu
21 MongoDB高级 - 复制(副本集)
21 MongoDB高级 - 复制(副本集)
69 1

相关产品

  • 云数据库 MongoDB 版