PYTHON-3400 Only use new electionId/setVersion logic on 6.0+

This commit is contained in:
Shane Harvey 2022-09-29 14:31:47 -07:00 committed by Shane Harvey
parent 64d7d6da8a
commit 85f0987e1d
14 changed files with 559 additions and 40 deletions

View File

@ -531,19 +531,35 @@ def _update_rs_from_primary(
# We found a primary but it doesn't have the replica_set_name
# provided by the user.
sds.pop(server_description.address)
return (_check_has_primary(sds), replica_set_name, max_set_version, max_election_id)
new_election_tuple = server_description.election_id, server_description.set_version
max_election_tuple = max_election_id, max_set_version
new_election_safe = tuple(MinKey() if i is None else i for i in new_election_tuple)
max_election_safe = tuple(MinKey() if i is None else i for i in max_election_tuple)
if new_election_safe >= max_election_safe:
max_election_id, max_set_version = new_election_tuple
else:
# Stale primary, set to type Unknown.
sds[server_description.address] = server_description.to_unknown()
return _check_has_primary(sds), replica_set_name, max_set_version, max_election_id
if server_description.max_wire_version is None or server_description.max_wire_version < 17:
new_election_tuple = server_description.set_version, server_description.election_id
max_election_tuple = max_set_version, max_election_id
if None not in new_election_tuple:
if None not in max_election_tuple and new_election_tuple < max_election_tuple:
# Stale primary, set to type Unknown.
sds[server_description.address] = server_description.to_unknown()
return _check_has_primary(sds), replica_set_name, max_set_version, max_election_id
max_election_id = server_description.election_id
if server_description.set_version is not None and (
max_set_version is None or server_description.set_version > max_set_version
):
max_set_version = server_description.set_version
else:
new_election_tuple = server_description.election_id, server_description.set_version
max_election_tuple = max_election_id, max_set_version
new_election_safe = tuple(MinKey() if i is None else i for i in new_election_tuple)
max_election_safe = tuple(MinKey() if i is None else i for i in max_election_tuple)
if new_election_safe < max_election_safe:
# Stale primary, set to type Unknown.
sds[server_description.address] = server_description.to_unknown()
return _check_has_primary(sds), replica_set_name, max_set_version, max_election_id
else:
max_election_id = server_description.election_id
max_set_version = server_description.set_version
# We've heard from the primary. Is it the same primary as before?
for server in sds.values():
if (

View File

@ -20,7 +20,7 @@
"$oid": "000000000000000000000001"
},
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
],
[
@ -39,7 +39,7 @@
"$oid": "000000000000000000000001"
},
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
],
[
@ -58,7 +58,7 @@
"$oid": "000000000000000000000002"
},
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
]
],

View File

@ -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"
}
}
}
]
}

View File

@ -18,7 +18,7 @@
"setVersion": 1,
"setName": "rs",
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
]
],
@ -66,7 +66,7 @@
"$oid": "000000000000000000000002"
},
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
]
],
@ -116,7 +116,7 @@
"setVersion": 1,
"setName": "rs",
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
]
],
@ -170,7 +170,7 @@
"$oid": "000000000000000000000001"
},
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
]
],

View File

@ -0,0 +1,83 @@
{
"description": "Pre 6.0 New primary",
"uri": "mongodb://a,b/?replicaSet=rs",
"phases": [
{
"responses": [
[
"a:27017",
{
"ok": 1,
"helloOk": true,
"isWritablePrimary": true,
"setName": "rs",
"hosts": [
"a:27017",
"b:27017"
],
"minWireVersion": 0,
"maxWireVersion": 6
}
],
[
"b:27017",
{
"ok": 1,
"helloOk": true,
"isWritablePrimary": false,
"secondary": true,
"setName": "rs",
"hosts": [
"a:27017",
"b:27017"
],
"minWireVersion": 0,
"maxWireVersion": 6
}
]
],
"outcome": {
"servers": {
"a:27017": {
"type": "RSPrimary",
"setName": "rs"
},
"b:27017": {
"type": "RSSecondary",
"setName": "rs"
}
},
"topologyType": "ReplicaSetWithPrimary",
"logicalSessionTimeoutMinutes": null,
"setName": "rs"
}
},
{
"responses": [
[
"b:27017",
{
"ok": 0,
"minWireVersion": 0,
"maxWireVersion": 6
}
]
],
"outcome": {
"servers": {
"a:27017": {
"type": "RSPrimary",
"setName": "rs"
},
"b:27017": {
"type": "Unknown",
"setName": null
}
},
"topologyType": "ReplicaSetWithPrimary",
"logicalSessionTimeoutMinutes": null,
"setName": "rs"
}
}
]
}

View File

@ -8,7 +8,7 @@
"a:27017",
{
"ok": 1,
"hello": true,
"helloOk": true,
"isWritablePrimary": true,
"hosts": [
"a:27017",
@ -20,7 +20,7 @@
"$oid": "000000000000000000000001"
},
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
]
],
@ -50,13 +50,12 @@
}
},
{
"_comment": "Response from new primary with newer election Id",
"responses": [
[
"b:27017",
{
"ok": 1,
"hello": true,
"helloOk": true,
"isWritablePrimary": true,
"hosts": [
"a:27017",
@ -68,7 +67,7 @@
"$oid": "000000000000000000000002"
},
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
]
],
@ -98,13 +97,12 @@
}
},
{
"_comment": "Response from stale primary",
"responses": [
[
"a:27017",
{
"ok": 1,
"hello": true,
"helloOk": true,
"isWritablePrimary": true,
"hosts": [
"a:27017",
@ -116,7 +114,7 @@
"$oid": "000000000000000000000001"
},
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
]
],

View File

@ -17,7 +17,7 @@
"setName": "rs",
"setVersion": 1,
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
]
],
@ -56,7 +56,7 @@
"setName": "rs",
"setVersion": 1,
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
]
],

View File

@ -17,7 +17,7 @@
"setName": "rs",
"setVersion": 1,
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
]
],
@ -56,7 +56,7 @@
"setName": "rs",
"setVersion": 2,
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
]
],

View File

@ -0,0 +1,84 @@
{
"description": "Pre 6.0 setVersion is ignored if there is no electionId",
"uri": "mongodb://a/?replicaSet=rs",
"phases": [
{
"responses": [
[
"a:27017",
{
"ok": 1,
"helloOk": true,
"isWritablePrimary": true,
"hosts": [
"a:27017",
"b:27017"
],
"setName": "rs",
"setVersion": 2,
"minWireVersion": 0,
"maxWireVersion": 6
}
]
],
"outcome": {
"servers": {
"a:27017": {
"type": "RSPrimary",
"setName": "rs",
"setVersion": 2,
"electionId": null
},
"b:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
}
},
"topologyType": "ReplicaSetWithPrimary",
"logicalSessionTimeoutMinutes": null,
"setName": "rs",
"maxSetVersion": 2
}
},
{
"responses": [
[
"b:27017",
{
"ok": 1,
"helloOk": true,
"isWritablePrimary": true,
"hosts": [
"a:27017",
"b:27017"
],
"setName": "rs",
"setVersion": 1,
"minWireVersion": 0,
"maxWireVersion": 6
}
]
],
"outcome": {
"servers": {
"a:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
},
"b:27017": {
"type": "RSPrimary",
"setName": "rs",
"setVersion": 1,
"electionId": null
}
},
"topologyType": "ReplicaSetWithPrimary",
"logicalSessionTimeoutMinutes": null,
"setName": "rs",
"maxSetVersion": 2
}
}
]
}

View File

@ -17,7 +17,7 @@
"setName": "rs",
"setVersion": 2,
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
]
],
@ -56,7 +56,7 @@
"setName": "rs",
"setVersion": 1,
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
]
],

View File

@ -0,0 +1,138 @@
{
"description": "Pre 6.0 Record max setVersion, even from primary without electionId",
"uri": "mongodb://a/?replicaSet=rs",
"phases": [
{
"responses": [
[
"a:27017",
{
"ok": 1,
"helloOk": true,
"isWritablePrimary": true,
"hosts": [
"a:27017",
"b:27017"
],
"setName": "rs",
"setVersion": 1,
"electionId": {
"$oid": "000000000000000000000001"
},
"minWireVersion": 0,
"maxWireVersion": 6
}
]
],
"outcome": {
"servers": {
"a:27017": {
"type": "RSPrimary",
"setName": "rs",
"setVersion": 1,
"electionId": {
"$oid": "000000000000000000000001"
}
},
"b:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
}
},
"topologyType": "ReplicaSetWithPrimary",
"logicalSessionTimeoutMinutes": null,
"setName": "rs",
"maxSetVersion": 1,
"maxElectionId": {
"$oid": "000000000000000000000001"
}
}
},
{
"responses": [
[
"b:27017",
{
"ok": 1,
"helloOk": true,
"isWritablePrimary": true,
"hosts": [
"a:27017",
"b:27017"
],
"setName": "rs",
"setVersion": 2,
"minWireVersion": 0,
"maxWireVersion": 6
}
]
],
"outcome": {
"servers": {
"a:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
},
"b:27017": {
"type": "RSPrimary",
"setName": "rs",
"setVersion": 2
}
},
"topologyType": "ReplicaSetWithPrimary",
"logicalSessionTimeoutMinutes": null,
"setName": "rs",
"maxSetVersion": 2,
"maxElectionId": {
"$oid": "000000000000000000000001"
}
}
},
{
"responses": [
[
"a:27017",
{
"ok": 1,
"helloOk": true,
"isWritablePrimary": true,
"hosts": [
"a:27017",
"b: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": 2
}
},
"topologyType": "ReplicaSetWithPrimary",
"logicalSessionTimeoutMinutes": null,
"setName": "rs",
"maxSetVersion": 2,
"maxElectionId": {
"$oid": "000000000000000000000001"
}
}
}
]
}

View File

@ -20,7 +20,7 @@
"$oid": "000000000000000000000001"
},
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
]
],
@ -64,7 +64,7 @@
"setName": "rs",
"setVersion": 2,
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
]
],
@ -111,7 +111,7 @@
"$oid": "000000000000000000000002"
},
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 17
}
]
],

View File

@ -117,7 +117,7 @@
"replSetFreeze": 0
},
"readPreference": {
"mode": "Secondary"
"mode": "secondary"
},
"commandName": "replSetFreeze"
}

View File

@ -1004,10 +1004,7 @@ def assertion_context(msg):
try:
yield
except AssertionError as exc:
msg = "%s (%s)" % (exc, msg)
exc_type, exc_val, exc_tb = sys.exc_info()
assert exc_type is not None
raise exc_type(exc_val).with_traceback(exc_tb)
raise AssertionError(f"{msg}: {exc}")
def parse_spec_options(opts):