summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorIan Kuehne <ian.kuehne@mongodb.com>2017-07-03 13:10:24 -0400
committerIan Kuehne <ian.kuehne@mongodb.com>2017-07-03 15:58:06 -0400
commitacd196d77043d007b07b48b6e2c4fb13cfa5b938 (patch)
treeffd83f977e02211f7867bed6dc67d4efed71b0fe /src/mongo/db
parentd362678ea9a9e4e948bfda0bc60e2fefdd1eb045 (diff)
downloadmongo-acd196d77043d007b07b48b6e2c4fb13cfa5b938.tar.gz
SERVER-29544 Remove deprecated macro calls.
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/catalog/create_collection.cpp153
-rw-r--r--src/mongo/db/catalog/database_impl.cpp18
-rw-r--r--src/mongo/db/catalog/drop_collection.cpp7
-rw-r--r--src/mongo/db/catalog/drop_database.cpp31
-rw-r--r--src/mongo/db/catalog/drop_indexes.cpp65
-rw-r--r--src/mongo/db/catalog/rename_collection.cpp37
-rw-r--r--src/mongo/db/cloner.cpp36
-rw-r--r--src/mongo/db/commands/create_indexes.cpp19
-rw-r--r--src/mongo/db/commands/dbcommands.cpp12
-rw-r--r--src/mongo/db/commands/find_and_modify.cpp52
-rw-r--r--src/mongo/db/commands/fsync.cpp5
-rw-r--r--src/mongo/db/commands/list_indexes.cpp14
-rw-r--r--src/mongo/db/commands/mr.cpp38
-rw-r--r--src/mongo/db/commands/oplog_note.cpp5
-rw-r--r--src/mongo/db/concurrency/write_conflict_exception.h24
-rw-r--r--src/mongo/db/exec/update.cpp6
-rw-r--r--src/mongo/db/index/index_access_method.cpp5
-rw-r--r--src/mongo/db/ops/update.cpp5
-rw-r--r--src/mongo/db/ops/write_ops_exec.cpp10
-rw-r--r--src/mongo/db/query/plan_yield_policy.cpp3
-rw-r--r--src/mongo/db/read_concern.cpp7
-rw-r--r--src/mongo/db/repl/apply_ops.cpp10
-rw-r--r--src/mongo/db/repl/bgsync.cpp16
-rw-r--r--src/mongo/db/repl/collection_bulk_loader_impl.cpp82
-rw-r--r--src/mongo/db/repl/noop_writer.cpp5
-rw-r--r--src/mongo/db/repl/oplog.cpp5
-rw-r--r--src/mongo/db/repl/replication_coordinator_external_state_impl.cpp111
-rw-r--r--src/mongo/db/repl/rs_rollback.cpp13
-rw-r--r--src/mongo/db/repl/rs_rollback_no_uuid.cpp13
-rw-r--r--src/mongo/db/repl/storage_interface_impl.cpp124
-rw-r--r--src/mongo/db/repl/storage_interface_impl_test.cpp5
-rw-r--r--src/mongo/db/repl/sync_tail.cpp23
-rw-r--r--src/mongo/db/repl/sync_tail_test.cpp5
-rw-r--r--src/mongo/db/s/collection_range_deleter.cpp6
-rw-r--r--src/mongo/db/service_context_d_test_fixture.cpp5
-rw-r--r--src/mongo/db/system_index.cpp10
36 files changed, 484 insertions, 501 deletions
diff --git a/src/mongo/db/catalog/create_collection.cpp b/src/mongo/db/catalog/create_collection.cpp
index 9af83620ab6..283e10f267c 100644
--- a/src/mongo/db/catalog/create_collection.cpp
+++ b/src/mongo/db/catalog/create_collection.cpp
@@ -78,7 +78,7 @@ Status createCollection(OperationContext* opCtx,
!options["capped"].trueValue() || options["size"].isNumber() ||
options.hasField("$nExtents"));
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ return writeConflictRetry(opCtx, "create", nss.ns(), [&] {
Lock::DBLock dbXLock(opCtx, nss.db(), MODE_X);
OldClientContext ctx(opCtx, nss.ns());
if (opCtx->writesAreReplicated() &&
@@ -93,14 +93,15 @@ Status createCollection(OperationContext* opCtx,
const bool createDefaultIndexes = true;
status =
userCreateNS(opCtx, ctx.db(), nss.ns(), options, kind, createDefaultIndexes, idIndex);
+
if (!status.isOK()) {
return status;
}
wunit.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "create", nss.ns());
- return Status::OK();
+
+ return Status::OK();
+ });
}
} // namespace
@@ -132,72 +133,88 @@ Status createCollectionForApplyOps(OperationContext* opCtx,
// create a database on MMAPv1, which could result in createCollection failing if the database
// does not yet exist.
if (ui.ok()) {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
- WriteUnitOfWork wunit(opCtx);
- // Options need the field to be named "uuid", so parse/recreate.
- auto uuid = uassertStatusOK(UUID::parse(ui));
- uassert(ErrorCodes::InvalidUUID,
- "Invalid UUID in applyOps create command: " + uuid.toString(),
- uuid.isRFC4122v4());
-
- auto& catalog = UUIDCatalog::get(opCtx);
- auto currentName = catalog.lookupNSSByUUID(uuid);
- OpObserver* opObserver = getGlobalServiceContext()->getOpObserver();
- if (currentName == newCollName)
- return Status::OK();
-
- // In the case of oplog replay, a future command may have created or renamed a
- // collection with that same name. In that case, renaming this future collection to a
- // random temporary name is correct: once all entries are replayed no temporary names
- // will remain.
- // On MMAPv1 the rename can result in index names that are too long. However this should
- // only happen for initial sync and "resync collection" for rollback, so we can let the
- // error propagate resulting in an abort and restart of the initial sync or result in
- // rollback to fassert, requiring a resync of that node.
- const bool stayTemp = true;
- if (auto futureColl = db ? db->getCollection(opCtx, newCollName) : nullptr) {
- auto tmpName = NamespaceString(newCollName.db(), "tmp" + UUID::gen().toString());
- Status status =
- db->renameCollection(opCtx, newCollName.ns(), tmpName.ns(), stayTemp);
- if (!status.isOK())
- return status;
- opObserver->onRenameCollection(opCtx,
- newCollName,
- tmpName,
- futureColl->uuid(),
- /*dropTarget*/ false,
- /*dropTargetUUID*/ {},
- /*dropSourceUUID*/ {},
- stayTemp);
- }
-
- // If the collection with the requested UUID already exists, but with a different name,
- // just rename it to 'newCollName'.
- if (catalog.lookupCollectionByUUID(uuid)) {
- Status status =
- db->renameCollection(opCtx, currentName.ns(), newCollName.ns(), stayTemp);
- if (!status.isOK())
- return status;
- opObserver->onRenameCollection(opCtx,
- currentName,
- newCollName,
- uuid,
- /*dropTarget*/ false,
- /*dropTargetUUID*/ {},
- /*dropSourceUUID*/ {},
- stayTemp);
-
+ // Return an optional, indicating whether we need to early return (if the collection already
+ // exists, or in case of an error).
+ using Result = boost::optional<Status>;
+ auto result =
+ writeConflictRetry(opCtx, "createCollectionForApplyOps", newCollName.ns(), [&] {
+ WriteUnitOfWork wunit(opCtx);
+ // Options need the field to be named "uuid", so parse/recreate.
+ auto uuid = uassertStatusOK(UUID::parse(ui));
+ uassert(ErrorCodes::InvalidUUID,
+ "Invalid UUID in applyOps create command: " + uuid.toString(),
+ uuid.isRFC4122v4());
+
+ auto& catalog = UUIDCatalog::get(opCtx);
+ auto currentName = catalog.lookupNSSByUUID(uuid);
+ OpObserver* opObserver = getGlobalServiceContext()->getOpObserver();
+ if (currentName == newCollName)
+ return Result(Status::OK());
+
+ // In the case of oplog replay, a future command may have created or renamed a
+ // collection with that same name. In that case, renaming this future collection to
+ // a
+ // random temporary name is correct: once all entries are replayed no temporary
+ // names
+ // will remain.
+ // On MMAPv1 the rename can result in index names that are too long. However this
+ // should
+ // only happen for initial sync and "resync collection" for rollback, so we can let
+ // the
+ // error propagate resulting in an abort and restart of the initial sync or result
+ // in
+ // rollback to fassert, requiring a resync of that node.
+ const bool stayTemp = true;
+ if (auto futureColl = db ? db->getCollection(opCtx, newCollName) : nullptr) {
+ auto tmpName =
+ NamespaceString(newCollName.db(), "tmp" + UUID::gen().toString());
+ Status status =
+ db->renameCollection(opCtx, newCollName.ns(), tmpName.ns(), stayTemp);
+ if (!status.isOK())
+ return Result(status);
+ opObserver->onRenameCollection(opCtx,
+ newCollName,
+ tmpName,
+ futureColl->uuid(),
+ /*dropTarget*/ false,
+ /*dropTargetUUID*/ {},
+ /*dropSourceUUID*/ {},
+ stayTemp);
+ }
+
+ // If the collection with the requested UUID already exists, but with a different
+ // name,
+ // just rename it to 'newCollName'.
+ if (catalog.lookupCollectionByUUID(uuid)) {
+ Status status =
+ db->renameCollection(opCtx, currentName.ns(), newCollName.ns(), stayTemp);
+ if (!status.isOK())
+ return Result(status);
+ opObserver->onRenameCollection(opCtx,
+ currentName,
+ newCollName,
+ uuid,
+ /*dropTarget*/ false,
+ /*dropTargetUUID*/ {},
+ /*dropSourceUUID*/ {},
+ stayTemp);
+
+ wunit.commit();
+ return Result(Status::OK());
+ }
+
+ // A new collection with the specific UUID must be created, so add the UUID to the
+ // creation options. Regular user collection creation commands cannot do this.
+ auto uuidObj = uuid.toBSON();
+ newCmd = cmdObj.addField(uuidObj.firstElement());
wunit.commit();
- return Status::OK();
- }
-
- // A new collection with the specific UUID must be created, so add the UUID to the
- // creation options. Regular user collection creation commands cannot do this.
- auto uuidObj = uuid.toBSON();
- newCmd = cmdObj.addField(uuidObj.firstElement());
- wunit.commit();
+
+ return Result(boost::none);
+ });
+
+ if (result) {
+ return *result;
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "createCollectionForApplyOps", newCollName.ns());
}
return createCollection(
diff --git a/src/mongo/db/catalog/database_impl.cpp b/src/mongo/db/catalog/database_impl.cpp
index 9933ea6f36c..e96bd7325d6 100644
--- a/src/mongo/db/catalog/database_impl.cpp
+++ b/src/mongo/db/catalog/database_impl.cpp
@@ -764,13 +764,12 @@ void DatabaseImpl::dropDatabase(OperationContext* opCtx, Database* db) {
dbHolder().close(opCtx, name, "database dropped");
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "dropDatabase", name, [&] {
getGlobalServiceContext()
->getGlobalStorageEngine()
->dropDatabase(opCtx, name)
.transitional_ignore();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "dropDatabase", name);
+ });
}
namespace {
@@ -803,20 +802,19 @@ void mongo::dropAllDatabasesExceptLocalImpl(OperationContext* opCtx) {
repl::getGlobalReplicationCoordinator()->dropAllSnapshots();
- for (vector<string>::iterator i = n.begin(); i != n.end(); i++) {
- if (*i != "local") {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
- Database* db = dbHolder().get(opCtx, *i);
+ for (const auto& dbName : n) {
+ if (dbName != "local") {
+ writeConflictRetry(opCtx, "dropAllDatabasesExceptLocal", dbName, [&opCtx, &dbName] {
+ Database* db = dbHolder().get(opCtx, dbName);
// This is needed since dropDatabase can't be rolled back.
// This is safe be replaced by "invariant(db);dropDatabase(opCtx, db);" once fixed
if (db == nullptr) {
- log() << "database disappeared after listDatabases but before drop: " << *i;
+ log() << "database disappeared after listDatabases but before drop: " << dbName;
} else {
DatabaseImpl::dropDatabase(opCtx, db);
}
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "dropAllDatabasesExceptLocal", *i);
+ });
}
}
}
diff --git a/src/mongo/db/catalog/drop_collection.cpp b/src/mongo/db/catalog/drop_collection.cpp
index 154d599fb49..46cd73e0766 100644
--- a/src/mongo/db/catalog/drop_collection.cpp
+++ b/src/mongo/db/catalog/drop_collection.cpp
@@ -60,7 +60,7 @@ Status dropCollection(OperationContext* opCtx,
const std::string dbname = collectionName.db().toString();
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ return writeConflictRetry(opCtx, "drop", collectionName.ns(), [&] {
AutoGetDb autoDb(opCtx, dbname, MODE_X);
Database* const db = autoDb.getDb();
Collection* coll = db ? db->getCollection(opCtx, collectionName) : nullptr;
@@ -110,10 +110,9 @@ Status dropCollection(OperationContext* opCtx,
}
}
wunit.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "drop", collectionName.ns());
- return Status::OK();
+ return Status::OK();
+ });
}
} // namespace mongo
diff --git a/src/mongo/db/catalog/drop_database.cpp b/src/mongo/db/catalog/drop_database.cpp
index ef9bc6f8aa5..1df925e5b49 100644
--- a/src/mongo/db/catalog/drop_database.cpp
+++ b/src/mongo/db/catalog/drop_database.cpp
@@ -98,22 +98,25 @@ Status dropDatabase(OperationContext* opCtx, const std::string& dbName) {
// collections to drop.
repl::OpTime latestDropPendingOpTime;
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ using Result = boost::optional<Status>;
+ // Get an optional result--if it's there, early return; otherwise, wait for collections to drop.
+ auto result = writeConflictRetry(opCtx, "dropDatabase_collection", dbName, [&] {
Lock::GlobalWrite lk(opCtx);
AutoGetDb autoDB(opCtx, dbName, MODE_X);
Database* const db = autoDB.getDb();
if (!db) {
- return Status(ErrorCodes::NamespaceNotFound,
- str::stream() << "Could not drop database " << dbName
- << " because it does not exist");
+ return Result(Status(ErrorCodes::NamespaceNotFound,
+ str::stream() << "Could not drop database " << dbName
+ << " because it does not exist"));
}
bool userInitiatedWritesAndNotPrimary =
opCtx->writesAreReplicated() && !replCoord->canAcceptWritesForDatabase(opCtx, dbName);
if (userInitiatedWritesAndNotPrimary) {
- return Status(ErrorCodes::NotMaster,
- str::stream() << "Not primary while dropping database " << dbName);
+ return Result(
+ Status(ErrorCodes::NotMaster,
+ str::stream() << "Not primary while dropping database " << dbName));
}
log() << "dropDatabase " << dbName << " - starting";
@@ -145,10 +148,15 @@ Status dropDatabase(OperationContext* opCtx, const std::string& dbName) {
// If there are no collection drops to wait for, we complete the drop database operation.
if (numCollectionsToDrop == 0U && latestDropPendingOpTime.isNull()) {
- return _finishDropDatabase(opCtx, dbName, db);
+ return Result(_finishDropDatabase(opCtx, dbName, db));
}
+
+ return Result(boost::none);
+ });
+
+ if (result) {
+ return *result;
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "dropDatabase_collection", dbName);
// If waitForWriteConcern() returns an error or throws an exception, we should reset the
// drop-pending state on Database.
@@ -214,7 +222,7 @@ Status dropDatabase(OperationContext* opCtx, const std::string& dbName) {
dropPendingGuardWhileAwaitingReplication.Dismiss();
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ return writeConflictRetry(opCtx, "dropDatabase_database", dbName, [&] {
Lock::GlobalWrite lk(opCtx);
AutoGetDb autoDB(opCtx, dbName, MODE_X);
if (auto db = autoDB.getDb()) {
@@ -226,10 +234,7 @@ Status dropDatabase(OperationContext* opCtx, const std::string& dbName) {
<< " because it does not exist after dropping "
<< numCollectionsToDrop
<< " collection(s).");
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "dropDatabase_database", dbName);
-
- MONGO_UNREACHABLE;
+ });
}
} // namespace mongo
diff --git a/src/mongo/db/catalog/drop_indexes.cpp b/src/mongo/db/catalog/drop_indexes.cpp
index 2081f58d6ae..650a2acf32f 100644
--- a/src/mongo/db/catalog/drop_indexes.cpp
+++ b/src/mongo/db/catalog/drop_indexes.cpp
@@ -138,46 +138,47 @@ Status dropIndexes(OperationContext* opCtx,
const NamespaceString& nss,
const BSONObj& idxDescriptor,
BSONObjBuilder* result) {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
- AutoGetDb autoDb(opCtx, nss.db(), MODE_X);
+ return writeConflictRetry(
+ opCtx, "dropIndexes", nss.db(), [opCtx, &nss, &idxDescriptor, result] {
+ AutoGetDb autoDb(opCtx, nss.db(), MODE_X);
- bool userInitiatedWritesAndNotPrimary = opCtx->writesAreReplicated() &&
- !repl::getGlobalReplicationCoordinator()->canAcceptWritesFor(opCtx, nss);
+ bool userInitiatedWritesAndNotPrimary = opCtx->writesAreReplicated() &&
+ !repl::getGlobalReplicationCoordinator()->canAcceptWritesFor(opCtx, nss);
- if (userInitiatedWritesAndNotPrimary) {
- return {ErrorCodes::NotMaster,
- str::stream() << "Not primary while dropping indexes in " << nss.ns()};
- }
-
- if (!serverGlobalParams.quiet.load()) {
- LOG(0) << "CMD: dropIndexes " << nss;
- }
+ if (userInitiatedWritesAndNotPrimary) {
+ return Status(ErrorCodes::NotMaster,
+ str::stream() << "Not primary while dropping indexes in "
+ << nss.ns());
+ }
- // If db/collection does not exist, short circuit and return.
- Database* db = autoDb.getDb();
- Collection* collection = db ? db->getCollection(opCtx, nss) : nullptr;
- if (!db || !collection) {
- if (db && db->getViewCatalog()->lookup(opCtx, nss.ns())) {
- return {ErrorCodes::CommandNotSupportedOnView,
- str::stream() << "Cannot drop indexes on view " << nss.ns()};
+ if (!serverGlobalParams.quiet.load()) {
+ LOG(0) << "CMD: dropIndexes " << nss;
}
- return Status(ErrorCodes::NamespaceNotFound, "ns not found");
- }
+ // If db/collection does not exist, short circuit and return.
+ Database* db = autoDb.getDb();
+ Collection* collection = db ? db->getCollection(opCtx, nss) : nullptr;
+ if (!db || !collection) {
+ if (db && db->getViewCatalog()->lookup(opCtx, nss.ns())) {
+ return Status(ErrorCodes::CommandNotSupportedOnView,
+ str::stream() << "Cannot drop indexes on view " << nss.ns());
+ }
- WriteUnitOfWork wunit(opCtx);
- OldClientContext ctx(opCtx, nss.ns());
- BackgroundOperation::assertNoBgOpInProgForNs(nss);
+ return Status(ErrorCodes::NamespaceNotFound, "ns not found");
+ }
- Status status = wrappedRun(opCtx, collection, idxDescriptor, result);
- if (!status.isOK()) {
- return status;
- }
+ WriteUnitOfWork wunit(opCtx);
+ OldClientContext ctx(opCtx, nss.ns());
+ BackgroundOperation::assertNoBgOpInProgForNs(nss);
- wunit.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "dropIndexes", nss.db());
- return Status::OK();
+ Status status = wrappedRun(opCtx, collection, idxDescriptor, result);
+ if (!status.isOK()) {
+ return status;
+ }
+
+ wunit.commit();
+ return Status::OK();
+ });
}
} // namespace mongo
diff --git a/src/mongo/db/catalog/rename_collection.cpp b/src/mongo/db/catalog/rename_collection.cpp
index 2e71e2be1a0..604e0b8c6ea 100644
--- a/src/mongo/db/catalog/rename_collection.cpp
+++ b/src/mongo/db/catalog/rename_collection.cpp
@@ -164,7 +164,7 @@ Status renameCollection(OperationContext* opCtx,
auto sourceUUID = sourceColl->uuid();
// If we are renaming in the same database, just rename the namespace and we're done.
if (sourceDB == targetDB) {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ return writeConflictRetry(opCtx, "renameCollection", target.ns(), [&] {
WriteUnitOfWork wunit(opCtx);
OptionalCollectionUUID dropTargetUUID;
if (targetColl) {
@@ -192,9 +192,8 @@ Status renameCollection(OperationContext* opCtx,
stayTemp);
wunit.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "renameCollection", target.ns());
- return Status::OK();
+ return Status::OK();
+ });
}
@@ -218,7 +217,7 @@ Status renameCollection(OperationContext* opCtx,
options.uuid = newUUID;
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "renameCollection", tmpName.ns(), [&] {
WriteUnitOfWork wunit(opCtx);
// No logOp necessary because the entire renameCollection command is one logOp.
@@ -229,8 +228,7 @@ Status renameCollection(OperationContext* opCtx,
false); // _id index build with others later.
wunit.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "renameCollection", tmpName.ns());
+ });
}
// Dismissed on success
@@ -270,7 +268,7 @@ Status renameCollection(OperationContext* opCtx,
const auto obj = record->data.releaseToBson();
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ status = writeConflictRetry(opCtx, "renameCollection", tmpName.ns(), [&] {
WriteUnitOfWork wunit(opCtx);
// No logOp necessary because the entire renameCollection command is one logOp.
repl::UnreplicatedWritesBlock uwb(opCtx);
@@ -278,8 +276,12 @@ Status renameCollection(OperationContext* opCtx,
if (!status.isOK())
return status;
wunit.commit();
+ return Status::OK();
+ });
+
+ if (!status.isOK()) {
+ return status;
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "renameCollection", tmpName.ns());
}
}
@@ -290,7 +292,7 @@ Status renameCollection(OperationContext* opCtx,
// Getting here means we successfully built the target copy. We now do the final
// in-place rename and remove the source collection.
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ status = writeConflictRetry(opCtx, "renameCollection", tmpName.ns(), [&] {
WriteUnitOfWork wunit(opCtx);
indexer.commit();
OptionalCollectionUUID dropTargetUUID;
@@ -311,18 +313,15 @@ Status renameCollection(OperationContext* opCtx,
}
getGlobalServiceContext()->getOpObserver()->onRenameCollection(
- opCtx,
- source,
- target,
- newUUID,
- dropTarget,
- dropTargetUUID,
- /*dropSourceUUID*/ sourceUUID,
- stayTemp);
+ opCtx, source, target, newUUID, dropTarget, dropTargetUUID, sourceUUID, stayTemp);
wunit.commit();
+ return Status::OK();
+ });
+
+ if (!status.isOK()) {
+ return status;
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "renameCollection", tmpName.ns());
tmpCollectionDropper.Dismiss();
return Status::OK();
diff --git a/src/mongo/db/cloner.cpp b/src/mongo/db/cloner.cpp
index 0d294656632..a160d1fe383 100644
--- a/src/mongo/db/cloner.cpp
+++ b/src/mongo/db/cloner.cpp
@@ -162,7 +162,7 @@ struct Cloner::Fun {
str::stream() << "collection dropped during clone [" << to_collection.ns()
<< "]",
!createdCollection);
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "createCollection", to_collection.ns(), [&] {
opCtx->checkForInterrupt();
WriteUnitOfWork wunit(opCtx);
@@ -177,8 +177,7 @@ struct Cloner::Fun {
verify(s.isOK());
wunit.commit();
collection = db->getCollection(opCtx, to_collection);
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "createCollection", to_collection.ns());
+ });
}
const bool isSystemViewsClone = to_collection.isSystemDotViews();
@@ -258,7 +257,8 @@ struct Cloner::Fun {
verify(collection);
++numSeen;
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+
+ writeConflictRetry(opCtx, "cloner insert", to_collection.ns(), [&] {
opCtx->checkForInterrupt();
WriteUnitOfWork wunit(opCtx);
@@ -274,8 +274,8 @@ struct Cloner::Fun {
if (status.isOK()) {
wunit.commit();
}
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "cloner insert", to_collection.ns());
+ });
+
RARELY if (time(0) - saveLast > 60) {
log() << numSeen << " objects cloned so far from collection " << from_collection;
saveLast = time(0);
@@ -370,7 +370,7 @@ void Cloner::copyIndexes(OperationContext* opCtx,
Collection* collection = db->getCollection(opCtx, to_collection);
if (!collection) {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "createCollection", to_collection.ns(), [&] {
opCtx->checkForInterrupt();
WriteUnitOfWork wunit(opCtx);
@@ -387,8 +387,7 @@ void Cloner::copyIndexes(OperationContext* opCtx,
collection = db->getCollection(opCtx, to_collection);
invariant(collection);
wunit.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "createCollection", to_collection.ns());
+ });
}
// TODO pass the MultiIndexBlock when inserting into the collection rather than building the
@@ -469,7 +468,7 @@ bool Cloner::copyCollection(OperationContext* opCtx,
Database* db = dbHolder().openDb(opCtx, dbname);
if (shouldCreateCollection) {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ bool result = writeConflictRetry(opCtx, "createCollection", ns, [&] {
opCtx->checkForInterrupt();
WriteUnitOfWork wunit(opCtx);
@@ -486,9 +485,14 @@ bool Cloner::copyCollection(OperationContext* opCtx,
// abort write unit of work
return false;
}
+
wunit.commit();
+ return true;
+ });
+
+ if (!result) {
+ return result;
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "createCollection", ns);
} else {
LOG(1) << "No collection info found for ns:" << nss.toString()
<< ", host:" << _conn->getServerAddress();
@@ -565,7 +569,7 @@ Status Cloner::createCollectionsForDb(
const NamespaceString nss(dbName, params.collectionName);
uassertStatusOK(userAllowedCreateNS(dbName, params.collectionName));
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ Status status = writeConflictRetry(opCtx, "createCollection", nss.ns(), [&] {
opCtx->checkForInterrupt();
WriteUnitOfWork wunit(opCtx);
@@ -583,9 +587,15 @@ Status Cloner::createCollectionsForDb(
}
wunit.commit();
+ return Status::OK();
+ });
+
+ // Break early if one of the creations fails.
+ if (!status.isOK()) {
+ return status;
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "createCollection", nss.ns());
}
+
return Status::OK();
}
diff --git a/src/mongo/db/commands/create_indexes.cpp b/src/mongo/db/commands/create_indexes.cpp
index 77feecc13a0..4134c300cd0 100644
--- a/src/mongo/db/commands/create_indexes.cpp
+++ b/src/mongo/db/commands/create_indexes.cpp
@@ -267,13 +267,12 @@ public:
return appendCommandStatus(result, {ErrorCodes::CommandNotSupportedOnView, errmsg});
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, kCommandName, ns.ns(), [&] {
WriteUnitOfWork wunit(opCtx);
collection = db->createCollection(opCtx, ns.ns(), CollectionOptions());
invariant(collection);
wunit.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, kCommandName, ns.ns());
+ });
result.appendBool("createdCollectionAutomatically", true);
}
@@ -321,11 +320,10 @@ public:
}
}
- std::vector<BSONObj> indexInfoObjs;
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
- indexInfoObjs = uassertStatusOK(indexer.init(specs));
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, kCommandName, ns.ns());
+ std::vector<BSONObj> indexInfoObjs =
+ writeConflictRetry(opCtx, kCommandName, ns.ns(), [&indexer, &specs] {
+ return uassertStatusOK(indexer.init(specs));
+ });
// If we're a background index, replace exclusive db lock with an intent lock, so that
// other readers and writers can proceed during this phase.
@@ -383,7 +381,7 @@ public:
uassert(28552, "collection dropped during index build", db->getCollection(opCtx, ns));
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, kCommandName, ns.ns(), [&] {
WriteUnitOfWork wunit(opCtx);
indexer.commit();
@@ -394,8 +392,7 @@ public:
}
wunit.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, kCommandName, ns.ns());
+ });
result.append("numIndexesAfter", collection->getIndexCatalog()->numIndexesTotal(opCtx));
diff --git a/src/mongo/db/commands/dbcommands.cpp b/src/mongo/db/commands/dbcommands.cpp
index 1c443cab40d..b1010263699 100644
--- a/src/mongo/db/commands/dbcommands.cpp
+++ b/src/mongo/db/commands/dbcommands.cpp
@@ -697,7 +697,7 @@ public:
BSONObj query = BSON("files_id" << jsobj["filemd5"] << "n" << GTE << n);
BSONObj sort = BSON("files_id" << 1 << "n" << 1);
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ return writeConflictRetry(opCtx, "filemd5", dbname, [&] {
auto qr = stdx::make_unique<QueryRequest>(nss);
qr->setFilter(query);
qr->setSort(sort);
@@ -706,7 +706,7 @@ public:
opCtx, std::move(qr), ExtensionsCallbackDisallowExtensions());
if (!statusWithCQ.isOK()) {
uasserted(17240, "Can't canonicalize query " + query.toString());
- return 0;
+ return false;
}
unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue());
@@ -724,7 +724,7 @@ public:
QueryPlannerParams::NO_TABLE_SCAN);
if (!statusWithPlanExecutor.isOK()) {
uasserted(17241, "Can't get executor for query " + query.toString());
- return 0;
+ return false;
}
auto exec = std::move(statusWithPlanExecutor.getValue());
@@ -788,9 +788,9 @@ public:
result.append("numChunks", n);
result.append("md5", digestToString(d));
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "filemd5", dbname);
- return true;
+
+ return true;
+ });
}
void dumpChunks(OperationContext* opCtx,
diff --git a/src/mongo/db/commands/find_and_modify.cpp b/src/mongo/db/commands/find_and_modify.cpp
index 202bbdbf8f6..07d8dd7eaea 100644
--- a/src/mongo/db/commands/find_and_modify.cpp
+++ b/src/mongo/db/commands/find_and_modify.cpp
@@ -379,7 +379,7 @@ public:
// Although usually the PlanExecutor handles WCE internally, it will throw WCEs when it is
// executing a findAndModify. This is done to ensure that we can always match, modify, and
// return the document under concurrency, if a matching document exists.
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ bool success = writeConflictRetry(opCtx, "findAndModify", nsString.ns(), [&] {
if (args.isRemove()) {
DeleteRequest request(nsString);
const bool isExplain = false;
@@ -388,7 +388,8 @@ public:
ParsedDelete parsedDelete(opCtx, &request);
Status parsedDeleteStatus = parsedDelete.parseRequest();
if (!parsedDeleteStatus.isOK()) {
- return appendCommandStatus(result, parsedDeleteStatus);
+ appendCommandStatus(result, parsedDeleteStatus);
+ return false;
}
AutoGetOrCreateDb autoDb(opCtx, dbName, MODE_IX);
@@ -406,19 +407,22 @@ public:
Status isPrimary = checkCanAcceptWritesForDatabase(opCtx, nsString);
if (!isPrimary.isOK()) {
- return appendCommandStatus(result, isPrimary);
+ appendCommandStatus(result, isPrimary);
+ return false;
}
Collection* const collection = autoDb.getDb()->getCollection(opCtx, nsString);
if (!collection && autoDb.getDb()->getViewCatalog()->lookup(opCtx, nsString.ns())) {
- return appendCommandStatus(result,
- {ErrorCodes::CommandNotSupportedOnView,
- "findAndModify not supported on a view"});
+ appendCommandStatus(result,
+ {ErrorCodes::CommandNotSupportedOnView,
+ "findAndModify not supported on a view"});
+ return false;
}
auto statusWithPlanExecutor =
getExecutorDelete(opCtx, opDebug, collection, &parsedDelete);
if (!statusWithPlanExecutor.isOK()) {
- return appendCommandStatus(result, statusWithPlanExecutor.getStatus());
+ appendCommandStatus(result, statusWithPlanExecutor.getStatus());
+ return false;
}
const auto exec = std::move(statusWithPlanExecutor.getValue());
@@ -430,7 +434,8 @@ public:
StatusWith<boost::optional<BSONObj>> advanceStatus =
advanceExecutor(opCtx, exec.get(), args.isRemove());
if (!advanceStatus.isOK()) {
- return appendCommandStatus(result, advanceStatus.getStatus());
+ appendCommandStatus(result, advanceStatus.getStatus());
+ return false;
}
// Nothing after advancing the plan executor should throw a WriteConflictException,
// so the following bookkeeping with execution stats won't end up being done
@@ -464,7 +469,8 @@ public:
ParsedUpdate parsedUpdate(opCtx, &request);
Status parsedUpdateStatus = parsedUpdate.parseRequest();
if (!parsedUpdateStatus.isOK()) {
- return appendCommandStatus(result, parsedUpdateStatus);
+ appendCommandStatus(result, parsedUpdateStatus);
+ return false;
}
AutoGetOrCreateDb autoDb(opCtx, dbName, MODE_IX);
@@ -482,14 +488,16 @@ public:
Status isPrimary = checkCanAcceptWritesForDatabase(opCtx, nsString);
if (!isPrimary.isOK()) {
- return appendCommandStatus(result, isPrimary);
+ appendCommandStatus(result, isPrimary);
+ return false;
}
Collection* collection = autoDb.getDb()->getCollection(opCtx, nsString.ns());
if (!collection && autoDb.getDb()->getViewCatalog()->lookup(opCtx, nsString.ns())) {
- return appendCommandStatus(result,
- {ErrorCodes::CommandNotSupportedOnView,
- "findAndModify not supported on a view"});
+ appendCommandStatus(result,
+ {ErrorCodes::CommandNotSupportedOnView,
+ "findAndModify not supported on a view"});
+ return false;
}
// Create the collection if it does not exist when performing an upsert
@@ -501,7 +509,8 @@ public:
collection = autoDb.getDb()->getCollection(opCtx, nsString);
Status isPrimaryAfterRelock = checkCanAcceptWritesForDatabase(opCtx, nsString);
if (!isPrimaryAfterRelock.isOK()) {
- return appendCommandStatus(result, isPrimaryAfterRelock);
+ appendCommandStatus(result, isPrimaryAfterRelock);
+ return false;
}
if (collection) {
@@ -511,7 +520,8 @@ public:
Status createCollStatus =
userCreateNS(opCtx, autoDb.getDb(), nsString.ns(), BSONObj());
if (!createCollStatus.isOK()) {
- return appendCommandStatus(result, createCollStatus);
+ appendCommandStatus(result, createCollStatus);
+ return false;
}
wuow.commit();
@@ -523,7 +533,8 @@ public:
auto statusWithPlanExecutor =
getExecutorUpdate(opCtx, opDebug, collection, &parsedUpdate);
if (!statusWithPlanExecutor.isOK()) {
- return appendCommandStatus(result, statusWithPlanExecutor.getStatus());
+ appendCommandStatus(result, statusWithPlanExecutor.getStatus());
+ return false;
}
const auto exec = std::move(statusWithPlanExecutor.getValue());
@@ -535,7 +546,8 @@ public:
StatusWith<boost::optional<BSONObj>> advanceStatus =
advanceExecutor(opCtx, exec.get(), args.isRemove());
if (!advanceStatus.isOK()) {
- return appendCommandStatus(result, advanceStatus.getStatus());
+ appendCommandStatus(result, advanceStatus.getStatus());
+ return false;
}
// Nothing after advancing the plan executor should throw a WriteConflictException,
// so the following bookkeeping with execution stats won't end up being done
@@ -559,8 +571,12 @@ public:
boost::optional<BSONObj> value = advanceStatus.getValue();
appendCommandResponse(exec.get(), args.isRemove(), value, result);
}
+ return true;
+ });
+
+ if (!success) {
+ return false;
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "findAndModify", nsString.ns());
if (repl::ReplClientInfo::forClient(client).getLastOp() != lastOpAtOperationStart) {
// If this operation has already generated a new lastOp, don't bother setting it here.
diff --git a/src/mongo/db/commands/fsync.cpp b/src/mongo/db/commands/fsync.cpp
index 5359963d381..e776b10a451 100644
--- a/src/mongo/db/commands/fsync.cpp
+++ b/src/mongo/db/commands/fsync.cpp
@@ -366,10 +366,9 @@ void FSyncLockThread::run() {
return;
}
try {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(&opCtx, "beginBackup", "global", [&storageEngine, &opCtx] {
uassertStatusOK(storageEngine->beginBackup(&opCtx));
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(&opCtx, "beginBackup", "global");
+ });
} catch (const DBException& e) {
error() << "storage engine unable to begin backup : " << e.toString();
fsyncCmd.threadStatus = e.toStatus();
diff --git a/src/mongo/db/commands/list_indexes.cpp b/src/mongo/db/commands/list_indexes.cpp
index bada0092be4..557390465f1 100644
--- a/src/mongo/db/commands/list_indexes.cpp
+++ b/src/mongo/db/commands/list_indexes.cpp
@@ -148,21 +148,19 @@ public:
invariant(cce);
vector<string> indexNames;
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "listIndexes", ns.ns(), [&indexNames, &cce, &opCtx] {
indexNames.clear();
cce->getAllIndexes(opCtx, &indexNames);
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "listIndexes", ns.ns());
+ });
auto ws = make_unique<WorkingSet>();
auto root = make_unique<QueuedDataStage>(opCtx, ws.get());
for (size_t i = 0; i < indexNames.size(); i++) {
- BSONObj indexSpec;
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
- indexSpec = cce->getIndexSpec(opCtx, indexNames[i]);
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "listIndexes", ns.ns());
+ BSONObj indexSpec =
+ writeConflictRetry(opCtx, "listIndexes", ns.ns(), [&cce, &opCtx, &indexNames, i] {
+ return cce->getIndexSpec(opCtx, indexNames[i]);
+ });
WorkingSetID id = ws->allocate();
WorkingSetMember* member = ws->get(id);
diff --git a/src/mongo/db/commands/mr.cpp b/src/mongo/db/commands/mr.cpp
index 02eb08c1aab..4f4460df780 100644
--- a/src/mongo/db/commands/mr.cpp
+++ b/src/mongo/db/commands/mr.cpp
@@ -368,7 +368,7 @@ Config::Config(const string& _dbname, const BSONObj& cmdObj) {
*/
void State::dropTempCollections() {
if (!_config.tempNamespace.isEmpty()) {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(_opCtx, "M/R dropTempCollections", _config.tempNamespace.ns(), [this] {
AutoGetDb autoDb(_opCtx, _config.tempNamespace.db(), MODE_X);
if (auto db = autoDb.getDb()) {
WriteUnitOfWork wunit(_opCtx);
@@ -379,9 +379,7 @@ void State::dropTempCollections() {
db->dropCollection(_opCtx, _config.tempNamespace.ns()).transitional_ignore();
wunit.commit();
}
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(
- _opCtx, "M/R dropTempCollections", _config.tempNamespace.ns());
+ });
// Always forget about temporary namespaces, so we don't cache lots of them
ShardConnection::forgetNS(_config.tempNamespace.ns());
}
@@ -390,16 +388,14 @@ void State::dropTempCollections() {
// harmless, this would lead to a scary looking warning on the secondaries.
repl::UnreplicatedWritesBlock uwb(_opCtx);
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(_opCtx, "M/R dropTempCollections", _config.incLong.ns(), [this] {
Lock::DBLock lk(_opCtx, _config.incLong.db(), MODE_X);
if (Database* db = dbHolder().get(_opCtx, _config.incLong.ns())) {
WriteUnitOfWork wunit(_opCtx);
db->dropCollection(_opCtx, _config.incLong.ns()).transitional_ignore();
wunit.commit();
}
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(
- _opCtx, "M/R dropTempCollections", _config.incLong.ns());
+ });
ShardConnection::forgetNS(_config.incLong.ns());
}
@@ -418,7 +414,7 @@ void State::prepTempCollection() {
// Intentionally not replicating the inc collection to secondaries.
repl::UnreplicatedWritesBlock uwb(_opCtx);
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(_opCtx, "M/R prepTempCollection", _config.incLong.ns(), [this] {
OldClientWriteContext incCtx(_opCtx, _config.incLong.ns());
WriteUnitOfWork wuow(_opCtx);
Collection* incColl = incCtx.getCollection();
@@ -450,8 +446,7 @@ void State::prepTempCollection() {
<< status.code());
}
wuow.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(_opCtx, "M/R prepTempCollection", _config.incLong.ns());
+ });
}
CollectionOptions finalOptions;
@@ -485,7 +480,7 @@ void State::prepTempCollection() {
}
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(_opCtx, "M/R prepTempCollection", _config.tempNamespace.ns(), [&] {
// create temp collection and insert the indexes from temporary storage
OldClientWriteContext tempCtx(_opCtx, _config.tempNamespace.ns());
WriteUnitOfWork wuow(_opCtx);
@@ -519,9 +514,7 @@ void State::prepTempCollection() {
_opCtx, _config.tempNamespace, uuid, *it, false);
}
wuow.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(
- _opCtx, "M/R prepTempCollection", _config.tempNamespace.ns());
+ });
}
/**
@@ -741,7 +734,7 @@ long long State::postProcessCollectionNonAtomic(OperationContext* opCtx,
void State::insert(const NamespaceString& nss, const BSONObj& o) {
verify(_onDisk);
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(_opCtx, "M/R insert", nss.ns(), [this, &nss, &o] {
OldClientWriteContext ctx(_opCtx, nss.ns());
WriteUnitOfWork wuow(_opCtx);
uassert(ErrorCodes::PrimarySteppedDown,
@@ -766,8 +759,7 @@ void State::insert(const NamespaceString& nss, const BSONObj& o) {
OpDebug* const nullOpDebug = nullptr;
uassertStatusOK(coll->insertDocument(_opCtx, bo, nullOpDebug, true));
wuow.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(_opCtx, "M/R insert", nss.ns());
+ });
}
/**
@@ -776,7 +768,7 @@ void State::insert(const NamespaceString& nss, const BSONObj& o) {
void State::_insertToInc(BSONObj& o) {
verify(_onDisk);
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(_opCtx, "M/R insertToInc", _config.incLong.ns(), [this, &o] {
OldClientWriteContext ctx(_opCtx, _config.incLong.ns());
WriteUnitOfWork wuow(_opCtx);
Collection* coll = getCollectionOrUassert(_opCtx, ctx.db(), _config.incLong);
@@ -799,8 +791,7 @@ void State::_insertToInc(BSONObj& o) {
OpDebug* const nullOpDebug = nullptr;
uassertStatusOK(coll->insertDocument(_opCtx, o, nullOpDebug, true, false));
wuow.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(_opCtx, "M/R insertToInc", _config.incLong.ns());
+ });
}
State::State(OperationContext* opCtx, const Config& c)
@@ -1066,7 +1057,7 @@ void State::finalReduce(OperationContext* opCtx, CurOp* curOp, ProgressMeterHold
verify(_temp->size() == 0);
BSONObj sortKey = BSON("0" << 1);
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(_opCtx, "finalReduce", _config.incLong.ns(), [&] {
OldClientWriteContext incCtx(_opCtx, _config.incLong.ns());
WriteUnitOfWork wuow(_opCtx);
Collection* incColl = getCollectionOrUassert(_opCtx, incCtx.db(), _config.incLong);
@@ -1085,8 +1076,7 @@ void State::finalReduce(OperationContext* opCtx, CurOp* curOp, ProgressMeterHold
verify(foundIndex);
wuow.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(_opCtx, "finalReduce", _config.incLong.ns());
+ });
unique_ptr<AutoGetCollectionForReadCommand> ctx(
new AutoGetCollectionForReadCommand(_opCtx, _config.incLong));
diff --git a/src/mongo/db/commands/oplog_note.cpp b/src/mongo/db/commands/oplog_note.cpp
index 371057a68fa..d1edfcbdfb9 100644
--- a/src/mongo/db/commands/oplog_note.cpp
+++ b/src/mongo/db/commands/oplog_note.cpp
@@ -69,12 +69,11 @@ Status _performNoopWrite(OperationContext* opCtx, BSONObj msgObj, StringData not
return {ErrorCodes::NotMaster, "Not a primary"};
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, note, repl::rsOplogName, [&opCtx, &msgObj] {
WriteUnitOfWork uow(opCtx);
opCtx->getClient()->getServiceContext()->getOpObserver()->onOpMessage(opCtx, msgObj);
uow.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, note, repl::rsOplogName);
+ });
return Status::OK();
}
diff --git a/src/mongo/db/concurrency/write_conflict_exception.h b/src/mongo/db/concurrency/write_conflict_exception.h
index 5a053502727..a15086ae83c 100644
--- a/src/mongo/db/concurrency/write_conflict_exception.h
+++ b/src/mongo/db/concurrency/write_conflict_exception.h
@@ -36,30 +36,6 @@
#include "mongo/db/curop.h"
#include "mongo/util/assert_util.h"
-// Use of this macro is deprecated. Prefer the writeConflictRetry template, below, instead.
-
-// clang-format off
-
-#define MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN \
- do { \
- int WCR_attempts = 0; \
- do { \
- try
-#define MONGO_WRITE_CONFLICT_RETRY_LOOP_END(PTXN, OPSTR, NSSTR) \
- catch (const ::mongo::WriteConflictException& WCR_wce) { \
- OperationContext const* WCR_opCtx = (PTXN); \
- ++CurOp::get(WCR_opCtx)->debug().writeConflicts; \
- WCR_wce.logAndBackoff(WCR_attempts, (OPSTR), (NSSTR)); \
- ++WCR_attempts; \
- WCR_opCtx->recoveryUnit()->abandonSnapshot(); \
- continue; \
- } \
- break; \
- } while (true); \
- } while (false)
-
-// clang-format on
-
namespace mongo {
/**
diff --git a/src/mongo/db/exec/update.cpp b/src/mongo/db/exec/update.cpp
index c3dae9389fb..879a5c7db05 100644
--- a/src/mongo/db/exec/update.cpp
+++ b/src/mongo/db/exec/update.cpp
@@ -476,7 +476,8 @@ void UpdateStage::doInsert() {
if (request->isExplain()) {
return;
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+
+ writeConflictRetry(getOpCtx(), "upsert", _collection->ns().ns(), [&] {
WriteUnitOfWork wunit(getOpCtx());
invariant(_collection);
const bool enforceQuota = !request->isGod();
@@ -486,8 +487,7 @@ void UpdateStage::doInsert() {
// Technically, we should save/restore state here, but since we are going to return
// immediately after, it would just be wasted work.
wunit.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(getOpCtx(), "upsert", _collection->ns().ns());
+ });
}
bool UpdateStage::doneUpdating() {
diff --git a/src/mongo/db/index/index_access_method.cpp b/src/mongo/db/index/index_access_method.cpp
index b52092a6cb0..80d031a680c 100644
--- a/src/mongo/db/index/index_access_method.cpp
+++ b/src/mongo/db/index/index_access_method.cpp
@@ -475,7 +475,7 @@ Status IndexAccessMethod::commitBulk(OperationContext* opCtx,
std::unique_ptr<SortedDataBuilderInterface> builder;
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "setting index multikey flag", "", [&] {
WriteUnitOfWork wunit(opCtx);
if (bulk->_everGeneratedMultipleKeys || isMultikeyFromPaths(bulk->_indexMultikeyPaths)) {
@@ -484,8 +484,7 @@ Status IndexAccessMethod::commitBulk(OperationContext* opCtx,
builder.reset(_newInterface->getBulkBuilder(opCtx, dupsAllowed));
wunit.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "setting index multikey flag", "");
+ });
while (i->more()) {
if (mayInterrupt) {
diff --git a/src/mongo/db/ops/update.cpp b/src/mongo/db/ops/update.cpp
index 078d2f30f25..86822feef00 100644
--- a/src/mongo/db/ops/update.cpp
+++ b/src/mongo/db/ops/update.cpp
@@ -86,7 +86,7 @@ UpdateResult update(OperationContext* opCtx, Database* db, const UpdateRequest&
invariant(locker->isW() ||
locker->isLockHeldForMode(ResourceId(RESOURCE_DATABASE, nsString.db()), MODE_X));
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "createCollection", nsString.ns(), [&] {
Lock::DBLock lk(opCtx, nsString.db(), MODE_X);
const bool userInitiatedWritesAndNotPrimary = opCtx->writesAreReplicated() &&
@@ -102,8 +102,7 @@ UpdateResult update(OperationContext* opCtx, Database* db, const UpdateRequest&
collection = db->createCollection(opCtx, nsString.ns(), CollectionOptions());
invariant(collection);
wuow.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "createCollection", nsString.ns());
+ });
}
// Parse the update, get an executor for it, run the executor, get stats out.
diff --git a/src/mongo/db/ops/write_ops_exec.cpp b/src/mongo/db/ops/write_ops_exec.cpp
index 3c3b9394296..8991ab15224 100644
--- a/src/mongo/db/ops/write_ops_exec.cpp
+++ b/src/mongo/db/ops/write_ops_exec.cpp
@@ -175,7 +175,7 @@ void assertCanWrite_inlock(OperationContext* opCtx, const NamespaceString& ns) {
}
void makeCollection(OperationContext* opCtx, const NamespaceString& ns) {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "implicit collection creation", ns.ns(), [&opCtx, &ns] {
AutoGetOrCreateDb db(opCtx, ns.db(), MODE_X);
assertCanWrite_inlock(opCtx, ns);
if (!db.getDb()->getCollection(opCtx, ns)) { // someone else may have beat us to it.
@@ -183,8 +183,7 @@ void makeCollection(OperationContext* opCtx, const NamespaceString& ns) {
uassertStatusOK(userCreateNS(opCtx, db.getDb(), ns.ns(), BSONObj()));
wuow.commit();
}
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "implicit collection creation", ns.ns());
+ });
}
/**
@@ -371,7 +370,7 @@ static bool insertBatchAndHandleErrors(OperationContext* opCtx,
for (auto it = batch.begin(); it != batch.end(); ++it) {
globalOpCounters.gotInsert();
try {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "insert", wholeOp.ns.ns(), [&] {
try {
if (!collection)
acquireCollection();
@@ -388,8 +387,7 @@ static bool insertBatchAndHandleErrors(OperationContext* opCtx,
collection.reset();
throw;
}
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "insert", wholeOp.ns.ns());
+ });
} catch (const DBException& ex) {
bool canContinue = handleError(opCtx, ex, wholeOp, out);
if (!canContinue)
diff --git a/src/mongo/db/query/plan_yield_policy.cpp b/src/mongo/db/query/plan_yield_policy.cpp
index b7a8f0225ea..52633ea0185 100644
--- a/src/mongo/db/query/plan_yield_policy.cpp
+++ b/src/mongo/db/query/plan_yield_policy.cpp
@@ -86,8 +86,7 @@ bool PlanYieldPolicy::yield(RecordFetcher* fetcher) {
invariant(opCtx);
invariant(!opCtx->lockState()->inAWriteUnitOfWork());
- // Can't use MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN/END since we need to call saveState
- // before reseting the transaction.
+ // Can't use writeConflictRetry since we need to call saveState before reseting the transaction.
for (int attempt = 1; true; attempt++) {
try {
// All YIELD_AUTO plans will get here eventually when the elapsed tracker triggers
diff --git a/src/mongo/db/read_concern.cpp b/src/mongo/db/read_concern.cpp
index a2f79eeea95..b0266a169af 100644
--- a/src/mongo/db/read_concern.cpp
+++ b/src/mongo/db/read_concern.cpp
@@ -245,17 +245,14 @@ Status waitForLinearizableReadConcern(OperationContext* opCtx) {
"No longer primary when waiting for linearizable read concern"};
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
-
+ writeConflictRetry(opCtx, "waitForLinearizableReadConcern", "local.rs.oplog", [&opCtx] {
WriteUnitOfWork uow(opCtx);
opCtx->getClient()->getServiceContext()->getOpObserver()->onOpMessage(
opCtx,
BSON("msg"
<< "linearizable read"));
uow.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(
- opCtx, "waitForLinearizableReadConcern", "local.rs.oplog");
+ });
}
WriteConcernOptions wc = WriteConcernOptions(
WriteConcernOptions::kMajority, WriteConcernOptions::SyncMode::UNSET, 0);
diff --git a/src/mongo/db/repl/apply_ops.cpp b/src/mongo/db/repl/apply_ops.cpp
index 446133b79ad..d08cff9f8a5 100644
--- a/src/mongo/db/repl/apply_ops.cpp
+++ b/src/mongo/db/repl/apply_ops.cpp
@@ -145,7 +145,7 @@ Status _applyOps(OperationContext* opCtx,
return status;
} else {
try {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "applyOps", ns, [&] {
if (*opType == 'c') {
status = repl::applyCommand_inlock(opCtx, opObj, true);
} else {
@@ -181,8 +181,7 @@ Status _applyOps(OperationContext* opCtx,
repl::applyOperation_inlock(opCtx, ctx.db(), opObj, alwaysUpsert);
}
}
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "applyOps", ns);
+ });
} catch (const DBException& ex) {
ab.append(false);
result->append("applied", ++(*numApplied));
@@ -288,7 +287,7 @@ mongo::Status mongo::applyOps(OperationContext* opCtx,
// Perform write ops atomically
try {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "applyOps", dbName, [&] {
BSONObjBuilder intermediateResult;
WriteUnitOfWork wunit(opCtx);
numApplied = 0;
@@ -322,8 +321,7 @@ mongo::Status mongo::applyOps(OperationContext* opCtx,
}
wunit.commit();
result->appendElements(intermediateResult.obj());
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "applyOps", dbName);
+ });
} catch (const DBException& ex) {
if (ex.getCode() == ErrorCodes::NamespaceNotFound) {
// Retry in non-atomic mode, since MMAP cannot implicitly create a new database
diff --git a/src/mongo/db/repl/bgsync.cpp b/src/mongo/db/repl/bgsync.cpp
index 5eeb0136c16..e0b2e7a9be7 100644
--- a/src/mongo/db/repl/bgsync.cpp
+++ b/src/mongo/db/repl/bgsync.cpp
@@ -837,16 +837,16 @@ void BackgroundSync::clearBuffer(OperationContext* opCtx) {
OpTimeWithHash BackgroundSync::_readLastAppliedOpTimeWithHash(OperationContext* opCtx) {
BSONObj oplogEntry;
try {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ bool success = writeConflictRetry(opCtx, "readLastAppliedHash", rsOplogName, [&] {
Lock::DBLock lk(opCtx, "local", MODE_X);
- bool success = Helpers::getLast(opCtx, rsOplogName.c_str(), oplogEntry);
- if (!success) {
- // This can happen when we are to do an initial sync. lastHash will be set
- // after the initial sync is complete.
- return OpTimeWithHash(0);
- }
+ return Helpers::getLast(opCtx, rsOplogName.c_str(), oplogEntry);
+ });
+
+ if (!success) {
+ // This can happen when we are to do an initial sync. lastHash will be set
+ // after the initial sync is complete.
+ return OpTimeWithHash(0);
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "readLastAppliedHash", rsOplogName);
} catch (const DBException& ex) {
severe() << "Problem reading " << rsOplogName << ": " << redact(ex);
fassertFailed(18904);
diff --git a/src/mongo/db/repl/collection_bulk_loader_impl.cpp b/src/mongo/db/repl/collection_bulk_loader_impl.cpp
index abfe67a63cb..c7118429ba9 100644
--- a/src/mongo/db/repl/collection_bulk_loader_impl.cpp
+++ b/src/mongo/db/repl/collection_bulk_loader_impl.cpp
@@ -152,30 +152,37 @@ Status CollectionBulkLoaderImpl::insertDocuments(const std::vector<BSONObj>::con
if (_secondaryIndexesBlock) {
indexers.push_back(_secondaryIndexesBlock.get());
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
- WriteUnitOfWork wunit(_opCtx.get());
- if (!indexers.empty()) {
- // This flavor of insertDocument will not update any pre-existing indexes, only
- // the indexers passed in.
- const auto status = _autoColl->getCollection()->insertDocument(
- _opCtx.get(), *iter, indexers, false);
- if (!status.isOK()) {
- return status;
- }
- } else {
- // For capped collections, we use regular insertDocument, which will update
- // pre-existing indexes.
- const auto status = _autoColl->getCollection()->insertDocument(
- _opCtx.get(), *iter, nullptr, false);
- if (!status.isOK()) {
- return status;
+
+ Status status = writeConflictRetry(
+ _opCtx.get(), "CollectionBulkLoaderImpl::insertDocuments", _nss.ns(), [&] {
+ WriteUnitOfWork wunit(_opCtx.get());
+ if (!indexers.empty()) {
+ // This flavor of insertDocument will not update any pre-existing indexes,
+ // only
+ // the indexers passed in.
+ const auto status = _autoColl->getCollection()->insertDocument(
+ _opCtx.get(), *iter, indexers, false);
+ if (!status.isOK()) {
+ return status;
+ }
+ } else {
+ // For capped collections, we use regular insertDocument, which will update
+ // pre-existing indexes.
+ const auto status = _autoColl->getCollection()->insertDocument(
+ _opCtx.get(), *iter, nullptr, false);
+ if (!status.isOK()) {
+ return status;
+ }
}
- }
- wunit.commit();
+ wunit.commit();
+
+ return Status::OK();
+ });
+
+ if (!status.isOK()) {
+ return status;
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(
- _opCtx.get(), "CollectionBulkLoaderImpl::insertDocuments", _nss.ns());
++count;
}
@@ -203,13 +210,11 @@ Status CollectionBulkLoaderImpl::commit() {
<< " duplicates on secondary index(es) even though "
"MultiIndexBlock::ignoreUniqueConstraint set."};
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(_opCtx.get(), "CollectionBulkLoaderImpl::commit", _nss.ns(), [this] {
WriteUnitOfWork wunit(_opCtx.get());
_secondaryIndexesBlock->commit();
wunit.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(
- _opCtx.get(), "CollectionBulkLoaderImpl::commit", _nss.ns());
+ });
}
if (_idIndexBlock) {
@@ -222,27 +227,24 @@ Status CollectionBulkLoaderImpl::commit() {
}
for (auto&& it : dups) {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
- WriteUnitOfWork wunit(_opCtx.get());
- _autoColl->getCollection()->deleteDocument(_opCtx.get(),
- it,
- nullptr /** OpDebug **/,
- false /* fromMigrate */,
- true /* noWarn */);
- wunit.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(
- _opCtx.get(), "CollectionBulkLoaderImpl::commit", _nss.ns());
+ writeConflictRetry(
+ _opCtx.get(), "CollectionBulkLoaderImpl::commit", _nss.ns(), [this, &it] {
+ WriteUnitOfWork wunit(_opCtx.get());
+ _autoColl->getCollection()->deleteDocument(_opCtx.get(),
+ it,
+ nullptr /** OpDebug **/,
+ false /* fromMigrate */,
+ true /* noWarn */);
+ wunit.commit();
+ });
}
// Commit _id index, without dups.
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(_opCtx.get(), "CollectionBulkLoaderImpl::commit", _nss.ns(), [this] {
WriteUnitOfWork wunit(_opCtx.get());
_idIndexBlock->commit();
wunit.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(
- _opCtx.get(), "CollectionBulkLoaderImpl::commit", _nss.ns());
+ });
}
_stats.endBuildingIndexes = Date_t::now();
LOG(2) << "Done creating indexes for ns: " << _nss.ns() << ", stats: " << _stats.toString();
diff --git a/src/mongo/db/repl/noop_writer.cpp b/src/mongo/db/repl/noop_writer.cpp
index c82eb575ae1..76603129a83 100644
--- a/src/mongo/db/repl/noop_writer.cpp
+++ b/src/mongo/db/repl/noop_writer.cpp
@@ -167,13 +167,12 @@ void NoopWriter::_writeNoop(OperationContext* opCtx) {
LOG(logLevel)
<< "Writing noop to oplog as there has been no writes to this replica set in over "
<< _writeInterval;
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "writeNoop", rsOplogName, [&opCtx] {
WriteUnitOfWork uow(opCtx);
opCtx->getClient()->getServiceContext()->getOpObserver()->onOpMessage(opCtx,
kMsgObj);
uow.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "writeNoop", rsOplogName);
+ });
}
}
diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp
index 9baa4b211cc..b82fb22629a 100644
--- a/src/mongo/db/repl/oplog.cpp
+++ b/src/mongo/db/repl/oplog.cpp
@@ -534,14 +534,13 @@ void createOplog(OperationContext* opCtx, const std::string& oplogCollectionName
options.cappedSize = sz;
options.autoIndexId = CollectionOptions::NO;
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "createCollection", oplogCollectionName, [&] {
WriteUnitOfWork uow(opCtx);
invariant(ctx.db()->createCollection(opCtx, oplogCollectionName, options));
if (!isReplSet)
getGlobalServiceContext()->getOpObserver()->onOpMessage(opCtx, BSONObj());
uow.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "createCollection", oplogCollectionName);
+ });
/* sync here so we don't get any surprising lag later when we try to sync */
StorageEngine* storageEngine = getGlobalServiceContext()->getGlobalStorageEngine();
diff --git a/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp b/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp
index 4d328f5f1de..9ae171ccaec 100644
--- a/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp
@@ -379,17 +379,17 @@ Status ReplicationCoordinatorExternalStateImpl::initializeReplSetStorage(Operati
try {
createOplog(opCtx);
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
- Lock::GlobalWrite globalWrite(opCtx);
-
- WriteUnitOfWork wuow(opCtx);
- Helpers::putSingleton(opCtx, configCollectionName, config);
- const auto msgObj = BSON("msg"
- << "initiating set");
- _service->getOpObserver()->onOpMessage(opCtx, msgObj);
- wuow.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "initiate oplog entry", "local.oplog.rs");
+ writeConflictRetry(
+ opCtx, "initiate oplog entry", "local.oplog.rs", [this, &opCtx, &config] {
+ Lock::GlobalWrite globalWrite(opCtx);
+
+ WriteUnitOfWork wuow(opCtx);
+ Helpers::putSingleton(opCtx, configCollectionName, config);
+ const auto msgObj = BSON("msg"
+ << "initiating set");
+ _service->getOpObserver()->onOpMessage(opCtx, msgObj);
+ wuow.commit();
+ });
FeatureCompatibilityVersion::setIfCleanStartup(opCtx, _storageInterface);
} catch (const DBException& ex) {
@@ -420,16 +420,14 @@ OpTime ReplicationCoordinatorExternalStateImpl::onTransitionToPrimary(OperationC
_replicationProcess->getConsistencyMarkers()->setAppliedThrough(opCtx, {});
if (isV1ElectionProtocol) {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "logging transition to primary to oplog", "local.oplog.rs", [&] {
WriteUnitOfWork wuow(opCtx);
opCtx->getClient()->getServiceContext()->getOpObserver()->onOpMessage(
opCtx,
BSON("msg"
<< "new primary"));
wuow.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(
- opCtx, "logging transition to primary to oplog", "local.oplog.rs");
+ });
}
const auto opTimeToReturn = fassertStatusOK(28665, loadLastOpTime(opCtx));
@@ -476,7 +474,7 @@ OID ReplicationCoordinatorExternalStateImpl::ensureMe(OperationContext* opCtx) {
StatusWith<BSONObj> ReplicationCoordinatorExternalStateImpl::loadLocalConfigDocument(
OperationContext* opCtx) {
try {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ return writeConflictRetry(opCtx, "load replica set config", configCollectionName, [opCtx] {
BSONObj config;
if (!Helpers::getSingleton(opCtx, configCollectionName, config)) {
return StatusWith<BSONObj>(
@@ -485,8 +483,7 @@ StatusWith<BSONObj> ReplicationCoordinatorExternalStateImpl::loadLocalConfigDocu
<< configCollectionName);
}
return StatusWith<BSONObj>(config);
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "load replica set config", configCollectionName);
+ });
} catch (const DBException& ex) {
return StatusWith<BSONObj>(ex.toStatus());
}
@@ -495,12 +492,12 @@ StatusWith<BSONObj> ReplicationCoordinatorExternalStateImpl::loadLocalConfigDocu
Status ReplicationCoordinatorExternalStateImpl::storeLocalConfigDocument(OperationContext* opCtx,
const BSONObj& config) {
try {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "save replica set config", configCollectionName, [&] {
Lock::DBLock dbWriteLock(opCtx, configDatabaseName, MODE_X);
Helpers::putSingleton(opCtx, configCollectionName, config);
- return Status::OK();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "save replica set config", configCollectionName);
+ });
+
+ return Status::OK();
} catch (const DBException& ex) {
return ex.toStatus();
}
@@ -509,18 +506,17 @@ Status ReplicationCoordinatorExternalStateImpl::storeLocalConfigDocument(Operati
StatusWith<LastVote> ReplicationCoordinatorExternalStateImpl::loadLocalLastVoteDocument(
OperationContext* opCtx) {
try {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
- BSONObj lastVoteObj;
- if (!Helpers::getSingleton(opCtx, lastVoteCollectionName, lastVoteObj)) {
- return StatusWith<LastVote>(ErrorCodes::NoMatchingDocument,
- str::stream()
- << "Did not find replica set lastVote document in "
- << lastVoteCollectionName);
- }
- return LastVote::readFromLastVote(lastVoteObj);
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(
- opCtx, "load replica set lastVote", lastVoteCollectionName);
+ return writeConflictRetry(
+ opCtx, "load replica set lastVote", lastVoteCollectionName, [opCtx] {
+ BSONObj lastVoteObj;
+ if (!Helpers::getSingleton(opCtx, lastVoteCollectionName, lastVoteObj)) {
+ return StatusWith<LastVote>(
+ ErrorCodes::NoMatchingDocument,
+ str::stream() << "Did not find replica set lastVote document in "
+ << lastVoteCollectionName);
+ }
+ return LastVote::readFromLastVote(lastVoteObj);
+ });
} catch (const DBException& ex) {
return StatusWith<LastVote>(ex.toStatus());
}
@@ -530,30 +526,37 @@ Status ReplicationCoordinatorExternalStateImpl::storeLocalLastVoteDocument(
OperationContext* opCtx, const LastVote& lastVote) {
BSONObj lastVoteObj = lastVote.toBSON();
try {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
- Lock::DBLock dbWriteLock(opCtx, lastVoteDatabaseName, MODE_X);
-
- // If there is no last vote document, we want to store one. Otherwise, we only want to
- // replace it if the new last vote document would have a higher term. We both check
- // the term of the current last vote document and insert the new document under the
- // DBLock to synchronize the two operations.
- BSONObj result;
- bool exists = Helpers::getSingleton(opCtx, lastVoteCollectionName, result);
- if (!exists) {
- Helpers::putSingleton(opCtx, lastVoteCollectionName, lastVoteObj);
- } else {
- StatusWith<LastVote> oldLastVoteDoc = LastVote::readFromLastVote(result);
- if (!oldLastVoteDoc.isOK()) {
- return oldLastVoteDoc.getStatus();
- }
- if (lastVote.getTerm() > oldLastVoteDoc.getValue().getTerm()) {
+ Status status =
+ writeConflictRetry(opCtx, "save replica set lastVote", lastVoteCollectionName, [&] {
+ Lock::DBLock dbWriteLock(opCtx, lastVoteDatabaseName, MODE_X);
+
+ // If there is no last vote document, we want to store one. Otherwise, we only want
+ // to replace it if the new last vote document would have a higher term. We both
+ // check the term of the current last vote document and insert the new document
+ // under the DBLock to synchronize the two operations.
+ BSONObj result;
+ bool exists = Helpers::getSingleton(opCtx, lastVoteCollectionName, result);
+ if (!exists) {
Helpers::putSingleton(opCtx, lastVoteCollectionName, lastVoteObj);
+ } else {
+ StatusWith<LastVote> oldLastVoteDoc = LastVote::readFromLastVote(result);
+ if (!oldLastVoteDoc.isOK()) {
+ return oldLastVoteDoc.getStatus();
+ }
+ if (lastVote.getTerm() > oldLastVoteDoc.getValue().getTerm()) {
+ Helpers::putSingleton(opCtx, lastVoteCollectionName, lastVoteObj);
+ }
}
- }
+
+ return Status::OK();
+ });
+
+ if (!status.isOK()) {
+ return status;
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(
- opCtx, "save replica set lastVote", lastVoteCollectionName);
+
opCtx->recoveryUnit()->waitUntilDurable();
+
return Status::OK();
} catch (const DBException& ex) {
return ex.toStatus();
diff --git a/src/mongo/db/repl/rs_rollback.cpp b/src/mongo/db/repl/rs_rollback.cpp
index 4531276bfd2..8054c31c5e3 100644
--- a/src/mongo/db/repl/rs_rollback.cpp
+++ b/src/mongo/db/repl/rs_rollback.cpp
@@ -777,13 +777,12 @@ void syncFixUp(OperationContext* opCtx,
} catch (const DBException& e) {
if (e.getCode() == 13415) {
// hack: need to just make cappedTruncate do this...
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
- WriteUnitOfWork wunit(opCtx);
- uassertStatusOK(collection->truncate(opCtx));
- wunit.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(
- opCtx, "truncate", collection->ns().ns());
+ writeConflictRetry(
+ opCtx, "truncate", collection->ns().ns(), [&] {
+ WriteUnitOfWork wunit(opCtx);
+ uassertStatusOK(collection->truncate(opCtx));
+ wunit.commit();
+ });
} else {
throw e;
}
diff --git a/src/mongo/db/repl/rs_rollback_no_uuid.cpp b/src/mongo/db/repl/rs_rollback_no_uuid.cpp
index 1e93966d027..d5391e8bda9 100644
--- a/src/mongo/db/repl/rs_rollback_no_uuid.cpp
+++ b/src/mongo/db/repl/rs_rollback_no_uuid.cpp
@@ -758,13 +758,12 @@ void syncFixUp(OperationContext* opCtx,
} catch (const DBException& e) {
if (e.getCode() == 13415) {
// hack: need to just make cappedTruncate do this...
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
- WriteUnitOfWork wunit(opCtx);
- uassertStatusOK(collection->truncate(opCtx));
- wunit.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(
- opCtx, "truncate", collection->ns().ns());
+ writeConflictRetry(
+ opCtx, "truncate", collection->ns().ns(), [&] {
+ WriteUnitOfWork wunit(opCtx);
+ uassertStatusOK(collection->truncate(opCtx));
+ wunit.commit();
+ });
} else {
throw e;
}
diff --git a/src/mongo/db/repl/storage_interface_impl.cpp b/src/mongo/db/repl/storage_interface_impl.cpp
index 7422b8c913d..251518cc1d0 100644
--- a/src/mongo/db/repl/storage_interface_impl.cpp
+++ b/src/mongo/db/repl/storage_interface_impl.cpp
@@ -196,7 +196,7 @@ StorageInterfaceImpl::createCollectionForBulkLoading(
std::unique_ptr<AutoGetCollection> autoColl;
// Retry if WCE.
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ Status status = writeConflictRetry(opCtx.get(), "beginCollectionClone", nss.ns(), [&] {
UnreplicatedWritesBlock uwb(opCtx.get());
// Get locks and create the collection.
@@ -204,8 +204,8 @@ StorageInterfaceImpl::createCollectionForBulkLoading(
AutoGetCollection coll(opCtx.get(), nss, MODE_IX);
if (coll.getCollection()) {
- return {ErrorCodes::NamespaceExists,
- str::stream() << "Collection " << nss.ns() << " already exists."};
+ return Status(ErrorCodes::NamespaceExists,
+ str::stream() << "Collection " << nss.ns() << " already exists.");
}
{
// Create the collection.
@@ -239,8 +239,13 @@ StorageInterfaceImpl::createCollectionForBulkLoading(
}
wunit.commit();
}
+
+ return Status::OK();
+ });
+
+ if (!status.isOK()) {
+ return status;
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx.get(), "beginCollectionClone", nss.ns());
// Move locks into loader, so it now controls their lifetime.
auto loader =
@@ -249,7 +254,7 @@ StorageInterfaceImpl::createCollectionForBulkLoading(
std::move(autoColl),
options.capped ? BSONObj() : idIndexSpec);
- auto status = loader->init(options.capped ? std::vector<BSONObj>() : secondaryIndexSpecs);
+ status = loader->init(options.capped ? std::vector<BSONObj>() : secondaryIndexSpecs);
if (!status.isOK()) {
return status;
}
@@ -328,14 +333,19 @@ Status StorageInterfaceImpl::insertDocuments(OperationContext* opCtx,
// Try to insert the batch one-at-a-time because the batch failed all-at-once inserting.
for (auto it = docs.cbegin(); it != docs.cend(); ++it) {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
- auto status = insertDocumentsSingleBatch(opCtx, nss, it, it + 1);
- if (!status.isOK()) {
- return status;
- }
+ auto status =
+ writeConflictRetry(opCtx, "StorageInterfaceImpl::insertDocuments", nss.ns(), [&] {
+ auto status = insertDocumentsSingleBatch(opCtx, nss, it, it + 1);
+ if (!status.isOK()) {
+ return status;
+ }
+
+ return Status::OK();
+ });
+
+ if (!status.isOK()) {
+ return status;
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(
- opCtx, "StorageInterfaceImpl::insertDocuments", nss.ns());
}
return Status::OK();
@@ -370,13 +380,13 @@ StatusWith<size_t> StorageInterfaceImpl::getOplogMaxSize(OperationContext* opCtx
Status StorageInterfaceImpl::createCollection(OperationContext* opCtx,
const NamespaceString& nss,
const CollectionOptions& options) {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ return writeConflictRetry(opCtx, "StorageInterfaceImpl::createCollection", nss.ns(), [&] {
AutoGetOrCreateDb databaseWriteGuard(opCtx, nss.db(), MODE_X);
auto db = databaseWriteGuard.getDb();
invariant(db);
if (db->getCollection(opCtx, nss)) {
- return {ErrorCodes::NamespaceExists,
- str::stream() << "Collection " << nss.ns() << " already exists."};
+ return Status(ErrorCodes::NamespaceExists,
+ str::stream() << "Collection " << nss.ns() << " already exists.");
}
WriteUnitOfWork wuow(opCtx);
try {
@@ -386,13 +396,13 @@ Status StorageInterfaceImpl::createCollection(OperationContext* opCtx,
return ex.toStatus();
}
wuow.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "StorageInterfaceImpl::createCollection", nss.ns());
- return Status::OK();
+
+ return Status::OK();
+ });
}
Status StorageInterfaceImpl::dropCollection(OperationContext* opCtx, const NamespaceString& nss) {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ return writeConflictRetry(opCtx, "StorageInterfaceImpl::dropCollection", nss.ns(), [&] {
AutoGetDb autoDB(opCtx, nss.db(), MODE_X);
if (!autoDB.getDb()) {
// Database does not exist - nothing to do.
@@ -404,8 +414,7 @@ Status StorageInterfaceImpl::dropCollection(OperationContext* opCtx, const Names
wunit.commit();
}
return status;
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "StorageInterfaceImpl::dropCollection", nss.ns());
+ });
}
Status StorageInterfaceImpl::renameCollection(OperationContext* opCtx,
@@ -420,7 +429,7 @@ Status StorageInterfaceImpl::renameCollection(OperationContext* opCtx,
<< toNS.ns());
}
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ return writeConflictRetry(opCtx, "StorageInterfaceImpl::renameCollection", fromNS.ns(), [&] {
AutoGetDb autoDB(opCtx, fromNS.db(), MODE_X);
if (!autoDB.getDb()) {
return Status(ErrorCodes::NamespaceNotFound,
@@ -443,9 +452,7 @@ Status StorageInterfaceImpl::renameCollection(OperationContext* opCtx,
}
wunit.commit();
return status;
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(
- opCtx, "StorageInterfaceImpl::renameCollection", fromNS.ns());
+ });
}
namespace {
@@ -478,13 +485,18 @@ StatusWith<std::vector<BSONObj>> _findOrDeleteDocuments(
auto isFind = mode == FindDeleteMode::kFind;
auto opStr = isFind ? "StorageInterfaceImpl::find" : "StorageInterfaceImpl::delete";
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+
+ return writeConflictRetry(opCtx, opStr, nss.ns(), [&] {
+ // We need to explicitly use this in a few places to help the type inference. Use a
+ // shorthand.
+ using Result = StatusWith<std::vector<BSONObj>>;
+
auto collectionAccessMode = isFind ? MODE_IS : MODE_IX;
AutoGetCollection autoColl(opCtx, nss, collectionAccessMode);
auto collectionResult = getCollection(
autoColl, nss, str::stream() << "Unable to proceed with " << opStr << ".");
if (!collectionResult.isOK()) {
- return collectionResult.getStatus();
+ return Result(collectionResult.getStatus());
}
auto collection = collectionResult.getValue();
@@ -494,13 +506,13 @@ StatusWith<std::vector<BSONObj>> _findOrDeleteDocuments(
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> planExecutor;
if (!indexName) {
if (!startKey.isEmpty()) {
- return {ErrorCodes::NoSuchKey,
- "non-empty startKey not allowed for collection scan"};
+ return Result(ErrorCodes::NoSuchKey,
+ "non-empty startKey not allowed for collection scan");
}
if (boundInclusion != BoundInclusion::kIncludeStartKeyOnly) {
- return {ErrorCodes::InvalidOptions,
- "bound inclusion must be BoundInclusion::kIncludeStartKeyOnly for "
- "collection scan"};
+ return Result(ErrorCodes::InvalidOptions,
+ "bound inclusion must be BoundInclusion::kIncludeStartKeyOnly for "
+ "collection scan");
}
// Use collection scan.
planExecutor = isFind
@@ -520,16 +532,17 @@ StatusWith<std::vector<BSONObj>> _findOrDeleteDocuments(
IndexDescriptor* indexDescriptor =
indexCatalog->findIndexByName(opCtx, *indexName, includeUnfinishedIndexes);
if (!indexDescriptor) {
- return {ErrorCodes::IndexNotFound,
- str::stream() << "Index not found, ns:" << nss.ns() << ", index: "
- << *indexName};
+ return Result(ErrorCodes::IndexNotFound,
+ str::stream() << "Index not found, ns:" << nss.ns() << ", index: "
+ << *indexName);
}
if (indexDescriptor->isPartial()) {
- return {ErrorCodes::IndexOptionsConflict,
- str::stream() << "Partial index is not allowed for this operation, ns:"
- << nss.ns()
- << ", index: "
- << *indexName};
+ return Result(ErrorCodes::IndexOptionsConflict,
+ str::stream()
+ << "Partial index is not allowed for this operation, ns:"
+ << nss.ns()
+ << ", index: "
+ << *indexName);
}
KeyPattern keyPattern(indexDescriptor->keyPattern());
@@ -575,10 +588,8 @@ StatusWith<std::vector<BSONObj>> _findOrDeleteDocuments(
break;
}
}
- return docs;
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, opStr, nss.ns());
- MONGO_UNREACHABLE;
+ return Result(docs);
+ });
}
StatusWith<BSONObj> _findOrDeleteById(OperationContext* opCtx,
@@ -714,7 +725,7 @@ Status _upsertWithQuery(OperationContext* opCtx,
invariant(!request.shouldReturnAnyDocs());
invariant(PlanExecutor::NO_YIELD == request.getYieldPolicy());
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ return writeConflictRetry(opCtx, "_upsertWithQuery", nss.ns(), [&] {
// ParsedUpdate needs to be inside the write conflict retry loop because it may create a
// CanonicalQuery whose ownership will be transferred to the plan executor in
// getExecutorUpdate().
@@ -743,10 +754,7 @@ Status _upsertWithQuery(OperationContext* opCtx,
auto planExecutor = std::move(planExecutorResult.getValue());
return planExecutor->executePlan();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "_upsertWithQuery", nss.ns());
-
- MONGO_UNREACHABLE;
+ });
}
} // namespace
@@ -771,7 +779,7 @@ Status StorageInterfaceImpl::upsertById(OperationContext* opCtx,
invariant(!request.shouldReturnAnyDocs());
invariant(PlanExecutor::NO_YIELD == request.getYieldPolicy());
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ return writeConflictRetry(opCtx, "StorageInterfaceImpl::upsertById", nss.ns(), [&] {
// ParsedUpdate needs to be inside the write conflict retry loop because it contains
// the UpdateDriver whose state may be modified while we are applying the update.
ParsedUpdate parsedUpdate(opCtx, &request);
@@ -791,8 +799,8 @@ Status StorageInterfaceImpl::upsertById(OperationContext* opCtx,
// without an _id index.
auto descriptor = collection->getIndexCatalog()->findIdIndex(opCtx);
if (!descriptor) {
- return {ErrorCodes::IndexNotFound,
- "Unable to update document in a collection without an _id index."};
+ return Status(ErrorCodes::IndexNotFound,
+ "Unable to update document in a collection without an _id index.");
}
UpdateStageParams updateStageParams(
@@ -805,10 +813,7 @@ Status StorageInterfaceImpl::upsertById(OperationContext* opCtx,
parsedUpdate.yieldPolicy());
return planExecutor->executePlan();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "StorageInterfaceImpl::upsertById", nss.ns());
-
- MONGO_UNREACHABLE;
+ });
}
Status StorageInterfaceImpl::putSingleton(OperationContext* opCtx,
@@ -829,7 +834,7 @@ Status StorageInterfaceImpl::deleteByFilter(OperationContext* opCtx,
// disallow client deletes from unrecognized system collections.
request.setGod();
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ return writeConflictRetry(opCtx, "StorageInterfaceImpl::deleteByFilter", nss.ns(), [&] {
// ParsedDelete needs to be inside the write conflict retry loop because it may create a
// CanonicalQuery whose ownership will be transferred to the plan executor in
// getExecutorDelete().
@@ -858,10 +863,7 @@ Status StorageInterfaceImpl::deleteByFilter(OperationContext* opCtx,
auto planExecutor = std::move(planExecutorResult.getValue());
return planExecutor->executePlan();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "StorageInterfaceImpl::deleteByFilter", nss.ns());
-
- MONGO_UNREACHABLE;
+ });
}
StatusWith<StorageInterface::CollectionSize> StorageInterfaceImpl::getCollectionSize(
diff --git a/src/mongo/db/repl/storage_interface_impl_test.cpp b/src/mongo/db/repl/storage_interface_impl_test.cpp
index 8affb72dccd..9f98851679a 100644
--- a/src/mongo/db/repl/storage_interface_impl_test.cpp
+++ b/src/mongo/db/repl/storage_interface_impl_test.cpp
@@ -101,7 +101,7 @@ CollectionOptions createOplogCollectionOptions() {
void createCollection(OperationContext* opCtx,
const NamespaceString& nss,
const CollectionOptions& options = CollectionOptions()) {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "createCollection", nss.ns(), [&] {
Lock::DBLock dblk(opCtx, nss.db(), MODE_X);
OldClientContext ctx(opCtx, nss.ns());
auto db = ctx.db();
@@ -110,8 +110,7 @@ void createCollection(OperationContext* opCtx,
auto coll = db->createCollection(opCtx, nss.ns(), options);
ASSERT_TRUE(coll);
wuow.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "createCollection", nss.ns());
+ });
}
/**
diff --git a/src/mongo/db/repl/sync_tail.cpp b/src/mongo/db/repl/sync_tail.cpp
index f22201d213c..ed39314544d 100644
--- a/src/mongo/db/repl/sync_tail.cpp
+++ b/src/mongo/db/repl/sync_tail.cpp
@@ -313,16 +313,15 @@ Status SyncTail::syncApply(OperationContext* opCtx,
auto opStr = isNoOp ? "syncApply_noop" : "syncApply_indexBuild";
if (isNoOp && nss.db() == "")
return Status::OK();
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ return writeConflictRetry(opCtx, opStr, nss.ns(), [&] {
Lock::DBLock dbLock(opCtx, nss.db(), MODE_X);
OldClientContext ctx(opCtx, nss.ns());
return applyOp(ctx.db());
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, opStr, nss.ns());
+ });
}
if (isCrudOpType(opType)) {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ return writeConflictRetry(opCtx, "syncApply_CRUD", nss.ns(), [&] {
// DB lock always acquires the global lock
std::unique_ptr<Lock::DBLock> dbLock;
std::unique_ptr<Lock::CollectionLock> collectionLock;
@@ -357,12 +356,11 @@ Status SyncTail::syncApply(OperationContext* opCtx,
}
return applyOp(ctx->db());
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "syncApply_CRUD", nss.ns());
+ });
}
if (opType[0] == 'c') {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ return writeConflictRetry(opCtx, "syncApply_command", nss.ns(), [&] {
// a command may need a global write lock. so we will conservatively go
// ahead and grab one here. suboptimal. :-(
Lock::GlobalWrite globalWriteLock(opCtx);
@@ -371,8 +369,7 @@ Status SyncTail::syncApply(OperationContext* opCtx,
Status status = applyCommandInLock(opCtx, op, inSteadyStateReplication);
incrementOpsAppliedStats();
return status;
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "syncApply_command", nss.ns());
+ });
}
// unknown opType
@@ -989,7 +986,7 @@ BSONObj SyncTail::getMissingDoc(OperationContext* opCtx, Database* db, const BSO
bool SyncTail::shouldRetry(OperationContext* opCtx, const BSONObj& o) {
const NamespaceString nss(o.getStringField("ns"));
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ return writeConflictRetry(opCtx, "InsertRetry", nss.ns(), [&] {
// Take an X lock on the database in order to preclude other modifications.
// Also, the database might not exist yet, so create it.
AutoGetOrCreateDb autoDb(opCtx, nss.db(), MODE_X);
@@ -1024,11 +1021,7 @@ bool SyncTail::shouldRetry(OperationContext* opCtx, const BSONObj& o) {
wunit.commit();
return true;
}
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "InsertRetry", nss.ns());
-
- // fixes compile errors on GCC - see SERVER-18219 for details
- MONGO_UNREACHABLE;
+ });
}
// This free function is used by the writer threads to apply each op
diff --git a/src/mongo/db/repl/sync_tail_test.cpp b/src/mongo/db/repl/sync_tail_test.cpp
index 705497240c4..6d056e27183 100644
--- a/src/mongo/db/repl/sync_tail_test.cpp
+++ b/src/mongo/db/repl/sync_tail_test.cpp
@@ -291,7 +291,7 @@ CollectionOptions createOplogCollectionOptions() {
void createCollection(OperationContext* opCtx,
const NamespaceString& nss,
const CollectionOptions& options) {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "createCollection", nss.ns(), [&] {
Lock::DBLock dblk(opCtx, nss.db(), MODE_X);
OldClientContext ctx(opCtx, nss.ns());
auto db = ctx.db();
@@ -300,8 +300,7 @@ void createCollection(OperationContext* opCtx,
auto coll = db->createCollection(opCtx, nss.ns(), options);
ASSERT_TRUE(coll);
wuow.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "createCollection", nss.ns());
+ });
}
/**
diff --git a/src/mongo/db/s/collection_range_deleter.cpp b/src/mongo/db/s/collection_range_deleter.cpp
index e3fc81f9940..5635a888b1d 100644
--- a/src/mongo/db/s/collection_range_deleter.cpp
+++ b/src/mongo/db/s/collection_range_deleter.cpp
@@ -302,16 +302,14 @@ StatusWith<int> CollectionRangeDeleter::_doDeletion(OperationContext* opCtx,
}
invariant(PlanExecutor::ADVANCED == state);
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "delete range", nss.ns(), [&] {
WriteUnitOfWork wuow(opCtx);
if (saver) {
saver->goingToDelete(obj).transitional_ignore();
}
collection->deleteDocument(opCtx, rloc, nullptr, true);
wuow.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "delete range", nss.ns());
-
+ });
} while (++numDeleted < maxToDelete);
return numDeleted;
diff --git a/src/mongo/db/service_context_d_test_fixture.cpp b/src/mongo/db/service_context_d_test_fixture.cpp
index dd18629eb05..eb35a212569 100644
--- a/src/mongo/db/service_context_d_test_fixture.cpp
+++ b/src/mongo/db/service_context_d_test_fixture.cpp
@@ -91,11 +91,10 @@ void ServiceContextMongoDTest::_dropAllDBs(OperationContext* opCtx) {
AutoGetDb autoDBLocal(opCtx, "local", MODE_X);
const auto localDB = autoDBLocal.getDb();
if (localDB) {
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "_dropAllDBs", "local", [&] {
// Do not wrap in a WriteUnitOfWork until SERVER-17103 is addressed.
autoDBLocal.getDb()->dropDatabase(opCtx, localDB);
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "_dropAllDBs", "local");
+ });
}
// dropAllDatabasesExceptLocal() does not close empty databases. However the holder still
diff --git a/src/mongo/db/system_index.cpp b/src/mongo/db/system_index.cpp
index a46b1bf45eb..0c07a4e46ad 100644
--- a/src/mongo/db/system_index.cpp
+++ b/src/mongo/db/system_index.cpp
@@ -118,21 +118,19 @@ void generateSystemIndexForExistingCollection(OperationContext* opCtx,
MultiIndexBlock indexer(opCtx, collection);
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "authorization index regeneration", ns.ns(), [&] {
fassertStatusOK(40453, indexer.init(indexSpec));
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "authorization index regeneration", ns.ns());
+ });
fassertStatusOK(40454, indexer.insertAllDocumentsInCollection());
- MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
+ writeConflictRetry(opCtx, "authorization index regeneration", ns.ns(), [&] {
WriteUnitOfWork wunit(opCtx);
indexer.commit();
wunit.commit();
- }
- MONGO_WRITE_CONFLICT_RETRY_LOOP_END(opCtx, "authorization index regeneration", ns.ns());
+ });
log() << "Authorization index construction on " << ns << " is complete";
} catch (const DBException& e) {