diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_prepare_conflict.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_prepare_conflict.cpp
|
index 730d3e998c..c11efccf5c 100644
|
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_prepare_conflict.cpp
|
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_prepare_conflict.cpp
|
@@ -41,6 +41,8 @@ namespace mongo {
|
// When set, simulates WT_PREPARE_CONFLICT returned from WiredTiger API calls.
|
MONGO_FAIL_POINT_DEFINE(WTPrepareConflictForReads);
|
|
+MONGO_FAIL_POINT_DEFINE(WTSkipPrepareConflictRetries);
|
+
|
void wiredTigerPrepareConflictLog(int attempts) {
|
LOG(1) << "Caught WT_PREPARE_CONFLICT, attempt " << attempts
|
<< ". Waiting for unit of work to commit or abort.";
|
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_prepare_conflict.h b/src/mongo/db/storage/wiredtiger/wiredtiger_prepare_conflict.h
|
index 7833c506ec..f3031a3105 100644
|
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_prepare_conflict.h
|
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_prepare_conflict.h
|
@@ -37,9 +37,12 @@
|
|
namespace mongo {
|
|
-// When set, returns simulates returning WT_PREPARE_CONFLICT on WT cursor read operations.
|
+// When set, simulates returning WT_PREPARE_CONFLICT on WT cursor read operations.
|
MONGO_FAIL_POINT_DECLARE(WTPrepareConflictForReads);
|
|
+// When set, WT_ROLLBACK is returned in place of retrying on WT_PREPARE_CONFLICT errors.
|
+MONGO_FAIL_POINT_DECLARE(WTSkipPrepareConflictRetries);
|
+
|
/**
|
* Logs a message with the number of prepare conflict retry attempts.
|
*/
|
@@ -66,6 +69,15 @@ int wiredTigerPrepareConflictRetry(OperationContext* opCtx, F&& f) {
|
CurOp::get(opCtx)->debug().additiveMetrics.incrementPrepareReadConflicts(1);
|
wiredTigerPrepareConflictLog(attempts);
|
|
+ if (MONGO_FAIL_POINT(WTSkipPrepareConflictRetries)) {
|
+ // Callers of wiredTigerPrepareConflictRetry() should eventually call wtRCToStatus() via
|
+ // invariantWTOK() and have the WT_ROLLBACK error bubble up as a WriteConflictException.
|
+ // Enabling the "skipWriteConflictRetries" failpoint in conjunction with the
|
+ // "WTSkipPrepareConflictRetries" failpoint prevents the higher layers from retrying the
|
+ // entire operation.
|
+ return WT_ROLLBACK;
|
+ }
|
+
|
while (true) {
|
attempts++;
|
auto lastCount = recoveryUnit->getSessionCache()->getPrepareCommitOrAbortCount();
|