mongodb副本集oplogSize设置过小的问题

mongodb副本集构建的高可用方案,最少需要三个节点,一个主节点master,一个从节点slave,一个选举仲裁节点arbiter。当主节点奔溃的时候,仲裁节点选举从节点来接替主节点,继续提供数据服务,保证高可用。副本集方案中,从节点也会保存数据,他的数据是从主节点同步过来的,和mysql bin-log主从复制的方式类似,mongodb采用的是根据oplog来从主节点同步数据。oplog不是无限大,默认如果不手动设置,那么oplogSize就是磁盘空间的5%。超过了5%,oplog会被覆盖。

存在这么一种情况,slave因为某种原因挂掉了。正常情况下,他不会影响系统的正常运行,因为主节点正常运行,但是如果我们重新启动从节点,那么从节点会从主节点上恢复数据,这期间,如果主节点写入数据过快,oplog被覆盖了,也就是说,从节点需要恢复的数据不是从奔溃那一刻开始恢复的,这中间的数据被丢掉了,这种情况下,从节点不会正常的恢复,状态会变为RECOVERING,这就是本文需要讨论的一个问题。

oplog被覆盖,主要的原因是主节点写入数据过快导致的,写满了嘛。因为oplogSize有限定值,超过了这个限定值,那么就会被覆盖。这里来模拟oplogSize设置过小,从节点奔溃,然后恢复,出现RECOVERING状态的情形。

1、构建副本集构建 ,各个节点的配置如下图所示,同一个linux主机,三个mongod进程,分别开启端口27017,27018,27019。

启动节点,然后随便通过mongo shell登入一个节点,此时,节点没有表现出副本集的任何信息,当我们通过rs.initiate(cfg)设置之后,主节点会慢慢的变为OTHER->SECONDARY->PRIMARY。 在主节点,我们插入三条记录。

rs0:PRIMARY> use test
switched to db test
rs0:PRIMARY> db.user.insert({id:1,name:"zhangsan"})
WriteResult({ "nInserted" : 1 })
rs0:PRIMARY> db.user.insert({id:2,name:"lisi"})
WriteResult({ "nInserted" : 1 })
rs0:PRIMARY> db.user.insert({id:3,name:"wangwu"})
WriteResult({ "nInserted" : 1 })

2、从节点读取数据

我们设置了27017为主节点,27018为从节点,27019为仲裁节点,此时登入27018端口的从节点,我们试图查询数据db.user.find(),出现从节点无法查询的错误,从节点默认是无法读取数据的,更不可能写入数据。我们通过rs.slaveOk()让从节点可以查询数据。这数据是从master节点复制同步过来的。 

副本集中slave是无法写入数据的。 

打印oplogSize ,在启动的时候,我们通过--oplogSize 100设置了oplogSize为100M,因此,这里打印的是我们启动mongodb时设置的值。这个值在mongodb进程不崩溃的情况下设置多少无所谓。

3、为了模拟从节点奔溃并恢复,这里我们需要将slave节点手动停止。 

4、批量插入数据: 在从节点停止之后,主节点是可以继续正常工作的,不会受到影响,这里为了让oplog被覆盖,我们向数据库中插入1000000条记录。

5、数据插入成功之后,我们需要再次恢复slave节点,启动mongod进程。 

如果不出意外,100M的oplog被我们覆盖了,这时候,虽然slave节点的mongod进程启动,而且也可以通过mongo shell访问,但是我们通过rs.status()查看副本集状态,会出现如下所示的无法同步数据的情况。

6、oplog会被覆盖:

我们查看slave节点的日志,发现从节点恢复数据失败:

数据无法恢复,这时候,即使我们手动更改了oplogSize,生效了,oplog也无法恢复,因为已经被覆盖了。这时候需要将slave恢复到奔溃之前,也不是没有办法,就是删除slave节点所有的数据,从master节点完全同步复制。这是恢复slave从节点数据的方法之一。当然也是最直接的方式。

7、单纯对这个问题的解决办法: 删除slave节点存储的数据,重新启动slave从节点mongodb进程。针对本例的数据量不是特别大,会很快恢复。 我们查看slave节点日志,会发现状态从RECOERING恢复到了SECONDARY。

8、验证恢复是否成功:模拟slave节点奔溃之后,我们通过mongo shell向test数据库user表中插入了1000000条记录,加上奔溃之前的3条总共1000003条,说明从节点恢复数据成功,而且从mongo shell前面的"SECONDARY"标记可以看出,确实已经恢复了。

本例中,说明oplogSize设置过小100M,主节点写入数据过快而导致oplog被覆盖,确实会导致从节点恢复失败。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luffy5459

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值