diff options
author | Benety Goh <benety@mongodb.com> | 2017-07-31 16:39:17 -0400 |
---|---|---|
committer | Benety Goh <benety@mongodb.com> | 2017-08-08 14:37:48 -0400 |
commit | a62fae74434fcdd90b94eb526dec7d43f116b16c (patch) | |
tree | aee0d8df76eedb9e1e990e7ef0168c5cc7c0d0a0 | |
parent | 28029005b4cc277ecf902989e249c49354e21447 (diff) | |
download | mongo-a62fae74434fcdd90b94eb526dec7d43f116b16c.tar.gz |
SERVER-29802 add applyOps 'allowAtomic' flag.
This flag supports non-atomic application of CRUD operations if set to false.
Defaults to true.
(cherry picked from commit e7de30308564cead80857592ed27d938f73a91f1)
-rw-r--r-- | jstests/replsets/libs/apply_ops_insert_write_conflict.js | 10 | ||||
-rw-r--r-- | src/mongo/db/catalog/apply_ops.cpp | 11 |
2 files changed, 10 insertions, 11 deletions
diff --git a/jstests/replsets/libs/apply_ops_insert_write_conflict.js b/jstests/replsets/libs/apply_ops_insert_write_conflict.js index 88b299c08b6..d0a47f5b6d8 100644 --- a/jstests/replsets/libs/apply_ops_insert_write_conflict.js +++ b/jstests/replsets/libs/apply_ops_insert_write_conflict.js @@ -36,14 +36,6 @@ var ApplyOpsInsertWriteConflictTest = function(options) { return {op: 'i', ns: t.getFullName(), o: {_id: i}}; }); - if (!options.atomic) { - // Adding a command to the list of operations to prevent the applyOps command from - // applying - // all the operations atomically. - ops.push({ns: "test.$cmd", op: "c", o: {applyOps: []}}); - numOps++; - } - // Probabilities for WCE are chosen based on empirical testing. // The probability for WCE during an atomic applyOps should be much smaller than that for // the non-atomic case because we have to attempt to re-apply the entire batch of 'numOps' @@ -62,7 +54,7 @@ var ApplyOpsInsertWriteConflictTest = function(options) { var previousLogLevel = assert.commandWorked(primaryDB.setLogLevel(3, 'replication')).was.replication.verbosity; - var applyOpsResult = primaryDB.adminCommand({applyOps: ops}); + var applyOpsResult = primaryDB.adminCommand({applyOps: ops, allowAtomic: options.atomic}); // Reset log level. primaryDB.setLogLevel(previousLogLevel, 'replication'); diff --git a/src/mongo/db/catalog/apply_ops.cpp b/src/mongo/db/catalog/apply_ops.cpp index 154df461dd4..9118c2b6d18 100644 --- a/src/mongo/db/catalog/apply_ops.cpp +++ b/src/mongo/db/catalog/apply_ops.cpp @@ -32,6 +32,7 @@ #include "mongo/db/catalog/apply_ops.h" +#include "mongo/bson/util/bson_extract.h" #include "mongo/db/catalog/collection.h" #include "mongo/db/catalog/database.h" #include "mongo/db/catalog/database_holder.h" @@ -56,7 +57,7 @@ namespace { /** * Return true iff the applyOpsCmd can be executed in a single WriteUnitOfWork. */ -bool canBeAtomic(const BSONObj& applyOpCmd) { +bool _areOpsCrudOnly(const BSONObj& applyOpCmd) { for (const auto& elem : applyOpCmd.firstElement().Obj()) { const char* names[] = {"ns", "op"}; BSONElement fields[2]; @@ -309,6 +310,12 @@ Status applyOps(OperationContext* opCtx, const std::string& dbName, const BSONObj& applyOpCmd, BSONObjBuilder* result) { + bool allowAtomic = false; + uassertStatusOK( + bsonExtractBooleanFieldWithDefault(applyOpCmd, "allowAtomic", true, &allowAtomic)); + auto areOpsCrudOnly = _areOpsCrudOnly(applyOpCmd); + auto isAtomic = allowAtomic && areOpsCrudOnly; + ScopedTransaction scopedXact(opCtx, MODE_X); Lock::GlobalWrite globalWriteLock(opCtx->lockState()); @@ -325,7 +332,7 @@ Status applyOps(OperationContext* opCtx, } int numApplied = 0; - if (!canBeAtomic(applyOpCmd)) + if (!isAtomic) return _applyOps(opCtx, dbName, applyOpCmd, result, &numApplied); // Perform write ops atomically |