PYTHON-2082 Retryable writes use the RetryableWriteError label
Use retryable write logic for transaction commit/abort. Do not assign the TransientTransactionError label to errors outside a transaction.
This commit is contained in:
parent
48df9b088f
commit
45a7963aac
@ -98,13 +98,11 @@ Classes
|
||||
"""
|
||||
|
||||
import collections
|
||||
import os
|
||||
import sys
|
||||
import uuid
|
||||
|
||||
from bson.binary import Binary
|
||||
from bson.int64 import Int64
|
||||
from bson.py3compat import abc, integer_types, reraise_instance
|
||||
from bson.py3compat import abc, integer_types
|
||||
from bson.son import SON
|
||||
from bson.timestamp import Timestamp
|
||||
|
||||
@ -114,7 +112,6 @@ from pymongo.errors import (ConfigurationError,
|
||||
InvalidOperation,
|
||||
OperationFailure,
|
||||
PyMongoError,
|
||||
ServerSelectionTimeoutError,
|
||||
WTimeoutError)
|
||||
from pymongo.helpers import _RETRYABLE_ERROR_CODES
|
||||
from pymongo.read_concern import ReadConcern
|
||||
@ -295,6 +292,7 @@ class _Transaction(object):
|
||||
self.sharded = False
|
||||
self.pinned_address = None
|
||||
self.recovery_token = None
|
||||
self.attempt = 0
|
||||
|
||||
def active(self):
|
||||
return self.state in (_TxnState.STARTING, _TxnState.IN_PROGRESS)
|
||||
@ -304,12 +302,13 @@ class _Transaction(object):
|
||||
self.sharded = False
|
||||
self.pinned_address = None
|
||||
self.recovery_token = None
|
||||
self.attempt = 0
|
||||
|
||||
|
||||
def _reraise_with_unknown_commit(exc):
|
||||
"""Re-raise an exception with the UnknownTransactionCommitResult label."""
|
||||
exc._add_error_label("UnknownTransactionCommitResult")
|
||||
reraise_instance(exc, trace=sys.exc_info()[2])
|
||||
raise
|
||||
|
||||
|
||||
def _max_time_expired_error(exc):
|
||||
@ -579,7 +578,6 @@ class ClientSession(object):
|
||||
.. versionadded:: 3.7
|
||||
"""
|
||||
self._check_ended()
|
||||
retry = False
|
||||
state = self._transaction.state
|
||||
if state is _TxnState.NONE:
|
||||
raise InvalidOperation("No transaction started")
|
||||
@ -594,10 +592,9 @@ class ClientSession(object):
|
||||
# We're explicitly retrying the commit, move the state back to
|
||||
# "in progress" so that in_transaction returns true.
|
||||
self._transaction.state = _TxnState.IN_PROGRESS
|
||||
retry = True
|
||||
|
||||
try:
|
||||
self._finish_transaction_with_retry("commitTransaction", retry)
|
||||
self._finish_transaction_with_retry("commitTransaction")
|
||||
except ConnectionFailure as exc:
|
||||
# We do not know if the commit was successfully applied on the
|
||||
# server or if it satisfied the provided write concern, set the
|
||||
@ -640,44 +637,25 @@ class ClientSession(object):
|
||||
"Cannot call abortTransaction after calling commitTransaction")
|
||||
|
||||
try:
|
||||
self._finish_transaction_with_retry("abortTransaction", False)
|
||||
self._finish_transaction_with_retry("abortTransaction")
|
||||
except (OperationFailure, ConnectionFailure):
|
||||
# The transactions spec says to ignore abortTransaction errors.
|
||||
pass
|
||||
finally:
|
||||
self._transaction.state = _TxnState.ABORTED
|
||||
|
||||
def _finish_transaction_with_retry(self, command_name, explict_retry):
|
||||
def _finish_transaction_with_retry(self, command_name):
|
||||
"""Run commit or abort with one retry after any retryable error.
|
||||
|
||||
:Parameters:
|
||||
- `command_name`: Either "commitTransaction" or "abortTransaction".
|
||||
- `explict_retry`: True when this is an explict commit retry attempt,
|
||||
ie the application called session.commit_transaction() twice.
|
||||
"""
|
||||
# This can be refactored with MongoClient._retry_with_session.
|
||||
try:
|
||||
return self._finish_transaction(command_name, explict_retry)
|
||||
except ServerSelectionTimeoutError:
|
||||
raise
|
||||
except ConnectionFailure as exc:
|
||||
try:
|
||||
return self._finish_transaction(command_name, True)
|
||||
except ServerSelectionTimeoutError:
|
||||
# Raise the original error so the application can infer that
|
||||
# an attempt was made.
|
||||
raise exc
|
||||
except OperationFailure as exc:
|
||||
if exc.code not in _RETRYABLE_ERROR_CODES:
|
||||
raise
|
||||
try:
|
||||
return self._finish_transaction(command_name, True)
|
||||
except ServerSelectionTimeoutError:
|
||||
# Raise the original error so the application can infer that
|
||||
# an attempt was made.
|
||||
raise exc
|
||||
def func(session, sock_info, retryable):
|
||||
return self._finish_transaction(sock_info, command_name)
|
||||
return self._client._retry_internal(True, func, self, None)
|
||||
|
||||
def _finish_transaction(self, command_name, retrying):
|
||||
def _finish_transaction(self, sock_info, command_name):
|
||||
self._transaction.attempt += 1
|
||||
opts = self._transaction.opts
|
||||
wc = opts.write_concern
|
||||
cmd = SON([(command_name, 1)])
|
||||
@ -688,7 +666,7 @@ class ClientSession(object):
|
||||
# Transaction spec says that after the initial commit attempt,
|
||||
# subsequent commitTransaction commands should be upgraded to use
|
||||
# w:"majority" and set a default value of 10 seconds for wtimeout.
|
||||
if retrying:
|
||||
if self._transaction.attempt > 1:
|
||||
wc_doc = wc.document
|
||||
wc_doc["w"] = "majority"
|
||||
wc_doc.setdefault("wtimeout", 10000)
|
||||
@ -697,13 +675,12 @@ class ClientSession(object):
|
||||
if self._transaction.recovery_token:
|
||||
cmd['recoveryToken'] = self._transaction.recovery_token
|
||||
|
||||
with self._client._socket_for_writes(self) as sock_info:
|
||||
return self._client.admin._command(
|
||||
sock_info,
|
||||
cmd,
|
||||
session=self,
|
||||
write_concern=wc,
|
||||
parse_write_concern_error=True)
|
||||
return self._client.admin._command(
|
||||
sock_info,
|
||||
cmd,
|
||||
session=self,
|
||||
write_concern=wc,
|
||||
parse_write_concern_error=True)
|
||||
|
||||
def _advance_cluster_time(self, cluster_time):
|
||||
"""Internal cluster time helper."""
|
||||
|
||||
@ -48,7 +48,7 @@ class PyMongoError(Exception):
|
||||
|
||||
def _remove_error_label(self, label):
|
||||
"""Remove the given label from this error."""
|
||||
self._error_labels.remove(label)
|
||||
self._error_labels.discard(label)
|
||||
|
||||
if sys.version_info[0] == 2:
|
||||
def __str__(self):
|
||||
@ -68,12 +68,6 @@ class ProtocolError(PyMongoError):
|
||||
|
||||
class ConnectionFailure(PyMongoError):
|
||||
"""Raised when a connection to the database cannot be made or is lost."""
|
||||
def __init__(self, message='', error_labels=None):
|
||||
if error_labels is None:
|
||||
# Connection errors are transient errors by default.
|
||||
error_labels = ("TransientTransactionError",)
|
||||
super(ConnectionFailure, self).__init__(
|
||||
message, error_labels=error_labels)
|
||||
|
||||
|
||||
class AutoReconnect(ConnectionFailure):
|
||||
@ -89,7 +83,10 @@ class AutoReconnect(ConnectionFailure):
|
||||
Subclass of :exc:`~pymongo.errors.ConnectionFailure`.
|
||||
"""
|
||||
def __init__(self, message='', errors=None):
|
||||
super(AutoReconnect, self).__init__(message)
|
||||
error_labels = None
|
||||
if errors is not None and isinstance(errors, dict):
|
||||
error_labels = errors.get('errorLabels')
|
||||
super(AutoReconnect, self).__init__(message, error_labels)
|
||||
self.errors = self.details = errors or []
|
||||
|
||||
|
||||
|
||||
@ -59,6 +59,7 @@ from pymongo.errors import (AutoReconnect,
|
||||
ConfigurationError,
|
||||
ConnectionFailure,
|
||||
InvalidOperation,
|
||||
NotMasterError,
|
||||
OperationFailure,
|
||||
PyMongoError,
|
||||
ServerSelectionTimeoutError)
|
||||
@ -1265,7 +1266,9 @@ class MongoClient(common.BaseObject):
|
||||
session._pin_mongos(server)
|
||||
return server
|
||||
except PyMongoError as exc:
|
||||
if session and exc.has_error_label("TransientTransactionError"):
|
||||
# Server selection errors in a transaction are transient.
|
||||
if session and session.in_transaction:
|
||||
exc._add_error_label("TransientTransactionError")
|
||||
session._unpin_mongos()
|
||||
raise
|
||||
|
||||
@ -1361,6 +1364,11 @@ class MongoClient(common.BaseObject):
|
||||
"""
|
||||
retryable = (retryable and self.retry_writes
|
||||
and session and not session.in_transaction)
|
||||
return self._retry_internal(retryable, func, session, bulk)
|
||||
|
||||
def _retry_internal(self, retryable, func, session, bulk):
|
||||
"""Internal retryable write helper."""
|
||||
max_wire_version = 0
|
||||
last_error = None
|
||||
retrying = False
|
||||
|
||||
@ -1369,7 +1377,7 @@ class MongoClient(common.BaseObject):
|
||||
# Increment the transaction id up front to ensure any retry attempt
|
||||
# will use the proper txnNumber, even if server or socket selection
|
||||
# fails before the command can be sent.
|
||||
if retryable:
|
||||
if retryable and session and not session.in_transaction:
|
||||
session._start_retryable_write()
|
||||
if bulk:
|
||||
bulk.started_retryable_write = True
|
||||
@ -1381,6 +1389,7 @@ class MongoClient(common.BaseObject):
|
||||
session is not None and
|
||||
server.description.retryable_writes_supported)
|
||||
with self._get_socket(server, session) as sock_info:
|
||||
max_wire_version = sock_info.max_wire_version
|
||||
if retryable and not supports_session:
|
||||
if is_retrying():
|
||||
# A retry is not possible because this server does
|
||||
@ -1398,40 +1407,12 @@ class MongoClient(common.BaseObject):
|
||||
# be a persistent outage. Attempting to retry in this case will
|
||||
# most likely be a waste of time.
|
||||
raise
|
||||
except ConnectionFailure as exc:
|
||||
if not retryable or is_retrying():
|
||||
except Exception as exc:
|
||||
if not retryable:
|
||||
raise
|
||||
if bulk:
|
||||
bulk.retrying = True
|
||||
else:
|
||||
retrying = True
|
||||
last_error = exc
|
||||
except BulkWriteError as exc:
|
||||
if not retryable or is_retrying():
|
||||
raise
|
||||
# Check the last writeConcernError to determine if this
|
||||
# BulkWriteError is retryable.
|
||||
wces = exc.details['writeConcernErrors']
|
||||
wce = wces[-1] if wces else {}
|
||||
if wce.get('code', 0) not in helpers._RETRYABLE_ERROR_CODES:
|
||||
raise
|
||||
if bulk:
|
||||
bulk.retrying = True
|
||||
else:
|
||||
retrying = True
|
||||
last_error = exc
|
||||
except OperationFailure as exc:
|
||||
# retryWrites on MMAPv1 should raise an actionable error.
|
||||
if (exc.code == 20 and
|
||||
str(exc).startswith("Transaction numbers")):
|
||||
errmsg = (
|
||||
"This MongoDB deployment does not support "
|
||||
"retryable writes. Please add retryWrites=false "
|
||||
"to your connection string.")
|
||||
raise OperationFailure(errmsg, exc.code, exc.details)
|
||||
if not retryable or is_retrying():
|
||||
raise
|
||||
if exc.code not in helpers._RETRYABLE_ERROR_CODES:
|
||||
# Add the RetryableWriteError label.
|
||||
if (not _retryable_writes_error(exc, max_wire_version)
|
||||
or is_retrying()):
|
||||
raise
|
||||
if bulk:
|
||||
bulk.retrying = True
|
||||
@ -2162,26 +2143,66 @@ class MongoClient(common.BaseObject):
|
||||
next = __next__
|
||||
|
||||
|
||||
def _retryable_error_doc(exc):
|
||||
"""Return the server response from PyMongo exception or None."""
|
||||
if isinstance(exc, BulkWriteError):
|
||||
# Check the last writeConcernError to determine if this
|
||||
# BulkWriteError is retryable.
|
||||
wces = exc.details['writeConcernErrors']
|
||||
wce = wces[-1] if wces else None
|
||||
return wce
|
||||
if isinstance(exc, (NotMasterError, OperationFailure)):
|
||||
return exc.details
|
||||
return None
|
||||
|
||||
|
||||
def _retryable_writes_error(exc, max_wire_version):
|
||||
doc = _retryable_error_doc(exc)
|
||||
if doc:
|
||||
code = doc.get('code', 0)
|
||||
# retryWrites on MMAPv1 should raise an actionable error.
|
||||
if (code == 20 and
|
||||
str(exc).startswith("Transaction numbers")):
|
||||
errmsg = (
|
||||
"This MongoDB deployment does not support "
|
||||
"retryable writes. Please add retryWrites=false "
|
||||
"to your connection string.")
|
||||
raise OperationFailure(errmsg, code, exc.details)
|
||||
if max_wire_version >= 9:
|
||||
# MongoDB 4.4+ utilizes RetryableWriteError.
|
||||
return 'RetryableWriteError' in doc.get('errorLabels', [])
|
||||
else:
|
||||
if code in helpers._RETRYABLE_ERROR_CODES:
|
||||
exc._add_error_label("RetryableWriteError")
|
||||
return True
|
||||
return False
|
||||
|
||||
if isinstance(exc, ConnectionFailure):
|
||||
exc._add_error_label("RetryableWriteError")
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class _MongoClientErrorHandler(object):
|
||||
"""Error handler for MongoClient."""
|
||||
__slots__ = ('_client', '_server_address', '_session',
|
||||
'_max_wire_version', '_sock_generation')
|
||||
"""Handle errors raised when executing an operation."""
|
||||
__slots__ = ('client', 'server_address', 'session', 'max_wire_version',
|
||||
'sock_generation')
|
||||
|
||||
def __init__(self, client, server, session):
|
||||
self._client = client
|
||||
self._server_address = server.description.address
|
||||
self._session = session
|
||||
self._max_wire_version = common.MIN_WIRE_VERSION
|
||||
self.client = client
|
||||
self.server_address = server.description.address
|
||||
self.session = session
|
||||
self.max_wire_version = common.MIN_WIRE_VERSION
|
||||
# XXX: When get_socket fails, this generation could be out of date:
|
||||
# "Note that when a network error occurs before the handshake
|
||||
# completes then the error's generation number is the generation
|
||||
# of the pool at the time the connection attempt was started."
|
||||
self._sock_generation = server.pool.generation
|
||||
self.sock_generation = server.pool.generation
|
||||
|
||||
def contribute_socket(self, sock_info):
|
||||
"""Provide socket information to the error handler."""
|
||||
self._max_wire_version = sock_info.max_wire_version
|
||||
self._sock_generation = sock_info.generation
|
||||
self.max_wire_version = sock_info.max_wire_version
|
||||
self.sock_generation = sock_info.generation
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
@ -2190,15 +2211,16 @@ class _MongoClientErrorHandler(object):
|
||||
if exc_type is None:
|
||||
return
|
||||
|
||||
if self.session:
|
||||
if issubclass(exc_type, ConnectionFailure):
|
||||
if self.session.in_transaction:
|
||||
exc_val._add_error_label("TransientTransactionError")
|
||||
self.session._server_session.mark_dirty()
|
||||
|
||||
if issubclass(exc_type, PyMongoError):
|
||||
if exc_val.has_error_label("TransientTransactionError"):
|
||||
self.session._unpin_mongos()
|
||||
|
||||
err_ctx = _ErrorContext(
|
||||
exc_val, self._max_wire_version, self._sock_generation)
|
||||
self._client._topology.handle_error(self._server_address, err_ctx)
|
||||
|
||||
if issubclass(exc_type, PyMongoError):
|
||||
if self._session and exc_val.has_error_label(
|
||||
"TransientTransactionError"):
|
||||
self._session._unpin_mongos()
|
||||
|
||||
if issubclass(exc_type, ConnectionFailure):
|
||||
if self._session:
|
||||
self._session._server_session.mark_dirty()
|
||||
exc_val, self.max_wire_version, self.sock_generation)
|
||||
self.client._topology.handle_error(self.server_address, err_ctx)
|
||||
|
||||
182
test/retryable_writes/bulkWrite-errorLabels.json
Normal file
182
test/retryable_writes/bulkWrite-errorLabels.json
Normal file
@ -0,0 +1,182 @@
|
||||
{
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "4.3.1",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded"
|
||||
]
|
||||
}
|
||||
],
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "BulkWrite succeeds with RetryableWriteError from server",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"update"
|
||||
],
|
||||
"errorCode": 112,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "bulkWrite",
|
||||
"arguments": {
|
||||
"requests": [
|
||||
{
|
||||
"name": "deleteOne",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "insertOne",
|
||||
"arguments": {
|
||||
"document": {
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "updateOne",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 2
|
||||
},
|
||||
"update": {
|
||||
"$inc": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"options": {
|
||||
"ordered": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"result": {
|
||||
"deletedCount": 1,
|
||||
"insertedCount": 1,
|
||||
"insertedIds": {
|
||||
"1": 3
|
||||
},
|
||||
"matchedCount": 1,
|
||||
"modifiedCount": 1,
|
||||
"upsertedCount": 0,
|
||||
"upsertedIds": {}
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 23
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "BulkWrite fails if server does not return RetryableWriteError",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"update"
|
||||
],
|
||||
"errorCode": 11600,
|
||||
"errorLabels": []
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "bulkWrite",
|
||||
"arguments": {
|
||||
"requests": [
|
||||
{
|
||||
"name": "deleteOne",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "insertOne",
|
||||
"arguments": {
|
||||
"document": {
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "updateOne",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 2
|
||||
},
|
||||
"update": {
|
||||
"$inc": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"options": {
|
||||
"ordered": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -35,7 +35,10 @@
|
||||
"failCommands": [
|
||||
"update"
|
||||
],
|
||||
"errorCode": 189
|
||||
"errorCode": 189,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
@ -117,7 +120,10 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 91,
|
||||
"errmsg": "Replication is being shut down"
|
||||
"errmsg": "Replication is being shut down",
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -186,6 +192,81 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "BulkWrite fails with a RetryableWriteError label after two connection failures",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 2
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"update"
|
||||
],
|
||||
"closeConnection": true
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "bulkWrite",
|
||||
"arguments": {
|
||||
"requests": [
|
||||
{
|
||||
"name": "deleteOne",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "insertOne",
|
||||
"arguments": {
|
||||
"document": {
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "updateOne",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 2
|
||||
},
|
||||
"update": {
|
||||
"$inc": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"options": {
|
||||
"ordered": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsContain": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
106
test/retryable_writes/deleteOne-errorLabels.json
Normal file
106
test/retryable_writes/deleteOne-errorLabels.json
Normal file
@ -0,0 +1,106 @@
|
||||
{
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "4.3.1",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded"
|
||||
]
|
||||
}
|
||||
],
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "DeleteOne succeeds with RetryableWriteError from server",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"delete"
|
||||
],
|
||||
"errorCode": 112,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "deleteOne",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"result": {
|
||||
"deletedCount": 1
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "DeleteOne fails if server does not return RetryableWriteError",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"delete"
|
||||
],
|
||||
"errorCode": 11600,
|
||||
"errorLabels": []
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "deleteOne",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -35,7 +35,10 @@
|
||||
"failCommands": [
|
||||
"delete"
|
||||
],
|
||||
"errorCode": 189
|
||||
"errorCode": 189,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
@ -73,7 +76,10 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 91,
|
||||
"errmsg": "Replication is being shut down"
|
||||
"errmsg": "Replication is being shut down",
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -98,6 +104,49 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "DeleteOne fails with RetryableWriteError label after two connection failures",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 2
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"delete"
|
||||
],
|
||||
"closeConnection": true
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "deleteOne",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsContain": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
117
test/retryable_writes/findOneAndDelete-errorLabels.json
Normal file
117
test/retryable_writes/findOneAndDelete-errorLabels.json
Normal file
@ -0,0 +1,117 @@
|
||||
{
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "4.3.1",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded"
|
||||
]
|
||||
}
|
||||
],
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "FindOneAndDelete succeeds with RetryableWriteError from server",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"findAndModify"
|
||||
],
|
||||
"errorCode": 112,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "findOneAndDelete",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"x": {
|
||||
"$gte": 11
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"result": {
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "FindOneAndDelete fails if server does not return RetryableWriteError",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"findAndModify"
|
||||
],
|
||||
"errorCode": 11600,
|
||||
"errorLabels": []
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "findOneAndDelete",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"x": {
|
||||
"$gte": 11
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -35,7 +35,10 @@
|
||||
"failCommands": [
|
||||
"findAndModify"
|
||||
],
|
||||
"errorCode": 189
|
||||
"errorCode": 189,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
@ -79,7 +82,10 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 91,
|
||||
"errmsg": "Replication is being shut down"
|
||||
"errmsg": "Replication is being shut down",
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -110,6 +116,54 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "FindOneAndDelete fails with a RetryableWriteError label after two connection failures",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 2
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"findAndModify"
|
||||
],
|
||||
"closeConnection": true
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "findOneAndDelete",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"x": {
|
||||
"$gte": 11
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsContain": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
121
test/retryable_writes/findOneAndReplace-errorLabels.json
Normal file
121
test/retryable_writes/findOneAndReplace-errorLabels.json
Normal file
@ -0,0 +1,121 @@
|
||||
{
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "4.3.1",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded"
|
||||
]
|
||||
}
|
||||
],
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "FindOneAndReplace succeeds with RetryableWriteError from server",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"findAndModify"
|
||||
],
|
||||
"errorCode": 112,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "findOneAndReplace",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
},
|
||||
"replacement": {
|
||||
"_id": 1,
|
||||
"x": 111
|
||||
},
|
||||
"returnDocument": "Before"
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"result": {
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 111
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "FindOneAndReplace fails if server does not return RetryableWriteError",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"findAndModify"
|
||||
],
|
||||
"errorCode": 11600,
|
||||
"errorLabels": []
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "findOneAndReplace",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
},
|
||||
"replacement": {
|
||||
"_id": 1,
|
||||
"x": 111
|
||||
},
|
||||
"returnDocument": "Before"
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -35,7 +35,10 @@
|
||||
"failCommands": [
|
||||
"findAndModify"
|
||||
],
|
||||
"errorCode": 189
|
||||
"errorCode": 189,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
@ -83,7 +86,10 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 91,
|
||||
"errmsg": "Replication is being shut down"
|
||||
"errmsg": "Replication is being shut down",
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -118,6 +124,54 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "FindOneAndReplace fails with a RetryableWriteError label after two connection failures",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 2
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"findAndModify"
|
||||
],
|
||||
"closeConnection": true
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "findOneAndReplace",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
},
|
||||
"replacement": {
|
||||
"_id": 1,
|
||||
"x": 111
|
||||
},
|
||||
"returnDocument": "Before"
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsContain": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
123
test/retryable_writes/findOneAndUpdate-errorLabels.json
Normal file
123
test/retryable_writes/findOneAndUpdate-errorLabels.json
Normal file
@ -0,0 +1,123 @@
|
||||
{
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "4.3.1",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded"
|
||||
]
|
||||
}
|
||||
],
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "FindOneAndUpdate succeeds with RetryableWriteError from server",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"findAndModify"
|
||||
],
|
||||
"errorCode": 112,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "findOneAndUpdate",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
},
|
||||
"update": {
|
||||
"$inc": {
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
"returnDocument": "Before"
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"result": {
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 12
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "FindOneAndUpdate fails if server does not return RetryableWriteError",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"findAndModify"
|
||||
],
|
||||
"errorCode": 11600,
|
||||
"errorLabels": []
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "findOneAndUpdate",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
},
|
||||
"update": {
|
||||
"$inc": {
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
"returnDocument": "Before"
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -35,7 +35,10 @@
|
||||
"failCommands": [
|
||||
"findAndModify"
|
||||
],
|
||||
"errorCode": 189
|
||||
"errorCode": 189,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
@ -84,7 +87,10 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 91,
|
||||
"errmsg": "Replication is being shut down"
|
||||
"errmsg": "Replication is being shut down",
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -120,6 +126,55 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "FindOneAndUpdate fails with a RetryableWriteError label after two connection failures",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 2
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"findAndModify"
|
||||
],
|
||||
"closeConnection": true
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "findOneAndUpdate",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
},
|
||||
"update": {
|
||||
"$inc": {
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
"returnDocument": "Before"
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsContain": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
129
test/retryable_writes/insertMany-errorLabels.json
Normal file
129
test/retryable_writes/insertMany-errorLabels.json
Normal file
@ -0,0 +1,129 @@
|
||||
{
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "4.3.1",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded"
|
||||
]
|
||||
}
|
||||
],
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "InsertMany succeeds with RetryableWriteError from server",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"insert"
|
||||
],
|
||||
"errorCode": 112,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "insertMany",
|
||||
"arguments": {
|
||||
"documents": [
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
],
|
||||
"options": {
|
||||
"ordered": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"result": {
|
||||
"insertedIds": {
|
||||
"0": 2,
|
||||
"1": 3
|
||||
}
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "InsertMany fails if server does not return RetryableWriteError",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"insert"
|
||||
],
|
||||
"errorCode": 11600,
|
||||
"errorLabels": []
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "insertMany",
|
||||
"arguments": {
|
||||
"documents": [
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
],
|
||||
"options": {
|
||||
"ordered": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -31,7 +31,10 @@
|
||||
"failCommands": [
|
||||
"insert"
|
||||
],
|
||||
"errorCode": 189
|
||||
"errorCode": 189,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
@ -90,7 +93,10 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 91,
|
||||
"errmsg": "Replication is being shut down"
|
||||
"errmsg": "Replication is being shut down",
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -136,6 +142,55 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "InsertMany fails with a RetryableWriteError label after two connection failures",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 2
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"insert"
|
||||
],
|
||||
"closeConnection": true
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "insertMany",
|
||||
"arguments": {
|
||||
"documents": [
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
],
|
||||
"options": {
|
||||
"ordered": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsContain": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
90
test/retryable_writes/insertOne-errorLabels.json
Normal file
90
test/retryable_writes/insertOne-errorLabels.json
Normal file
@ -0,0 +1,90 @@
|
||||
{
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "4.3.1",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded"
|
||||
]
|
||||
}
|
||||
],
|
||||
"data": [],
|
||||
"tests": [
|
||||
{
|
||||
"description": "InsertOne succeeds with RetryableWriteError from server",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"insert"
|
||||
],
|
||||
"errorCode": 112,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "insertOne",
|
||||
"arguments": {
|
||||
"document": {
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"result": {
|
||||
"insertedId": 1
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "InsertOne fails if server does not return RetryableWriteError",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"insert"
|
||||
],
|
||||
"errorCode": 11600,
|
||||
"errorLabels": []
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "insertOne",
|
||||
"arguments": {
|
||||
"document": {
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": []
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -69,6 +69,53 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "InsertOne fails after connection failure when retryWrites option is false",
|
||||
"clientOptions": {
|
||||
"retryWrites": false
|
||||
},
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"insert"
|
||||
],
|
||||
"closeConnection": true
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "insertOne",
|
||||
"arguments": {
|
||||
"document": {
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "InsertOne succeeds after NotMaster",
|
||||
"failPoint": {
|
||||
@ -81,6 +128,9 @@
|
||||
"insert"
|
||||
],
|
||||
"errorCode": 10107,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -127,6 +177,9 @@
|
||||
"insert"
|
||||
],
|
||||
"errorCode": 13436,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -173,6 +226,9 @@
|
||||
"insert"
|
||||
],
|
||||
"errorCode": 13435,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -219,6 +275,9 @@
|
||||
"insert"
|
||||
],
|
||||
"errorCode": 11602,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -265,6 +324,9 @@
|
||||
"insert"
|
||||
],
|
||||
"errorCode": 11600,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -311,6 +373,9 @@
|
||||
"insert"
|
||||
],
|
||||
"errorCode": 189,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -357,6 +422,9 @@
|
||||
"insert"
|
||||
],
|
||||
"errorCode": 91,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -403,6 +471,9 @@
|
||||
"insert"
|
||||
],
|
||||
"errorCode": 7,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -449,6 +520,9 @@
|
||||
"insert"
|
||||
],
|
||||
"errorCode": 6,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -495,6 +569,9 @@
|
||||
"insert"
|
||||
],
|
||||
"errorCode": 9001,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -541,6 +618,9 @@
|
||||
"insert"
|
||||
],
|
||||
"errorCode": 89,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -586,10 +666,11 @@
|
||||
"failCommands": [
|
||||
"insert"
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 262,
|
||||
"closeConnection": false
|
||||
}
|
||||
"errorCode": 262,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
@ -649,6 +730,11 @@
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
@ -676,7 +762,10 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 11600,
|
||||
"errmsg": "Replication is being shut down"
|
||||
"errmsg": "Replication is being shut down",
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -724,7 +813,10 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 11602,
|
||||
"errmsg": "Replication is being shut down"
|
||||
"errmsg": "Replication is being shut down",
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -772,7 +864,10 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 189,
|
||||
"errmsg": "Replication is being shut down"
|
||||
"errmsg": "Replication is being shut down",
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -820,7 +915,10 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 91,
|
||||
"errmsg": "Replication is being shut down"
|
||||
"errmsg": "Replication is being shut down",
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -883,6 +981,11 @@
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsContain": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
@ -929,6 +1032,11 @@
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
@ -979,6 +1087,11 @@
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
@ -996,6 +1109,50 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "InsertOne fails with a RetryableWriteError label after two connection failures",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 2
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"insert"
|
||||
],
|
||||
"closeConnection": true
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "insertOne",
|
||||
"arguments": {
|
||||
"document": {
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsContain": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
120
test/retryable_writes/replaceOne-errorLabels.json
Normal file
120
test/retryable_writes/replaceOne-errorLabels.json
Normal file
@ -0,0 +1,120 @@
|
||||
{
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "4.3.1",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded"
|
||||
]
|
||||
}
|
||||
],
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "ReplaceOne succeeds with RetryableWriteError from server",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"update"
|
||||
],
|
||||
"errorCode": 112,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "replaceOne",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
},
|
||||
"replacement": {
|
||||
"_id": 1,
|
||||
"x": 111
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"result": {
|
||||
"matchedCount": 1,
|
||||
"modifiedCount": 1,
|
||||
"upsertedCount": 0
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 111
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "ReplaceOne fails if server does not return RetryableWriteError",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"update"
|
||||
],
|
||||
"errorCode": 11600,
|
||||
"errorLabels": []
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "replaceOne",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
},
|
||||
"replacement": {
|
||||
"_id": 1,
|
||||
"x": 111
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -35,7 +35,10 @@
|
||||
"failCommands": [
|
||||
"update"
|
||||
],
|
||||
"errorCode": 189
|
||||
"errorCode": 189,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
@ -83,7 +86,10 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 91,
|
||||
"errmsg": "Replication is being shut down"
|
||||
"errmsg": "Replication is being shut down",
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -118,6 +124,53 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "ReplaceOne fails with a RetryableWriteError label after two connection failures",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 2
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"update"
|
||||
],
|
||||
"closeConnection": true
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "replaceOne",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
},
|
||||
"replacement": {
|
||||
"_id": 1,
|
||||
"x": 111
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsContain": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
122
test/retryable_writes/updateOne-errorLabels.json
Normal file
122
test/retryable_writes/updateOne-errorLabels.json
Normal file
@ -0,0 +1,122 @@
|
||||
{
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "4.3.1",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded"
|
||||
]
|
||||
}
|
||||
],
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "UpdateOne succeeds with RetryableWriteError from server",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"update"
|
||||
],
|
||||
"errorCode": 112,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "updateOne",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
},
|
||||
"update": {
|
||||
"$inc": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"result": {
|
||||
"matchedCount": 1,
|
||||
"modifiedCount": 1,
|
||||
"upsertedCount": 0
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 12
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "UpdateOne fails if server does not return RetryableWriteError",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"update"
|
||||
],
|
||||
"errorCode": 11600,
|
||||
"errorLabels": []
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "updateOne",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
},
|
||||
"update": {
|
||||
"$inc": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -35,7 +35,10 @@
|
||||
"failCommands": [
|
||||
"update"
|
||||
],
|
||||
"errorCode": 189
|
||||
"errorCode": 189,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
@ -84,7 +87,10 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 91,
|
||||
"errmsg": "Replication is being shut down"
|
||||
"errmsg": "Replication is being shut down",
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -120,6 +126,54 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "UpdateOne fails with a RetryableWriteError label after two connection failures",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 2
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"update"
|
||||
],
|
||||
"closeConnection": true
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"name": "updateOne",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
},
|
||||
"update": {
|
||||
"$inc": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"outcome": {
|
||||
"error": true,
|
||||
"result": {
|
||||
"errorLabelsContain": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
},
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -331,11 +331,13 @@ class TestSdamMonitoring(IntegrationTest):
|
||||
# changes because topologyVersion is not incremented.
|
||||
@client_context.require_version_max(4, 3)
|
||||
def test_not_master_error_publishes_events(self):
|
||||
self._test_app_error({'errorCode': 10107, 'closeConnection': False},
|
||||
self._test_app_error({'errorCode': 10107, 'closeConnection': False,
|
||||
'errorLabels': ['RetryableWriteError']},
|
||||
NotMasterError)
|
||||
|
||||
def test_shutdown_error_publishes_events(self):
|
||||
self._test_app_error({'errorCode': 91, 'closeConnection': False},
|
||||
self._test_app_error({'errorCode': 91, 'closeConnection': False,
|
||||
'errorLabels': ['RetryableWriteError']},
|
||||
NotMasterError)
|
||||
|
||||
|
||||
|
||||
@ -304,6 +304,9 @@
|
||||
"commitTransaction"
|
||||
],
|
||||
"errorCode": 10107,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
|
||||
@ -304,9 +304,7 @@
|
||||
"$set": {
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
"multi": false,
|
||||
"upsert": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"q": {
|
||||
@ -317,7 +315,6 @@
|
||||
"x": 2
|
||||
}
|
||||
},
|
||||
"multi": false,
|
||||
"upsert": true
|
||||
}
|
||||
],
|
||||
@ -379,9 +376,7 @@
|
||||
},
|
||||
"u": {
|
||||
"y": 1
|
||||
},
|
||||
"multi": false,
|
||||
"upsert": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"q": {
|
||||
@ -389,9 +384,7 @@
|
||||
},
|
||||
"u": {
|
||||
"y": 2
|
||||
},
|
||||
"multi": false,
|
||||
"upsert": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"ordered": true,
|
||||
@ -454,8 +447,7 @@
|
||||
"z": 1
|
||||
}
|
||||
},
|
||||
"multi": true,
|
||||
"upsert": false
|
||||
"multi": true
|
||||
}
|
||||
],
|
||||
"ordered": true,
|
||||
|
||||
@ -40,8 +40,7 @@
|
||||
"$inc": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"upsert": false
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"matchedCount": 1,
|
||||
@ -65,8 +64,7 @@
|
||||
"$inc": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"upsert": false
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"matchedCount": 1,
|
||||
@ -93,9 +91,7 @@
|
||||
"$inc": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"multi": false,
|
||||
"upsert": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"ordered": true,
|
||||
@ -123,9 +119,7 @@
|
||||
"$inc": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"multi": false,
|
||||
"upsert": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"ordered": true,
|
||||
@ -212,8 +206,7 @@
|
||||
"$inc": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"upsert": false
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"matchedCount": 1,
|
||||
@ -260,9 +253,7 @@
|
||||
"$inc": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"multi": false,
|
||||
"upsert": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"ordered": true,
|
||||
|
||||
@ -134,6 +134,7 @@
|
||||
"TransientTransactionError"
|
||||
],
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError",
|
||||
"UnknownTransactionCommitResult"
|
||||
]
|
||||
}
|
||||
@ -223,6 +224,7 @@
|
||||
"TransientTransactionError"
|
||||
],
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError",
|
||||
"UnknownTransactionCommitResult"
|
||||
]
|
||||
}
|
||||
@ -312,6 +314,7 @@
|
||||
"TransientTransactionError"
|
||||
],
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError",
|
||||
"UnknownTransactionCommitResult"
|
||||
]
|
||||
}
|
||||
@ -408,6 +411,7 @@
|
||||
"TransientTransactionError"
|
||||
],
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError",
|
||||
"UnknownTransactionCommitResult"
|
||||
]
|
||||
}
|
||||
@ -461,7 +465,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "add transient label to connection errors",
|
||||
"description": "add TransientTransactionError label to connection errors, but do not add RetryableWriteError label",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
@ -496,6 +500,7 @@
|
||||
"TransientTransactionError"
|
||||
],
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError",
|
||||
"UnknownTransactionCommitResult"
|
||||
]
|
||||
}
|
||||
@ -511,6 +516,7 @@
|
||||
"TransientTransactionError"
|
||||
],
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError",
|
||||
"UnknownTransactionCommitResult"
|
||||
]
|
||||
}
|
||||
@ -533,6 +539,7 @@
|
||||
"TransientTransactionError"
|
||||
],
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError",
|
||||
"UnknownTransactionCommitResult"
|
||||
]
|
||||
}
|
||||
@ -549,6 +556,7 @@
|
||||
"TransientTransactionError"
|
||||
],
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError",
|
||||
"UnknownTransactionCommitResult"
|
||||
]
|
||||
}
|
||||
@ -663,7 +671,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "add unknown commit label to connection errors",
|
||||
"description": "add RetryableWriteError and UnknownTransactionCommitResult labels to connection errors",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
@ -699,6 +707,7 @@
|
||||
"object": "session0",
|
||||
"result": {
|
||||
"errorLabelsContain": [
|
||||
"RetryableWriteError",
|
||||
"UnknownTransactionCommitResult"
|
||||
],
|
||||
"errorLabelsOmit": [
|
||||
@ -801,7 +810,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "add unknown commit label to retryable commit errors",
|
||||
"description": "add RetryableWriteError and UnknownTransactionCommitResult labels to retryable commit errors",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
@ -811,7 +820,10 @@
|
||||
"failCommands": [
|
||||
"commitTransaction"
|
||||
],
|
||||
"errorCode": 11602
|
||||
"errorCode": 11602,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operations": [
|
||||
@ -837,6 +849,7 @@
|
||||
"object": "session0",
|
||||
"result": {
|
||||
"errorLabelsContain": [
|
||||
"RetryableWriteError",
|
||||
"UnknownTransactionCommitResult"
|
||||
],
|
||||
"errorLabelsOmit": [
|
||||
@ -939,7 +952,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "add unknown commit label to writeConcernError ShutdownInProgress",
|
||||
"description": "add RetryableWriteError and UnknownTransactionCommitResult labels to writeConcernError ShutdownInProgress",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
@ -951,7 +964,10 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 91,
|
||||
"errmsg": "Replication is being shut down"
|
||||
"errmsg": "Replication is being shut down",
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -985,6 +1001,7 @@
|
||||
"object": "session0",
|
||||
"result": {
|
||||
"errorLabelsContain": [
|
||||
"RetryableWriteError",
|
||||
"UnknownTransactionCommitResult"
|
||||
],
|
||||
"errorLabelsOmit": [
|
||||
@ -1089,7 +1106,104 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "add unknown commit label to writeConcernError WriteConcernFailed",
|
||||
"description": "do not add RetryableWriteError label to writeConcernError ShutdownInProgress that occurs within transaction",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"insert"
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 91,
|
||||
"errmsg": "Replication is being shut down"
|
||||
}
|
||||
}
|
||||
},
|
||||
"operations": [
|
||||
{
|
||||
"name": "startTransaction",
|
||||
"object": "session0",
|
||||
"arguments": {
|
||||
"options": {
|
||||
"writeConcern": {
|
||||
"w": "majority"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "insertOne",
|
||||
"object": "collection",
|
||||
"arguments": {
|
||||
"session": "session0",
|
||||
"document": {
|
||||
"_id": 1
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"errorLabelsContain": [],
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError",
|
||||
"TransientTransactionError",
|
||||
"UnknownTransactionCommitResult"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "abortTransaction",
|
||||
"object": "session0"
|
||||
}
|
||||
],
|
||||
"expectations": [
|
||||
{
|
||||
"command_started_event": {
|
||||
"command": {
|
||||
"insert": "test",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
}
|
||||
],
|
||||
"ordered": true,
|
||||
"readConcern": null,
|
||||
"lsid": "session0",
|
||||
"txnNumber": {
|
||||
"$numberLong": "1"
|
||||
},
|
||||
"startTransaction": true,
|
||||
"autocommit": false
|
||||
},
|
||||
"command_name": "insert",
|
||||
"database_name": "transaction-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command_started_event": {
|
||||
"command": {
|
||||
"abortTransaction": 1,
|
||||
"lsid": "session0",
|
||||
"txnNumber": {
|
||||
"$numberLong": "1"
|
||||
},
|
||||
"startTransaction": null,
|
||||
"autocommit": false
|
||||
},
|
||||
"command_name": "abortTransaction",
|
||||
"database_name": "admin"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outcome": {
|
||||
"collection": {
|
||||
"data": []
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "add UnknownTransactionCommitResult label to writeConcernError WriteConcernFailed",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
@ -1138,6 +1252,7 @@
|
||||
"UnknownTransactionCommitResult"
|
||||
],
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError",
|
||||
"TransientTransactionError"
|
||||
]
|
||||
}
|
||||
@ -1220,7 +1335,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "add unknown commit label to writeConcernError WriteConcernFailed with wtimeout",
|
||||
"description": "add UnknownTransactionCommitResult label to writeConcernError WriteConcernFailed with wtimeout",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
@ -1273,6 +1388,7 @@
|
||||
"UnknownTransactionCommitResult"
|
||||
],
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError",
|
||||
"TransientTransactionError"
|
||||
]
|
||||
}
|
||||
@ -1355,7 +1471,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "omit unknown commit label to writeConcernError UnsatisfiableWriteConcern",
|
||||
"description": "omit UnknownTransactionCommitResult label from writeConcernError UnsatisfiableWriteConcern",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
@ -1401,6 +1517,7 @@
|
||||
"object": "session0",
|
||||
"result": {
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError",
|
||||
"TransientTransactionError",
|
||||
"UnknownTransactionCommitResult"
|
||||
]
|
||||
@ -1461,7 +1578,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "omit unknown commit label to writeConcernError UnknownReplWriteConcern",
|
||||
"description": "omit UnknownTransactionCommitResult label from writeConcernError UnknownReplWriteConcern",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
@ -1507,6 +1624,7 @@
|
||||
"object": "session0",
|
||||
"result": {
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteConcern",
|
||||
"TransientTransactionError",
|
||||
"UnknownTransactionCommitResult"
|
||||
]
|
||||
@ -1567,7 +1685,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "do not add unknown commit label to MaxTimeMSExpired inside transactions",
|
||||
"description": "do not add UnknownTransactionCommitResult label to MaxTimeMSExpired inside transactions",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
@ -1614,6 +1732,7 @@
|
||||
},
|
||||
"result": {
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError",
|
||||
"UnknownTransactionCommitResult",
|
||||
"TransientTransactionError"
|
||||
]
|
||||
@ -1696,7 +1815,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "add unknown commit label to MaxTimeMSExpired",
|
||||
"description": "add UnknownTransactionCommitResult label to MaxTimeMSExpired",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
@ -1743,6 +1862,7 @@
|
||||
"UnknownTransactionCommitResult"
|
||||
],
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError",
|
||||
"TransientTransactionError"
|
||||
]
|
||||
}
|
||||
@ -1827,7 +1947,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "add unknown commit label to writeConcernError MaxTimeMSExpired",
|
||||
"description": "add UnknownTransactionCommitResult label to writeConcernError MaxTimeMSExpired",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
@ -1877,6 +1997,7 @@
|
||||
"UnknownTransactionCommitResult"
|
||||
],
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError",
|
||||
"TransientTransactionError"
|
||||
]
|
||||
}
|
||||
|
||||
@ -181,7 +181,10 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 91,
|
||||
"errmsg": "Replication is being shut down"
|
||||
"errmsg": "Replication is being shut down",
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -875,7 +875,7 @@
|
||||
"failCommands": [
|
||||
"commitTransaction"
|
||||
],
|
||||
"errorCode": 50
|
||||
"errorCode": 51
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -887,7 +887,7 @@
|
||||
"errorLabelsOmit": [
|
||||
"TransientTransactionError"
|
||||
],
|
||||
"errorCode": 50
|
||||
"errorCode": 51
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
204
test/transactions/retryable-abort-errorLabels.json
Normal file
204
test/transactions/retryable-abort-errorLabels.json
Normal file
@ -0,0 +1,204 @@
|
||||
{
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "4.3.1",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded"
|
||||
]
|
||||
}
|
||||
],
|
||||
"database_name": "transaction-tests",
|
||||
"collection_name": "test",
|
||||
"data": [],
|
||||
"tests": [
|
||||
{
|
||||
"description": "abortTransaction only retries once with RetryableWriteError from server",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 2
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"abortTransaction"
|
||||
],
|
||||
"errorCode": 112,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operations": [
|
||||
{
|
||||
"name": "startTransaction",
|
||||
"object": "session0"
|
||||
},
|
||||
{
|
||||
"name": "insertOne",
|
||||
"object": "collection",
|
||||
"arguments": {
|
||||
"session": "session0",
|
||||
"document": {
|
||||
"_id": 1
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"insertedId": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "abortTransaction",
|
||||
"object": "session0"
|
||||
}
|
||||
],
|
||||
"expectations": [
|
||||
{
|
||||
"command_started_event": {
|
||||
"command": {
|
||||
"insert": "test",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
}
|
||||
],
|
||||
"ordered": true,
|
||||
"readConcern": null,
|
||||
"lsid": "session0",
|
||||
"txnNumber": {
|
||||
"$numberLong": "1"
|
||||
},
|
||||
"startTransaction": true,
|
||||
"autocommit": false,
|
||||
"writeConcern": null
|
||||
},
|
||||
"command_name": "insert",
|
||||
"database_name": "transaction-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command_started_event": {
|
||||
"command": {
|
||||
"abortTransaction": 1,
|
||||
"lsid": "session0",
|
||||
"txnNumber": {
|
||||
"$numberLong": "1"
|
||||
},
|
||||
"startTransaction": null,
|
||||
"autocommit": false,
|
||||
"writeConcern": null
|
||||
},
|
||||
"command_name": "abortTransaction",
|
||||
"database_name": "admin"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command_started_event": {
|
||||
"command": {
|
||||
"abortTransaction": 1,
|
||||
"lsid": "session0",
|
||||
"txnNumber": {
|
||||
"$numberLong": "1"
|
||||
},
|
||||
"startTransaction": null,
|
||||
"autocommit": false,
|
||||
"writeConcern": null
|
||||
},
|
||||
"command_name": "abortTransaction",
|
||||
"database_name": "admin"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outcome": {
|
||||
"collection": {
|
||||
"data": []
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "abortTransaction does not retry without RetryableWriteError label",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"abortTransaction"
|
||||
],
|
||||
"errorCode": 11600,
|
||||
"errorLabels": []
|
||||
}
|
||||
},
|
||||
"operations": [
|
||||
{
|
||||
"name": "startTransaction",
|
||||
"object": "session0"
|
||||
},
|
||||
{
|
||||
"name": "insertOne",
|
||||
"object": "collection",
|
||||
"arguments": {
|
||||
"session": "session0",
|
||||
"document": {
|
||||
"_id": 1
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"insertedId": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "abortTransaction",
|
||||
"object": "session0"
|
||||
}
|
||||
],
|
||||
"expectations": [
|
||||
{
|
||||
"command_started_event": {
|
||||
"command": {
|
||||
"insert": "test",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
}
|
||||
],
|
||||
"ordered": true,
|
||||
"readConcern": null,
|
||||
"lsid": "session0",
|
||||
"txnNumber": {
|
||||
"$numberLong": "1"
|
||||
},
|
||||
"startTransaction": true,
|
||||
"autocommit": false,
|
||||
"writeConcern": null
|
||||
},
|
||||
"command_name": "insert",
|
||||
"database_name": "transaction-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command_started_event": {
|
||||
"command": {
|
||||
"abortTransaction": 1,
|
||||
"lsid": "session0",
|
||||
"txnNumber": {
|
||||
"$numberLong": "1"
|
||||
},
|
||||
"startTransaction": null,
|
||||
"autocommit": false,
|
||||
"writeConcern": null
|
||||
},
|
||||
"command_name": "abortTransaction",
|
||||
"database_name": "admin"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outcome": {
|
||||
"collection": {
|
||||
"data": []
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -413,6 +413,9 @@
|
||||
"abortTransaction"
|
||||
],
|
||||
"errorCode": 10107,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -514,6 +517,9 @@
|
||||
"abortTransaction"
|
||||
],
|
||||
"errorCode": 13436,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -615,6 +621,9 @@
|
||||
"abortTransaction"
|
||||
],
|
||||
"errorCode": 13435,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -716,6 +725,9 @@
|
||||
"abortTransaction"
|
||||
],
|
||||
"errorCode": 11602,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -817,6 +829,9 @@
|
||||
"abortTransaction"
|
||||
],
|
||||
"errorCode": 11600,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -918,6 +933,9 @@
|
||||
"abortTransaction"
|
||||
],
|
||||
"errorCode": 189,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -1019,6 +1037,9 @@
|
||||
"abortTransaction"
|
||||
],
|
||||
"errorCode": 91,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -1120,6 +1141,9 @@
|
||||
"abortTransaction"
|
||||
],
|
||||
"errorCode": 7,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -1221,6 +1245,9 @@
|
||||
"abortTransaction"
|
||||
],
|
||||
"errorCode": 6,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -1322,6 +1349,9 @@
|
||||
"abortTransaction"
|
||||
],
|
||||
"errorCode": 9001,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -1423,6 +1453,9 @@
|
||||
"abortTransaction"
|
||||
],
|
||||
"errorCode": 89,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -1525,6 +1558,9 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 11600,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"errmsg": "Replication is being shut down"
|
||||
}
|
||||
}
|
||||
@ -1639,6 +1675,9 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 11602,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"errmsg": "Replication is being shut down"
|
||||
}
|
||||
}
|
||||
@ -1753,6 +1792,9 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 189,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"errmsg": "Replication is being shut down"
|
||||
}
|
||||
}
|
||||
@ -1867,6 +1909,9 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 91,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"errmsg": "Replication is being shut down"
|
||||
}
|
||||
}
|
||||
|
||||
223
test/transactions/retryable-commit-errorLabels.json
Normal file
223
test/transactions/retryable-commit-errorLabels.json
Normal file
@ -0,0 +1,223 @@
|
||||
{
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "4.3.1",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded"
|
||||
]
|
||||
}
|
||||
],
|
||||
"database_name": "transaction-tests",
|
||||
"collection_name": "test",
|
||||
"data": [],
|
||||
"tests": [
|
||||
{
|
||||
"description": "commitTransaction does not retry error without RetryableWriteError label",
|
||||
"clientOptions": {
|
||||
"retryWrites": false
|
||||
},
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"commitTransaction"
|
||||
],
|
||||
"errorCode": 11600,
|
||||
"errorLabels": []
|
||||
}
|
||||
},
|
||||
"operations": [
|
||||
{
|
||||
"name": "startTransaction",
|
||||
"object": "session0"
|
||||
},
|
||||
{
|
||||
"name": "insertOne",
|
||||
"object": "collection",
|
||||
"arguments": {
|
||||
"session": "session0",
|
||||
"document": {
|
||||
"_id": 1
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"insertedId": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "commitTransaction",
|
||||
"object": "session0",
|
||||
"result": {
|
||||
"errorLabelsOmit": [
|
||||
"RetryableWriteError",
|
||||
"TransientTransactionError"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectations": [
|
||||
{
|
||||
"command_started_event": {
|
||||
"command": {
|
||||
"insert": "test",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
}
|
||||
],
|
||||
"ordered": true,
|
||||
"readConcern": null,
|
||||
"lsid": "session0",
|
||||
"txnNumber": {
|
||||
"$numberLong": "1"
|
||||
},
|
||||
"startTransaction": true,
|
||||
"autocommit": false,
|
||||
"writeConcern": null
|
||||
},
|
||||
"command_name": "insert",
|
||||
"database_name": "transaction-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command_started_event": {
|
||||
"command": {
|
||||
"commitTransaction": 1,
|
||||
"lsid": "session0",
|
||||
"txnNumber": {
|
||||
"$numberLong": "1"
|
||||
},
|
||||
"startTransaction": null,
|
||||
"autocommit": false,
|
||||
"writeConcern": null
|
||||
},
|
||||
"command_name": "commitTransaction",
|
||||
"database_name": "admin"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outcome": {
|
||||
"collection": {
|
||||
"data": []
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "commitTransaction retries once with RetryableWriteError from server",
|
||||
"clientOptions": {
|
||||
"retryWrites": false
|
||||
},
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
"times": 1
|
||||
},
|
||||
"data": {
|
||||
"failCommands": [
|
||||
"commitTransaction"
|
||||
],
|
||||
"errorCode": 112,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
]
|
||||
}
|
||||
},
|
||||
"operations": [
|
||||
{
|
||||
"name": "startTransaction",
|
||||
"object": "session0"
|
||||
},
|
||||
{
|
||||
"name": "insertOne",
|
||||
"object": "collection",
|
||||
"arguments": {
|
||||
"session": "session0",
|
||||
"document": {
|
||||
"_id": 1
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"insertedId": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "commitTransaction",
|
||||
"object": "session0"
|
||||
}
|
||||
],
|
||||
"expectations": [
|
||||
{
|
||||
"command_started_event": {
|
||||
"command": {
|
||||
"insert": "test",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
}
|
||||
],
|
||||
"ordered": true,
|
||||
"readConcern": null,
|
||||
"lsid": "session0",
|
||||
"txnNumber": {
|
||||
"$numberLong": "1"
|
||||
},
|
||||
"startTransaction": true,
|
||||
"autocommit": false,
|
||||
"writeConcern": null
|
||||
},
|
||||
"command_name": "insert",
|
||||
"database_name": "transaction-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command_started_event": {
|
||||
"command": {
|
||||
"commitTransaction": 1,
|
||||
"lsid": "session0",
|
||||
"txnNumber": {
|
||||
"$numberLong": "1"
|
||||
},
|
||||
"startTransaction": null,
|
||||
"autocommit": false,
|
||||
"writeConcern": null
|
||||
},
|
||||
"command_name": "commitTransaction",
|
||||
"database_name": "admin"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command_started_event": {
|
||||
"command": {
|
||||
"commitTransaction": 1,
|
||||
"lsid": "session0",
|
||||
"txnNumber": {
|
||||
"$numberLong": "1"
|
||||
},
|
||||
"startTransaction": null,
|
||||
"autocommit": false,
|
||||
"writeConcern": {
|
||||
"w": "majority",
|
||||
"wtimeout": 10000
|
||||
}
|
||||
},
|
||||
"command_name": "commitTransaction",
|
||||
"database_name": "admin"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outcome": {
|
||||
"collection": {
|
||||
"data": [
|
||||
{
|
||||
"_id": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -57,6 +57,7 @@
|
||||
"object": "session0",
|
||||
"result": {
|
||||
"errorLabelsContain": [
|
||||
"RetryableWriteError",
|
||||
"UnknownTransactionCommitResult"
|
||||
],
|
||||
"errorLabelsOmit": [
|
||||
@ -207,6 +208,7 @@
|
||||
"object": "session0",
|
||||
"result": {
|
||||
"errorLabelsContain": [
|
||||
"RetryableWriteError",
|
||||
"UnknownTransactionCommitResult"
|
||||
],
|
||||
"errorLabelsOmit": [
|
||||
@ -353,7 +355,9 @@
|
||||
"result": {
|
||||
"errorCodeName": "Interrupted",
|
||||
"errorLabelsOmit": [
|
||||
"TransientTransactionError"
|
||||
"RetryableWriteError",
|
||||
"TransientTransactionError",
|
||||
"UnknownTransactionCommitResult"
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -406,7 +410,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "commitTransaction fails after WriteConcernError Interrupted",
|
||||
"description": "commitTransaction is not retried after UnsatisfiableWriteConcern error",
|
||||
"failPoint": {
|
||||
"configureFailPoint": "failCommand",
|
||||
"mode": {
|
||||
@ -417,8 +421,8 @@
|
||||
"commitTransaction"
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 11601,
|
||||
"errmsg": "operation was interrupted"
|
||||
"code": 100,
|
||||
"errmsg": "Not enough data-bearing nodes"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -452,7 +456,9 @@
|
||||
"object": "session0",
|
||||
"result": {
|
||||
"errorLabelsOmit": [
|
||||
"TransientTransactionError"
|
||||
"RetryableWriteError",
|
||||
"TransientTransactionError",
|
||||
"UnknownTransactionCommitResult"
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -629,6 +635,9 @@
|
||||
"commitTransaction"
|
||||
],
|
||||
"errorCode": 10107,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -737,6 +746,9 @@
|
||||
"commitTransaction"
|
||||
],
|
||||
"errorCode": 13436,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -845,6 +857,9 @@
|
||||
"commitTransaction"
|
||||
],
|
||||
"errorCode": 13435,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -953,6 +968,9 @@
|
||||
"commitTransaction"
|
||||
],
|
||||
"errorCode": 11602,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -1061,6 +1079,9 @@
|
||||
"commitTransaction"
|
||||
],
|
||||
"errorCode": 11600,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -1169,6 +1190,9 @@
|
||||
"commitTransaction"
|
||||
],
|
||||
"errorCode": 189,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -1277,6 +1301,9 @@
|
||||
"commitTransaction"
|
||||
],
|
||||
"errorCode": 91,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -1385,6 +1412,9 @@
|
||||
"commitTransaction"
|
||||
],
|
||||
"errorCode": 7,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -1493,6 +1523,9 @@
|
||||
"commitTransaction"
|
||||
],
|
||||
"errorCode": 6,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -1601,6 +1634,9 @@
|
||||
"commitTransaction"
|
||||
],
|
||||
"errorCode": 9001,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -1709,6 +1745,9 @@
|
||||
"commitTransaction"
|
||||
],
|
||||
"errorCode": 89,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"closeConnection": false
|
||||
}
|
||||
},
|
||||
@ -1818,6 +1857,9 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 11600,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"errmsg": "Replication is being shut down"
|
||||
}
|
||||
}
|
||||
@ -1937,6 +1979,9 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 11602,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"errmsg": "Replication is being shut down"
|
||||
}
|
||||
}
|
||||
@ -2056,6 +2101,9 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 189,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"errmsg": "Replication is being shut down"
|
||||
}
|
||||
}
|
||||
@ -2175,6 +2223,9 @@
|
||||
],
|
||||
"writeConcernError": {
|
||||
"code": 91,
|
||||
"errorLabels": [
|
||||
"RetryableWriteError"
|
||||
],
|
||||
"errmsg": "Replication is being shut down"
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,7 +116,6 @@
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
"multi": false,
|
||||
"upsert": true
|
||||
}
|
||||
],
|
||||
@ -145,9 +144,7 @@
|
||||
},
|
||||
"u": {
|
||||
"y": 1
|
||||
},
|
||||
"multi": false,
|
||||
"upsert": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"ordered": true,
|
||||
@ -179,8 +176,7 @@
|
||||
"z": 1
|
||||
}
|
||||
},
|
||||
"multi": true,
|
||||
"upsert": false
|
||||
"multi": true
|
||||
}
|
||||
],
|
||||
"ordered": true,
|
||||
@ -346,7 +342,6 @@
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
"multi": false,
|
||||
"upsert": true
|
||||
}
|
||||
],
|
||||
@ -375,9 +370,7 @@
|
||||
},
|
||||
"u": {
|
||||
"y": 1
|
||||
},
|
||||
"multi": false,
|
||||
"upsert": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"ordered": true,
|
||||
@ -409,8 +402,7 @@
|
||||
"z": 1
|
||||
}
|
||||
},
|
||||
"multi": true,
|
||||
"upsert": false
|
||||
"multi": true
|
||||
}
|
||||
],
|
||||
"ordered": true,
|
||||
|
||||
@ -877,7 +877,6 @@
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
"multi": false,
|
||||
"upsert": true
|
||||
}
|
||||
],
|
||||
|
||||
Loading…
Reference in New Issue
Block a user