资讯专栏INFORMATION COLUMN

MongoDB3.2 之 Rollback讲解及避免

go4it / 3580人阅读

摘要:解释首先,到底是什么意思呢在关系型数据库中因为有事务的概念,操作数据后在没有之前是可以执行命令进行数据回退的。

前言

前段时间突然发现数据库文件路径下多了个rollback名字的文件夹,很是纳闷,里面居然还有.bson后缀格式的文件,随一探究竟。
原来是在这段时间内发生过failover(主从切换),导致了某些不一致数据的丢失,这可是一个大问题啊,弄不好就是要丢数据的,
故进行了些调查研究,详述于此;供大虾们大绳们指点。

解释

首先,rollback到底是什么意思呢?在关系型数据库中因为有事务的概念,操作数据后在没有commit之前是可以执行rollback命令进行数据回退的。
而在单实例mongodb中,写入就写入了,删除就删除了,没有事务的概念,也没有rollback的操作,所以这里要讨论的是replicaset(复制集)的rollback

事故演示

如下图架构,在primary上执行写操作


步骤1: 客户端向Primary写入3笔数据 1、2、3, 经过oplog日志后同步到secondary节点上,此时各个节点数据一致
步骤2: 但当Primary节点再次被写入一笔数据4的时候,发生宕机,此时 数据4 还没来得及同步到从节点上
步骤3: 此时集群短时间关闭写操作开始竞选,经过一系列选举后有了新的primary节点,此时新Primary节点上是没有数据4的
步骤4: 新的primary承接了客户端的write请求,写入新数据 5,此时新primary的数据状态为1,2,3,5
步骤5: 原primary节点重新启动后申请加入replica member作为secondary节点,因为此时它与新primary数据不一致,所以就会发生rollback(回滚)动作,将数据状态恢复为1,2,3
步骤6:回滚完之后,将继续同步新primary节点的数据,之后数据状态变为1,2,3,5

rollback发生的具体过程:

请看下图:

流程说明

客户端驱动在连接mongo之后进行写操作的大致流程就是这样的,写操作会按照编号顺序进行, 当Client收到5号的response反馈后即认为写入成功,
而如何数据已写入journal files,但是尚未oplog同步到Secondary节点重放,如果此时发生Primary宕机,则就会造成主从之间数据不一致,即原Primary中有
刚才新写入的数据,但新选举出来的Primary却没有那部分数据,从来造成数据丢失

结论

综上所述,rollback的发生,主要是Primary写入数据后还未来得及同步到secondary节点时,发生宕机事故,导致数据缺失,
经重新选举后产生新primary节点,但当原Primary重新加入集群时,由于要追随新Primary节点进行强一致性处理,所以会回滚宕机前未同步的数据。

存放位置

那么回滚的数据跑到哪里去了呢?当rollback发生时,MongoDB将把rollback的数据以BSON格式存放到dbpath路径下rollback文件夹中,BSON文件的命名格式如下:

...bson

还原数据

那么这个rollback数据如何写回到mongodb呢?我们可以利用mongorestore命令进行基于文件的恢复操作,具体操作可以看我另外一篇关于mongodump/mongorestore的文章

mongorestore --host  --db db1 --collection c2 -u admin_user -p"123456" --authenticationDatabase admin rollback/c2_rollback.BSON
避免策略

要讲避免策略那就应先讲讲Write Concern(写关注),也就是关心写操作。是在驱动的connection level进行配置,支持一下值:

* w:0 | 1 | n | majority | tag
* j:1
* wtimeout: millis

w:0 unacknowledged
驱动只是一味的进行写入操作,不会关心是否写入成功,也就是mongo不会返回操作结果

w:1 Acknowledged
看图我们很容易理解,Driver在做写入操作后会收到mongod的反馈OK还是NG,而这个反馈行为只是在确认数据被成功写入Data Buffer,Journal Buffer
后的状态,不保证数据能够被写入datafile(落盘)

J:1 Journaled
驱动写操作不仅要写入Journal Buffer,Data Buffer中,还要确认数据持久化到Journal file中后才反馈结果。
即使数据库宕机,重启后,操作已经持久化到journal中,可以完全恢复,但前提是mongod一定要开启journal参数

w:2/n/majority Replica Acknowledged
看到下图,你应该就明白一半了,好的,下一半让小弟再给你解释一下。
rollback的发生就是因为数据成功写入Primary,但是尚未同步到Secondary节点,此时Primary宕机,
当原Primary重新加入集群后则会发生灰色数据自行rollback的现象,那么怎么避免呢?当然就是在发送反馈信息给驱动前
确保数据已经更新到至少一个Secondary节点,不就完美解决此问题了。是的,使用w:2/n/majority的配置参数
就能实现,当然,为了防止网络问题出现阻塞等待,我们可以设置wtimeout

Rollback 的限制

应用官方的一段话:

我的理解是rollback的数据超过300M后就需要手动干预从原Primary去除灰色数据了,但是有网友测试3G多的数据也能自行rollback,
So,I"m not clear the real meaning of the Limitations

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/19122.html

相关文章

  • 【云数据库 MySQL UDB】什么是UDB?产品功能,规格版本和使用限制

    摘要:版本目前支持和,用户可以根据需求选择相应的云数据库版本。硬盘云数据库的硬盘大小。云数据库提供自动备份和手动备份两种方式,防止数据丢失,避免误操作带来的风险。日志日志是用于记录云数据库操作事件的记录文件。什么是云数据库MongoDB?云数据库简介: 云数据库MongoDB是基于成熟云计算技术的高可用、高性能的数据库服务,完全兼容MongoDB 协议,支持灵活部署,除副本集实例架构外,云数据库...

    Tecode 评论0 收藏0
  • php微服务【分布式事务】

    摘要:分布式事务一直是微服务的一个难点。相关的解决方案和框架大部分是的,那么该如何解决呢下面一步一步讲解如何用解决分布式事务。框架极简高性能松耦合分布式可运行于多种环境框架完美支持上面的要求。 分布式事务一直是微服务的一个难点。相关的解决方案和框架大部分是java的,那么php该如何解决呢?下面一步一步讲解如何用php解决分布式事务。 单机单数据源事务 首先从单机事务开始。 大概逻辑如下 :...

    Tamic 评论0 收藏0
  • Centos7 安装mongodb记录

    摘要:下载解压启动查看进程关闭服务检查端口是否已被启动另一种配置文件启动方式这个要指定文件日志追加远程连接要指定不然无法连接。 下载解压 wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.6.2.tgz tar -zxvf mongodb-linux-x86_64-3.6.2.tgz mv mongodb-linux-x...

    Julylovin 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<