Skip to content

Commit

Permalink
DRIVERS-2412: add pre 6.0 condition to stale primary logic (#1309)
Browse files Browse the repository at this point in the history
  • Loading branch information
nbbeeken authored Oct 3, 2022
1 parent 92b6c0d commit 37c32cf
Show file tree
Hide file tree
Showing 24 changed files with 1,057 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Server Discovery And Monitoring
:Advisors: David Golden, Craig Wilson
:Status: Accepted
:Type: Standards
:Version: 2.34
:Last Modified: 2022-01-19
:Version: 2.35
:Last Modified: 2022-09-30

.. contents::

Expand Down Expand Up @@ -1109,21 +1109,49 @@ updateRSFromPrimary
return

# Election ids are ObjectIds, see
# "using setVersion and electionId to detect stale primaries"
# see "Using electionId and setVersion to detect stale primaries"
# for comparison rules.

# Null values for both electionId and setVersion are always considered less than
if serverDescription.electionId > topologyDescription.maxElectionId or (
serverDescription.electionId == topologyDescription.maxElectionId
and serverDescription.setVersion >= topologyDescription.maxSetVersion
):
topologyDescription.maxElectionId = serverDescription.electionId
topologyDescription.maxSetVersion = serverDescription.setVersion
if serverDescription.maxWireVersion >= 17: # MongoDB 6.0+
# Null values for both electionId and setVersion are always considered less than
if serverDescription.electionId > topologyDescription.maxElectionId or (
serverDescription.electionId == topologyDescription.maxElectionId
and serverDescription.setVersion >= topologyDescription.maxSetVersion
):
topologyDescription.maxElectionId = serverDescription.electionId
topologyDescription.maxSetVersion = serverDescription.setVersion
else:
# Stale primary.
# replace serverDescription with a default ServerDescription of type "Unknown"
checkIfHasPrimary()
return
else:
# Stale primary.
# replace serverDescription with a default ServerDescription of type "Unknown"
checkIfHasPrimary()
return
# Maintain old comparison rules, namely setVersion is checked before electionId
if serverDescription.setVersion is not null and serverDescription.electionId is not null:
if (
topologyDescription.maxSetVersion is not null
and topologyDescription.maxElectionId is not null
and (
topologyDescription.maxSetVersion > serverDescription.setVersion
or (
topologyDescription.maxSetVersion == serverDescription.setVersion
and topologyDescription.maxElectionId > serverDescription.electionId
)
)
):
# Stale primary.
# replace serverDescription with a default ServerDescription of type "Unknown"
checkIfHasPrimary()
return

topologyDescription.maxElectionId = serverDescription.electionId

if serverDescription.setVersion is not null and (
topologyDescription.maxSetVersion is null
or serverDescription.setVersion > topologyDescription.maxSetVersion
):
topologyDescription.maxSetVersion = serverDescription.setVersion


for each server in topologyDescription.servers:
if server.address != serverDescription.address:
Expand Down Expand Up @@ -1986,10 +2014,16 @@ between the old and new primary during a split-brain period,
and helps provide read-your-writes consistency with write concern "majority"
and read preference "primary".

Prior to MongoDB server version 6.0 drivers had the logic opposite from
the server side Replica Set Management logic by ordering the tuple by ``setVersion`` before the ``electionId``.
In order to remain compatibility with backup systems, etc. drivers continue to
maintain the reversed logic when connected to a topology that reports a maxWireVersion less than ``17``.
Server versions 6.0 and beyond MUST order the tuple by ``electionId`` then ``setVersion``.

Requirements for read-your-writes consistency
`````````````````````````````````````````````

Using (setVersion, electionId) only provides read-your-writes consistency if:
Using (electionId, setVersion) only provides read-your-writes consistency if:

* The application uses the same MongoClient instance for write-concern
"majority" writes and read-preference "primary" reads, and
Expand Down Expand Up @@ -2534,6 +2568,8 @@ mark the server Unknown and clear the pool.

2022-07-11: Convert integration tests to the unified format.

2022-30-09: Update ``updateRSFromPrimary`` to include logic before and after 6.0 servers

.. Section for links.
.. _hello or legacy hello: /source/mongodb-handshake/handshake.rst#terms
Expand Down
2 changes: 2 additions & 0 deletions source/server-discovery-and-monitoring/tests/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ All files in the "rs" directory include a connection string with a "replicaSet"
Set the client's initial TopologyType to ReplicaSetNoPrimary.
(For most clients, parsing a connection string with a "replicaSet" option
automatically sets the TopologyType to ReplicaSetNoPrimary.)
Some of the files in "rs" are post-fixed with "pre-6.0". These files test the ``updateRSFromPrimary`` behavior
prior to maxWireVersion 17, there should be no special handling required for these tests.

Set up a listener to collect SDAM events published by the client, including
events published during client construction.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"$oid": "000000000000000000000001"
},
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
],
[
Expand All @@ -39,7 +39,7 @@
"$oid": "000000000000000000000001"
},
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
],
[
Expand All @@ -58,7 +58,7 @@
"$oid": "000000000000000000000002"
},
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
]
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ phases:
electionId:
$oid: "000000000000000000000001"
minWireVersion: 0
maxWireVersion: 6
maxWireVersion: 17
- - "b:27017"
- ok: 1
helloOk: true
Expand All @@ -27,7 +27,7 @@ phases:
electionId:
$oid: "000000000000000000000001"
minWireVersion: 0
maxWireVersion: 6
maxWireVersion: 17
- - "a:27017"
- ok: 1
helloOk: true
Expand All @@ -40,7 +40,7 @@ phases:
electionId:
$oid: "000000000000000000000002"
minWireVersion: 0
maxWireVersion: 6
maxWireVersion: 17
outcome:
servers:
"a:27017":
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
{
"description": "Pre 6.0 Primaries with and without electionIds",
"uri": "mongodb://a/?replicaSet=rs",
"phases": [
{
"responses": [
[
"a:27017",
{
"ok": 1,
"helloOk": true,
"isWritablePrimary": true,
"hosts": [
"a:27017",
"b:27017",
"c:27017"
],
"setVersion": 1,
"setName": "rs",
"minWireVersion": 0,
"maxWireVersion": 6
}
]
],
"outcome": {
"servers": {
"a:27017": {
"type": "RSPrimary",
"setName": "rs",
"setVersion": 1,
"electionId": null
},
"b:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
},
"c:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
}
},
"topologyType": "ReplicaSetWithPrimary",
"logicalSessionTimeoutMinutes": null,
"setName": "rs",
"maxSetVersion": 1
}
},
{
"responses": [
[
"b:27017",
{
"ok": 1,
"helloOk": true,
"isWritablePrimary": true,
"hosts": [
"a:27017",
"b:27017",
"c:27017"
],
"setName": "rs",
"setVersion": 1,
"electionId": {
"$oid": "000000000000000000000002"
},
"minWireVersion": 0,
"maxWireVersion": 6
}
]
],
"outcome": {
"servers": {
"a:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
},
"b:27017": {
"type": "RSPrimary",
"setName": "rs",
"setVersion": 1,
"electionId": {
"$oid": "000000000000000000000002"
}
},
"c:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
}
},
"topologyType": "ReplicaSetWithPrimary",
"logicalSessionTimeoutMinutes": null,
"setName": "rs",
"maxSetVersion": 1,
"maxElectionId": {
"$oid": "000000000000000000000002"
}
}
},
{
"responses": [
[
"a:27017",
{
"ok": 1,
"helloOk": true,
"isWritablePrimary": true,
"hosts": [
"a:27017",
"b:27017",
"c:27017"
],
"setVersion": 1,
"setName": "rs",
"minWireVersion": 0,
"maxWireVersion": 6
}
]
],
"outcome": {
"servers": {
"a:27017": {
"type": "RSPrimary",
"setName": "rs",
"setVersion": 1,
"electionId": null
},
"b:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
},
"c:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
}
},
"topologyType": "ReplicaSetWithPrimary",
"logicalSessionTimeoutMinutes": null,
"setName": "rs",
"maxSetVersion": 1,
"maxElectionId": {
"$oid": "000000000000000000000002"
}
}
},
{
"responses": [
[
"c:27017",
{
"ok": 1,
"helloOk": true,
"isWritablePrimary": true,
"hosts": [
"a:27017",
"b:27017",
"c:27017"
],
"setName": "rs",
"setVersion": 1,
"electionId": {
"$oid": "000000000000000000000001"
},
"minWireVersion": 0,
"maxWireVersion": 6
}
]
],
"outcome": {
"servers": {
"a:27017": {
"type": "RSPrimary",
"setName": "rs",
"setVersion": 1,
"electionId": null
},
"b:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
},
"c:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
}
},
"topologyType": "ReplicaSetWithPrimary",
"logicalSessionTimeoutMinutes": null,
"setName": "rs",
"maxSetVersion": 1,
"maxElectionId": {
"$oid": "000000000000000000000002"
}
}
}
]
}
Loading

0 comments on commit 37c32cf

Please sign in to comment.