副本集协议版本

MongoDB 提供了副本集协议版本 0(pv0)和副本集协议版本 1(pv1)。 pv1是使用 MongoDB 3.2 或更高版本创建的所有新副本集的默认值。

以下概述了pv0pv1之间的一些区别。

Note

MongoDB 3.6 弃用了副本集协议版本 0.

保留笔迹

w:1 Writes

弃用的pv0优先考虑保留w:1个写入

与以下版本的pv0相比,pv1增加了w:1回滚的可能性:

  • MongoDB 3.4.1

  • MongoDB 3.4.0

  • MongoDB 3.2.11 或更早版本

但是,对于 MongoDB 3.4 和更高版本中的pv1,您可以配置catchUpTimeoutMillis以优先考虑w:1写入的保留。

w:“多数”写道

弃用的pv0可能会丢失已确认的w: "majority"写操作。

pv1确保保留已确认的w: "majority"写操作。

Availability

  • 不推荐使用的pv0在所有 MongoDB 版本中均可用。

  • pv1在 MongoDB 3.2 或更高版本中可用,并且是使用 3.2 或更高版本创建的所有新副本集的默认值。

MongoDB Versionspv0(已弃用)pv1
3.2+
< 3.2

Read Concern

Read Concernpv0(已弃用)pv1
"local"
"majority"
"linearizable"

Arbiters

对于以下 MongoDB 版本,具有仲裁器的副本集与pv0相比,pv1增加了w:1回滚的可能性:

  • MongoDB 3.4.1

  • MongoDB 3.4.0

  • MongoDB 3.2.11 或更早版本

对于支持pv1的其他版本的 MongoDB,对于具有仲裁程序的副本集,pv1不会增加w:1回滚的可能性。

Priorities

对于以下 MongoDB 版本,对于具有不同members[n].priority设置的副本集,与pv0相比,pv1增加了w:1回滚的可能性:

  • MongoDB 3.4.1

  • MongoDB 3.4.0

  • MongoDB 3.2.11 或更早版本

对于支持pv1的其他版本的 MongoDB,对于具有不同members[n].priority设置的副本集,pv1不会增加w:1回滚的可能性。

Vetoes

不建议使用的pv0允许成员根据成员的optimepriority值来veto elections

pv1不使用否决权。个别成员可以在特定选举中投票赞成或反对候选人,但不能单方面否决(中止)选举。

同时检测 Primitives

some circumstances中,副本集中的两个节点可能暂时认为它们是主要节点,但是最多,其中一个节点将能够完成{ w: "majority" }写入关注。可以完成{ w: "majority" }写操作的节点是当前主节点,另一个节点是以前的主节点,通常由于network partition而尚未识别其降级。发生这种情况时,尽管已请求读取首选项primary,但连接到先前主服务器的 Client 端仍可能会观察到过时的数据,并且对先前主服务器的新写入最终将回滚。

当两个成员都认为自己是主要成员时,不建议使用的pv0依靠时钟同步来消除歧义。

Warning

依赖时钟同步会导致丢失已确认的w: "majority"写操作。

pv1使用term的概念代替了时钟同步。这样可以更快地检测到同时存在的初选,并可以在短时间内成功进行多次选举。

背对背选举

不建议使用的pv0在背对背选举之间包含 30 秒的缓冲区,以防止时钟同步不良。此缓冲区有助于减少背对背选举的次数。但是,如果在短时间内需要多次选举,则pv0可以使副本集不具有任何主副本集。

pv1进行“尽力而为”的尝试,以使具有priority最高可用级别的辅助节点进行选举。这可能导致背对背选举,因为具有较高优先级的合格成员可以进行选举。

但是,在 MongoDB 3.6(以及 MongoDB 3.4.2 和 3.2.12)中,对于pv1

  • 仅当优先级较高的节点位于当前主节点的 10 秒以内时,才可以进行优先级选举。

  • 如果仲裁员检测到与候选人同等或更高优先级的健康初选,他们将在选举中不投票。

Double Voting

pv1防止在一名成员的选举中进行双重投票。这可以通过使用terms实现。

弃用的pv0减少了通过 30 秒缓冲区进行两次投票的可能性,但不能保证如果选举超过 30 秒,成员将不会进行两次投票。

修改副本集协议版本

更改协议版本之前,请确保至少有一个 oplog 条目(从当前协议版本生成)已从主服务器复制到所有辅助服务器。要进行验证,请在每个辅助节点上检查rs.status()返回的optimes.lastCommittedOpTime.t字段。例如,将mongo shell 连接到每个辅助节点并运行:

rs.status().optimes.lastCommittedOpTime.t
  • 如果当前副本集协议版本为0,则t等于-1

  • 如果当前副本集协议版本为1,则t大于-1

一旦确认至少有一个 oplog 条目(使用当前协议版本)已复制到所有辅助服务器上,就可以更改协议版本。

要更改副本集协议版本,请使用新的protocolVersion重新配置(rs.reconfig)副本集。例如,要升级到pv1,请将mongo shell 连接到当前的主数据库并执行以下操作序列:

cfg = rs.conf();
cfg.protocolVersion=1;
rs.reconfig(cfg);

为了减少w:1回滚的可能性,您还可以将副本集重新配置为更高的settings.catchUpTimeoutMillis设置。