summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2017-07-31 16:39:17 -0400
committerBenety Goh <benety@mongodb.com>2017-08-08 14:37:48 -0400
commita62fae74434fcdd90b94eb526dec7d43f116b16c (patch)
treeaee0d8df76eedb9e1e990e7ef0168c5cc7c0d0a0
parent28029005b4cc277ecf902989e249c49354e21447 (diff)
downloadmongo-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.js10
-rw-r--r--src/mongo/db/catalog/apply_ops.cpp11
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