summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/replsets/oplog_wallclock.js29
-rw-r--r--src/mongo/db/repl/oplog.cpp25
-rw-r--r--src/mongo/db/repl/oplog_entry.idl4
3 files changed, 53 insertions, 5 deletions
diff --git a/jstests/replsets/oplog_wallclock.js b/jstests/replsets/oplog_wallclock.js
new file mode 100644
index 00000000000..899586b6561
--- /dev/null
+++ b/jstests/replsets/oplog_wallclock.js
@@ -0,0 +1,29 @@
+// oplog should contain the field "wt" with wallClock timestamps.
+(function() {
+ 'use strict';
+ load('jstests/replsets/rslib.js');
+
+ var assertLastOplogHasWT = function(primary, msg) {
+ const opLogEntry = getLatestOp(primary);
+ assert(opLogEntry.hasOwnProperty('wt'),
+ 'oplog entry must contain wt field: ' + tojson(opLogEntry));
+ };
+
+ var name = 'wt_test_coll';
+ var replSet = new ReplSetTest({nodes: 1, oplogSize: 2, nodeOptions: {smallfiles: ''}});
+ replSet.startSet();
+ replSet.initiate();
+
+ var primary = replSet.getPrimary();
+ var collection = primary.getDB('test').getCollection(name);
+
+ assert.writeOK(collection.insert({_id: 1, val: 'x'}));
+ assertLastOplogHasWT(primary, 'insert');
+
+ assert.writeOK(collection.update({_id: 1}, {val: 'y'}));
+ assertLastOplogHasWT(primary, 'update');
+
+ assert.writeOK(collection.remove({_id: 1}));
+ assertLastOplogHasWT(primary, 'remove');
+
+})();
diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp
index 1f0b37d2008..bf69d4e02bd 100644
--- a/src/mongo/db/repl/oplog.cpp
+++ b/src/mongo/db/repl/oplog.cpp
@@ -257,7 +257,8 @@ OplogDocWriter _logOpWriter(OperationContext* opCtx,
const BSONObj* o2,
bool fromMigrate,
OpTime optime,
- long long hashNew) {
+ long long hashNew,
+ Date_t wallTime) {
BSONObjBuilder b(256);
b.append("ts", optime.getTimestamp());
@@ -274,6 +275,10 @@ OplogDocWriter _logOpWriter(OperationContext* opCtx,
if (o2)
b.append("o2", *o2);
+ if (wallTime != Date_t{}) {
+ b.appendDate("wt", wallTime);
+ }
+
return OplogDocWriter(OplogDocWriter(b.obj(), obj));
}
} // end anon namespace
@@ -388,8 +393,9 @@ OpTime logOp(OperationContext* opCtx,
auto replMode = replCoord->getReplicationMode();
OplogSlot slot;
getNextOpTime(opCtx, oplog, replCoord, replMode, 1, &slot);
- auto writer =
- _logOpWriter(opCtx, opstr, nss, uuid, obj, o2, fromMigrate, slot.opTime, slot.hash);
+
+ auto writer = _logOpWriter(
+ opCtx, opstr, nss, uuid, obj, o2, fromMigrate, slot.opTime, slot.hash, Date_t::now());
const DocWriter* basePtr = &writer;
_logOpsInner(opCtx, nss, &basePtr, 1, oplog, replMode, slot.opTime);
return slot.opTime;
@@ -418,9 +424,18 @@ void logOps(OperationContext* opCtx,
std::unique_ptr<OplogSlot[]> slots(new OplogSlot[count]);
auto replMode = replCoord->getReplicationMode();
getNextOpTime(opCtx, oplog, replCoord, replMode, count, slots.get());
+ auto wallTime = Date_t::now();
for (size_t i = 0; i < count; i++) {
- writers.emplace_back(_logOpWriter(
- opCtx, opstr, nss, uuid, begin[i], NULL, fromMigrate, slots[i].opTime, slots[i].hash));
+ writers.emplace_back(_logOpWriter(opCtx,
+ opstr,
+ nss,
+ uuid,
+ begin[i],
+ NULL,
+ fromMigrate,
+ slots[i].opTime,
+ slots[i].hash,
+ wallTime));
}
std::unique_ptr<DocWriter const* []> basePtrs(new DocWriter const*[count]);
diff --git a/src/mongo/db/repl/oplog_entry.idl b/src/mongo/db/repl/oplog_entry.idl
index 9611613d1d8..5d2cdfbd429 100644
--- a/src/mongo/db/repl/oplog_entry.idl
+++ b/src/mongo/db/repl/oplog_entry.idl
@@ -95,3 +95,7 @@ structs:
type: objectid
optional: true
description: "An optional _id field for tests that manually insert oplog entries"
+ wt:
+ type: date
+ optional: true # Optional for older than 3.6 releases
+ description: "A wallclock time with MS resolution"