summaryrefslogtreecommitdiff
path: root/jstests/replsets/oplog_format.js
diff options
context:
space:
mode:
authorJustin Seyster <justin.seyster@mongodb.com>2017-09-14 12:14:54 -0400
committerJustin Seyster <justin.seyster@mongodb.com>2017-09-14 12:14:54 -0400
commit390e5f47f00dcf133f361e3f9027e4da7d08d628 (patch)
tree901690cdc5bc1b681e1e2b95c30061784a15187e /jstests/replsets/oplog_format.js
parent5767ee2421fa6c7934a90e9083f07743a83dcf71 (diff)
downloadmongo-390e5f47f00dcf133f361e3f9027e4da7d08d628.tar.gz
SERVER-30705 Add $v field for update semantics in oplog updates.
With the new UpdateNodes class hierarchy, there are two code paths for applying an update to a document that have slightly different semantics. The order of fields in the resulting document can vary depending on which code path is used to apply an update. A difference in ordering between documents in a replica set is considered a "mismatch," so we need to ensure that secondaries always apply updates using the same update system that the primary uses. When an update executes as part of the application of an oplog entry, the update is now allowed to have a $v field, which allows it to specify which semantics were used by the operation that we are replicating by applying the entry. When the primary uses the new semantics (because it is a 3.6 mongod with featureCompatibilityVersion set to 3.6), it includes {$v: 1} in the oplog's update document to indicate that the secondary should apply with the newer 'UpdateNode' semantics. There are two other places where we need this behavior: 1) In role_graph_update.cpp, where the handleOplogUpdate observer needs to update its in-memory BSON representation of a role to reflect an update in the admin database and 2) in the applyOps command, which is used for testing how oplog entries get applied. Both these code paths set the fromOplogApplication flag, which replaces the old fromReplication flag, and they also gain behavior that used to be exclusive to oplog applications from replication. (Specifically, they skip update validation checks, which should have already passed before the oplog entry was created.)
Diffstat (limited to 'jstests/replsets/oplog_format.js')
-rw-r--r--jstests/replsets/oplog_format.js34
1 files changed, 17 insertions, 17 deletions
diff --git a/jstests/replsets/oplog_format.js b/jstests/replsets/oplog_format.js
index 5604ae1278b..2fd87e2d665 100644
--- a/jstests/replsets/oplog_format.js
+++ b/jstests/replsets/oplog_format.js
@@ -37,7 +37,7 @@ assertLastOplog({_id: 1, a: 2}, {_id: 1}, "save " + msg);
var res = assert.writeOK(coll.update({}, {$inc: {a: 1}, $set: {b: 2}}));
assert.eq(res.nModified, 1, "update failed for '" + msg + "': " + res.toString());
assert.docEq({_id: 1, a: 3, b: 2}, coll.findOne({}), msg);
-assertLastOplog({$set: {a: 3, b: 2}}, {_id: 1}, msg);
+assertLastOplog({$v: 1, $set: {a: 3, b: 2}}, {_id: 1}, msg);
var msg = "IncRewriteNonExistingField: $inc $set";
coll.save({_id: 1, c: 0});
@@ -45,7 +45,7 @@ assertLastOplog({_id: 1, c: 0}, {_id: 1}, "save " + msg);
res = assert.writeOK(coll.update({}, {$inc: {a: 1}, $set: {b: 2}}));
assert.eq(res.nModified, 1, "update failed for '" + msg + "': " + res.toString());
assert.docEq({_id: 1, c: 0, a: 1, b: 2}, coll.findOne({}), msg);
-assertLastOplog({$set: {a: 1, b: 2}}, {_id: 1}, msg);
+assertLastOplog({$v: 1, $set: {a: 1, b: 2}}, {_id: 1}, msg);
var msg = "TwoNestedPulls: two $pull";
coll.save({_id: 1, a: {b: [1, 2], c: [1, 2]}});
@@ -53,7 +53,7 @@ assertLastOplog({_id: 1, a: {b: [1, 2], c: [1, 2]}}, {_id: 1}, "save " + msg);
res = assert.writeOK(coll.update({}, {$pull: {'a.b': 2, 'a.c': 2}}));
assert.eq(res.nModified, 1, "update failed for '" + msg + "': " + res.toString());
assert.docEq({_id: 1, a: {b: [1], c: [1]}}, coll.findOne({}), msg);
-assertLastOplog({$set: {'a.b': [1], 'a.c': [1]}}, {_id: 1}, msg);
+assertLastOplog({$v: 1, $set: {'a.b': [1], 'a.c': [1]}}, {_id: 1}, msg);
var msg = "MultiSets: two $set";
coll.save({_id: 1, a: 1, b: 1});
@@ -61,7 +61,7 @@ assertLastOplog({_id: 1, a: 1, b: 1}, {_id: 1}, "save " + msg);
res = assert.writeOK(coll.update({}, {$set: {a: 2, b: 2}}));
assert.eq(res.nModified, 1, "update failed for '" + msg + "': " + res.toString());
assert.docEq({_id: 1, a: 2, b: 2}, coll.findOne({}), msg);
-assertLastOplog({$set: {a: 2, b: 2}}, {_id: 1}, msg);
+assertLastOplog({$v: 1, $set: {a: 2, b: 2}}, {_id: 1}, msg);
// More tests to validate the oplog format and correct excution
@@ -71,19 +71,19 @@ assertLastOplog({_id: 1, a: 1}, {_id: 1}, "save " + msg);
res = assert.writeOK(coll.update({}, {$set: {a: 2}}));
assert.eq(res.nModified, 1, "update failed for '" + msg + "': " + res.toString());
assert.docEq({_id: 1, a: 2}, coll.findOne({}), msg);
-assertLastOplog({$set: {a: 2}}, {_id: 1}, msg);
+assertLastOplog({$v: 1, $set: {a: 2}}, {_id: 1}, msg);
var msg = "bad single $inc";
res = assert.writeOK(coll.update({}, {$inc: {a: 1}}));
assert.eq(res.nModified, 1, "update failed for '" + msg + "': " + res.toString());
assert.docEq({_id: 1, a: 3}, coll.findOne({}), msg);
-assertLastOplog({$set: {a: 3}}, {_id: 1}, msg);
+assertLastOplog({$v: 1, $set: {a: 3}}, {_id: 1}, msg);
var msg = "bad double $set";
res = assert.writeOK(coll.update({}, {$set: {a: 2, b: 2}}));
assert.eq(res.nModified, 1, "update failed for '" + msg + "': " + res.toString());
assert.docEq({_id: 1, a: 2, b: 2}, coll.findOne({}), msg);
-assertLastOplog({$set: {a: 2, b: 2}}, {_id: 1}, msg);
+assertLastOplog({$v: 1, $set: {a: 2, b: 2}}, {_id: 1}, msg);
var msg = "bad save";
assert.writeOK(coll.save({_id: 1, a: [2]}));
@@ -94,14 +94,14 @@ var msg = "bad array $inc";
res = assert.writeOK(coll.update({}, {$inc: {"a.0": 1}}));
assert.eq(res.nModified, 1, "update failed for '" + msg + "': " + res.toString());
assert.docEq({_id: 1, a: [3]}, coll.findOne({}), msg);
-var lastTS = assertLastOplog({$set: {"a.0": 3}}, {_id: 1}, msg);
+var lastTS = assertLastOplog({$v: 1, $set: {"a.0": 3}}, {_id: 1}, msg);
var msg = "bad $setOnInsert";
res = assert.writeOK(coll.update({}, {$setOnInsert: {a: -1}}));
assert.eq(res.nMatched, 1, "update failed for '" + msg + "': " + res.toString());
-assert.docEq({_id: 1, a: [3]}, coll.findOne({}), msg); // No-op
-var otherTS = assertLastOplog({$set: {"a.0": 3}}, {_id: 1}, msg); // Nothing new
-assert.eq(lastTS, otherTS, "new oplog was not expected -- " + msg); // No new oplog entry
+assert.docEq({_id: 1, a: [3]}, coll.findOne({}), msg); // No-op
+var otherTS = assertLastOplog({$v: 1, $set: {"a.0": 3}}, {_id: 1}, msg); // Nothing new
+assert.eq(lastTS, otherTS, "new oplog was not expected -- " + msg); // No new oplog entry
coll.remove({});
assert.eq(coll.find().itcount(), 0, "collection not empty");
@@ -134,14 +134,14 @@ coll.save({_id: 1, a: "foo"});
res = assert.writeOK(coll.update({}, {$push: {c: 18}}));
assert.eq(res.nModified, 1, "update failed for '" + msg + "': " + res.toString());
assert.docEq({_id: 1, a: "foo", c: [18]}, coll.findOne({}), msg);
-assertLastOplog({$set: {"c": [18]}}, {_id: 1}, msg);
+assertLastOplog({$v: 1, $set: {"c": [18]}}, {_id: 1}, msg);
var msg = "bad array $push $slice";
coll.save({_id: 1, a: {b: [18]}});
res = assert.writeOK(coll.update({_id: {$gt: 0}}, {$push: {"a.b": {$each: [1, 2], $slice: -2}}}));
assert.eq(res.nModified, 1, "update failed for '" + msg + "': " + res.toString());
assert.docEq({_id: 1, a: {b: [1, 2]}}, coll.findOne({}), msg);
-assertLastOplog({$set: {"a.b": [1, 2]}}, {_id: 1}, msg);
+assertLastOplog({$v: 1, $set: {"a.b": [1, 2]}}, {_id: 1}, msg);
var msg = "bad array $push $sort ($slice -100)";
coll.save({_id: 1, a: {b: [{c: 2}, {c: 1}]}});
@@ -149,7 +149,7 @@ res = assert.writeOK(
coll.update({}, {$push: {"a.b": {$each: [{c: -1}], $sort: {c: 1}, $slice: -100}}}));
assert.eq(res.nModified, 1, "update failed for '" + msg + "': " + res.toString());
assert.docEq({_id: 1, a: {b: [{c: -1}, {c: 1}, {c: 2}]}}, coll.findOne({}), msg);
-assertLastOplog({$set: {"a.b": [{c: -1}, {c: 1}, {c: 2}]}}, {_id: 1}, msg);
+assertLastOplog({$v: 1, $set: {"a.b": [{c: -1}, {c: 1}, {c: 2}]}}, {_id: 1}, msg);
var msg = "bad array $push $slice $sort";
coll.save({_id: 1, a: [{b: 2}, {b: 1}]});
@@ -157,7 +157,7 @@ res = assert.writeOK(
coll.update({_id: {$gt: 0}}, {$push: {a: {$each: [{b: -1}], $slice: -2, $sort: {b: 1}}}}));
assert.eq(res.nModified, 1, "update failed for '" + msg + "': " + res.toString());
assert.docEq({_id: 1, a: [{b: 1}, {b: 2}]}, coll.findOne({}), msg);
-assertLastOplog({$set: {a: [{b: 1}, {b: 2}]}}, {_id: 1}, msg);
+assertLastOplog({$v: 1, $set: {a: [{b: 1}, {b: 2}]}}, {_id: 1}, msg);
var msg = "bad array $push $slice $sort first two";
coll.save({_id: 1, a: {b: [{c: 2}, {c: 1}]}});
@@ -165,7 +165,7 @@ res = assert.writeOK(
coll.update({_id: {$gt: 0}}, {$push: {"a.b": {$each: [{c: -1}], $slice: -2, $sort: {c: 1}}}}));
assert.eq(res.nModified, 1, "update failed for '" + msg + "': " + res.toString());
assert.docEq({_id: 1, a: {b: [{c: 1}, {c: 2}]}}, coll.findOne({}), msg);
-assertLastOplog({$set: {"a.b": [{c: 1}, {c: 2}]}}, {_id: 1}, msg);
+assertLastOplog({$v: 1, $set: {"a.b": [{c: 1}, {c: 2}]}}, {_id: 1}, msg);
var msg = "bad array $push $slice $sort reversed first two";
coll.save({_id: 1, a: {b: [{c: 1}, {c: 2}]}});
@@ -173,6 +173,6 @@ res = assert.writeOK(
coll.update({_id: {$gt: 0}}, {$push: {"a.b": {$each: [{c: -1}], $slice: -2, $sort: {c: -1}}}}));
assert.eq(res.nModified, 1, "update failed for '" + msg + "': " + res.toString());
assert.docEq({_id: 1, a: {b: [{c: 1}, {c: -1}]}}, coll.findOne({}), msg);
-assertLastOplog({$set: {"a.b": [{c: 1}, {c: -1}]}}, {_id: 1}, msg);
+assertLastOplog({$v: 1, $set: {"a.b": [{c: 1}, {c: -1}]}}, {_id: 1}, msg);
replTest.stopSet();