由于MongoDB副本集的意外故障转移导致的数据丢失

时间:2016-11-02 09:06:24

标签: mongodb replication failover mongodb-replica-set

所以我最近遇到了以下问题:

我有一个5人组的副本集(优先级)

  • 1 x primary(2)
  • 2 x secondary(0.5)
  • 1 x隐藏备份(0)
  • 1 x arbiter(0)

其中一个具有0.5优先级的辅助副本(让我们称之为 B )遇到了一些网络问题,并且与副本集的其余部分之间存在间歇性连接。但是,尽管有staler数据且优先级低于现有的主要数据(让我们称之为 A ),但它承担了主要角色:

  

[ReplicationExecutor] VoteRequester:没有来自xxx的投票,因为:候选人的数据比我的更稳定,分别是:{term:29,voteGranted:false,原因:"候选人的数据是staler比我的#34;,好的:1.0}

     

[ReplicationExecutor]选举成功,假设在第29项中担任主要角色

     

[ReplicationExecutor]过渡到PRIMARY

对于 A ,尽管与副本集的其余部分没有任何连接问题:

  

[ReplicationExecutor]从主要版本下台,因为新术语已经开始:29

所以问题1 是,考虑到这种情况,这怎么可能呢?

继续, A (现在是次要的)开始回滚数据:

  

[rsBackgroundSync]由于OplogStartMissing而开始回滚:我们上次的操作时间被提取:(术语:28,时间戳:xxx)。来源的GTE :(术语:29,时间戳:xxx)哈希:(xxx / xxx)

     

[rsBackgroundSync]开始回滚

     

[rsBackgroundSync] rollback 0

     

[ReplicationExecutor]转换到ROLLBACK

这导致写入的数据被删除。所以问题2是: OplogStart如何丢失?

最后但并非最不重要的是,问题3 ,如何防止这种情况?

提前谢谢!

1 个答案:

答案 0 :(得分:3)

您使用的是版本3.2.x和protocolVersion = 1(您可以使用rs.conf()命令查看它吗?)因为投票有“bug”。 您可以通过(选择一个或两个)来防止此错误:

  • 将protocolVersion更改为0。 cfg = rs.conf(); cfg.protocolVersion = 0; rs.reconfig(CFG);

  • 将所有优先级更改为相同的值

编辑: 这些是门票解释..或多或少.. Ticket 1 Ticket 2