Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRIVERS-2412: add pre 6.0 condition to stale primary logic #1309

Merged
merged 5 commits into from
Oct 3, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,55 @@ updateRSFromPrimary
return

# Election ids are ObjectIds, see
# "using setVersion and electionId to detect stale primaries"
# "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
# see "Using electionId and setVersion to detect stale primaries"
nbbeeken marked this conversation as resolved.
Show resolved Hide resolved
# for comparison rules.

if serverDescription.setVersion is not null and serverDescription.electionId is not null:
# Election ids are ObjectIds, see
# "using setVersion and electionId to detect stale primaries"
# for comparison rules.
nbbeeken marked this conversation as resolved.
Show resolved Hide resolved
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 +2020,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 +2574,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