On this page
副本集协议版本
MongoDB 提供了副本集协议版本 0(pv0
)和副本集协议版本 1(pv1
)。 pv1
是使用 MongoDB 3.2 或更高版本创建的所有新副本集的默认值。
以下概述了pv0
和pv1
之间的一些区别。
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 Versions | pv0 (已弃用) |
pv1 |
---|---|---|
3.2+ |
✓ | ✓ |
< 3.2 |
✓ |
Read Concern
Read Concern | pv0 (已弃用) |
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
允许成员根据成员的optime
和priority值来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设置。