diff options
34 files changed, 368 insertions, 360 deletions
diff --git a/src/mongo/db/op_observer_impl.cpp b/src/mongo/db/op_observer_impl.cpp index 9be2ec5c89b..4ba8d17eea1 100644 --- a/src/mongo/db/op_observer_impl.cpp +++ b/src/mongo/db/op_observer_impl.cpp @@ -186,7 +186,7 @@ OpTimeBundle replLogUpdate(OperationContext* opCtx, const OplogUpdateEntryArgs& // oplogLink could have been changed to include pre/postImageOpTime by the previous no-op write. repl::appendRetryableWriteInfo(opCtx, &oplogEntry, &oplogLink, args.updateArgs.stmtId); opTimes.writeOpTime = logOperation(opCtx, &oplogEntry); - opTimes.wallClockTime = oplogEntry.getWallClockTime().get(); + opTimes.wallClockTime = oplogEntry.getWallClockTime(); return opTimes; } @@ -223,7 +223,7 @@ OpTimeBundle replLogDelete(OperationContext* opCtx, // oplogLink could have been changed to include preImageOpTime by the previous no-op write. repl::appendRetryableWriteInfo(opCtx, &oplogEntry, &oplogLink, stmtId); opTimes.writeOpTime = logOperation(opCtx, &oplogEntry); - opTimes.wallClockTime = oplogEntry.getWallClockTime().get(); + opTimes.wallClockTime = oplogEntry.getWallClockTime(); return opTimes; } @@ -808,7 +808,7 @@ OpTimeBundle logApplyOpsForTransaction(OperationContext* opCtx, try { OpTimeBundle times; times.writeOpTime = logOperation(opCtx, oplogEntry); - times.wallClockTime = oplogEntry->getWallClockTime().get(); + times.wallClockTime = oplogEntry->getWallClockTime(); if (updateTxnTable) { SessionTxnRecord sessionTxnRecord; sessionTxnRecord.setLastWriteOpTime(times.writeOpTime); @@ -971,7 +971,7 @@ void logCommitOrAbortForPreparedTransaction(OperationContext* opCtx, SessionTxnRecord sessionTxnRecord; sessionTxnRecord.setLastWriteOpTime(oplogOpTime); - sessionTxnRecord.setLastWriteDate(oplogEntry->getWallClockTime().get()); + sessionTxnRecord.setLastWriteDate(oplogEntry->getWallClockTime()); sessionTxnRecord.setState(durableState); onWriteOpCompleted(opCtx, {}, sessionTxnRecord); wuow.commit(); diff --git a/src/mongo/db/ops/write_ops_retryability_test.cpp b/src/mongo/db/ops/write_ops_retryability_test.cpp index 550744fa95c..2956efeb7cf 100644 --- a/src/mongo/db/ops/write_ops_retryability_test.cpp +++ b/src/mongo/db/ops/write_ops_retryability_test.cpp @@ -70,7 +70,7 @@ repl::OplogEntry makeOplogEntry(repl::OpTime opTime, o2Field, // o2 {}, // sessionInfo boost::none, // upsert - boost::none, // wall clock time + Date_t(), // wall clock time boost::none, // statement id boost::none, // optime of previous write within same transaction preImageOpTime, // pre-image optime @@ -83,7 +83,8 @@ TEST_F(WriteOpsRetryability, ParseOplogEntryForUpdate) { << "u" << "ns" << "a.b" - << "o" << BSON("_id" << 1 << "x" << 5) << "o2" << BSON("_id" << 1)))); + << "wall" << Date_t() << "o" << BSON("_id" << 1 << "x" << 5) << "o2" + << BSON("_id" << 1)))); auto res = parseOplogEntryForUpdate(entry); @@ -112,12 +113,12 @@ TEST_F(WriteOpsRetryability, ParseOplogEntryForNestedUpdate) { } TEST_F(WriteOpsRetryability, ParseOplogEntryForUpsert) { - const auto entry = - assertGet(repl::OplogEntry::parse(BSON("ts" << Timestamp(50, 10) << "t" << 1LL << "op" - << "i" - << "ns" - << "a.b" - << "o" << BSON("_id" << 1 << "x" << 5)))); + const auto entry = assertGet(repl::OplogEntry::parse( + BSON("ts" << Timestamp(50, 10) << "t" << 1LL << "op" + << "i" + << "ns" + << "a.b" + << "wall" << Date_t() << "o" << BSON("_id" << 1 << "x" << 5)))); auto res = parseOplogEntryForUpdate(entry); diff --git a/src/mongo/db/pipeline/document_source_change_stream_test.cpp b/src/mongo/db/pipeline/document_source_change_stream_test.cpp index acc9d82e1f8..e9248465431 100644 --- a/src/mongo/db/pipeline/document_source_change_stream_test.cpp +++ b/src/mongo/db/pipeline/document_source_change_stream_test.cpp @@ -346,7 +346,7 @@ public: object2, // o2 sessionInfo, // sessionInfo boost::none, // upsert - boost::none, // wall clock time + Date_t(), // wall clock time boost::none, // statement id prevOpTime, // optime of previous write within same transaction boost::none, // pre-image optime @@ -1030,7 +1030,7 @@ TEST_F(ChangeStreamStageTest, CommitCommandReturnsOperationsFromPreparedTransact boost::none, // o2 sessionInfo, // sessionInfo boost::none, // upsert - boost::none, // wall clock time + Date_t(), // wall clock time boost::none, // statement id applyOpsOpTime, // optime of previous write within same transaction boost::none, // pre-image optime @@ -1227,7 +1227,7 @@ TEST_F(ChangeStreamStageTest, PreparedTransactionWithMultipleOplogEntries) { boost::none, // o2 sessionInfo, // sessionInfo boost::none, // upsert - boost::none, // wall clock time + Date_t(), // wall clock time boost::none, // statement id applyOpsOpTime2, // optime of previous write within same transaction boost::none, // pre-image optime diff --git a/src/mongo/db/repl/abstract_oplog_fetcher_test_fixture.cpp b/src/mongo/db/repl/abstract_oplog_fetcher_test_fixture.cpp index 882cf5f4fa8..9f748b283c5 100644 --- a/src/mongo/db/repl/abstract_oplog_fetcher_test_fixture.cpp +++ b/src/mongo/db/repl/abstract_oplog_fetcher_test_fixture.cpp @@ -58,7 +58,7 @@ repl::OplogEntry makeOplogEntry(repl::OpTime opTime, boost::none, // o2 {}, // sessionInfo boost::none, // upsert - boost::none, // wall clock time + Date_t(), // wall clock time boost::none, // statement id boost::none, // optime of previous write within same transaction boost::none, // pre-image optime diff --git a/src/mongo/db/repl/apply_ops.cpp b/src/mongo/db/repl/apply_ops.cpp index 49f8aab83ec..1e947868a65 100644 --- a/src/mongo/db/repl/apply_ops.cpp +++ b/src/mongo/db/repl/apply_ops.cpp @@ -162,9 +162,16 @@ Status _applyOps(OperationContext* opCtx, BSONObjBuilder builder; builder.appendElements(opObj); + + // If required fields are not present in the BSONObj for an applyOps entry, create these + // fields and populate them with dummy values before parsing the BSONObj as an oplog + // entry. if (!builder.hasField(OplogEntry::kTimestampFieldName)) { builder.append(OplogEntry::kTimestampFieldName, Timestamp()); } + if (!builder.hasField(OplogEntry::kWallClockTimeFieldName)) { + builder.append(OplogEntry::kWallClockTimeFieldName, Date_t()); + } // Reject malformed operations in an atomic applyOps. auto entry = OplogEntry::parse(builder.done()); if (!entry.isOK()) { @@ -212,6 +219,9 @@ Status _applyOps(OperationContext* opCtx, if (!builder.hasField(OplogEntry::kHashFieldName)) { builder.append(OplogEntry::kHashFieldName, 0LL); } + if (!builder.hasField(OplogEntry::kWallClockTimeFieldName)) { + builder.append(OplogEntry::kWallClockTimeFieldName, Date_t()); + } auto entry = uassertStatusOK(OplogEntry::parse(builder.done())); if (*opType == 'c') { invariant(opCtx->lockState()->isW()); diff --git a/src/mongo/db/repl/apply_ops_test.cpp b/src/mongo/db/repl/apply_ops_test.cpp index eaa21394384..b5ddfadcd0f 100644 --- a/src/mongo/db/repl/apply_ops_test.cpp +++ b/src/mongo/db/repl/apply_ops_test.cpp @@ -346,7 +346,7 @@ OplogEntry makeOplogEntry(OpTypeEnum opType, const BSONObj& oField) { boost::none, // o2 {}, // sessionInfo boost::none, // upsert - boost::none, // wall clock time + Date_t(), // wall clock time boost::none, // statement id boost::none, // optime of previous write within same transaction boost::none, // pre-image optime diff --git a/src/mongo/db/repl/idempotency_test_fixture.cpp b/src/mongo/db/repl/idempotency_test_fixture.cpp index c7f77c967d5..6e609c9b6ae 100644 --- a/src/mongo/db/repl/idempotency_test_fixture.cpp +++ b/src/mongo/db/repl/idempotency_test_fixture.cpp @@ -74,7 +74,7 @@ repl::OplogEntry makeOplogEntry(repl::OpTime opTime, BSONObj object, boost::optional<BSONObj> object2 = boost::none, OperationSessionInfo sessionInfo = {}, - boost::optional<Date_t> wallClockTime = boost::none, + Date_t wallClockTime = Date_t(), boost::optional<StmtId> stmtId = boost::none, boost::optional<UUID> uuid = boost::none, boost::optional<OpTime> prevOpTime = boost::none) { @@ -215,7 +215,7 @@ OplogEntry makeCommandOplogEntry(OpTime opTime, command, boost::none /* o2 */, {} /* sessionInfo */, - boost::none /* wallClockTime*/, + Date_t() /* wallClockTime*/, boost::none /* stmtId */, uuid); } diff --git a/src/mongo/db/repl/initial_syncer.cpp b/src/mongo/db/repl/initial_syncer.cpp index 9843aa7b2ea..dc121c9072c 100644 --- a/src/mongo/db/repl/initial_syncer.cpp +++ b/src/mongo/db/repl/initial_syncer.cpp @@ -1182,8 +1182,7 @@ void InitialSyncer::_getNextApplierBatchCallback( return _oplogApplier->multiApply(opCtx, std::move(ops)); }; OpTime lastApplied = ops.back().getOpTime(); - invariant(ops.back().getWallClockTime()); - Date_t lastAppliedWall = ops.back().getWallClockTime().get(); + Date_t lastAppliedWall = ops.back().getWallClockTime(); auto numApplied = ops.size(); MultiApplier::CallbackFn onCompletionFn = [=](const Status& s) { diff --git a/src/mongo/db/repl/initial_syncer_test.cpp b/src/mongo/db/repl/initial_syncer_test.cpp index b9eb16070bc..55f4b1074bf 100644 --- a/src/mongo/db/repl/initial_syncer_test.cpp +++ b/src/mongo/db/repl/initial_syncer_test.cpp @@ -1888,7 +1888,7 @@ TEST_F(InitialSyncerTest, ASSERT_OK(_lastApplied.getStatus()); auto dummyEntry = makeOplogEntry(1); ASSERT_EQUALS(dummyEntry.getOpTime(), _lastApplied.getValue().opTime); - ASSERT_EQUALS(dummyEntry.getWallClockTime().get(), _lastApplied.getValue().wallTime); + ASSERT_EQUALS(dummyEntry.getWallClockTime(), _lastApplied.getValue().wallTime); } TEST_F( @@ -1954,7 +1954,7 @@ TEST_F( ASSERT_OK(_lastApplied.getStatus()); auto dummyEntry = makeOplogEntry(3); ASSERT_EQUALS(dummyEntry.getOpTime(), _lastApplied.getValue().opTime); - ASSERT_EQUALS(dummyEntry.getWallClockTime().get(), _lastApplied.getValue().wallTime); + ASSERT_EQUALS(dummyEntry.getWallClockTime(), _lastApplied.getValue().wallTime); } TEST_F( @@ -3222,7 +3222,7 @@ TEST_F(InitialSyncerTest, LastOpTimeShouldBeSetEvenIfNoOperationsAreAppliedAfter initialSyncer->join(); ASSERT_OK(_lastApplied.getStatus()); ASSERT_EQUALS(oplogEntry.getOpTime(), _lastApplied.getValue().opTime); - ASSERT_EQUALS(oplogEntry.getWallClockTime().get(), _lastApplied.getValue().wallTime); + ASSERT_EQUALS(oplogEntry.getWallClockTime(), _lastApplied.getValue().wallTime); ASSERT_FALSE(_replicationProcess->getConsistencyMarkers()->getInitialSyncFlag(opCtx.get())); } @@ -3823,7 +3823,7 @@ void InitialSyncerTest::doSuccessfulInitialSyncWithOneBatch() { serverGlobalParams.featureCompatibility.reset(); ASSERT_OK(_lastApplied.getStatus()); ASSERT_EQUALS(lastOp.getOpTime(), _lastApplied.getValue().opTime); - ASSERT_EQUALS(lastOp.getWallClockTime().get(), _lastApplied.getValue().wallTime); + ASSERT_EQUALS(lastOp.getWallClockTime(), _lastApplied.getValue().wallTime); ASSERT_EQUALS(lastOp.getOpTime().getTimestamp(), _storageInterface->getInitialDataTimestamp()); } @@ -3945,7 +3945,7 @@ TEST_F(InitialSyncerTest, initialSyncer->join(); ASSERT_OK(_lastApplied.getStatus()); ASSERT_EQUALS(lastOp.getOpTime(), _lastApplied.getValue().opTime); - ASSERT_EQUALS(lastOp.getWallClockTime().get(), _lastApplied.getValue().wallTime); + ASSERT_EQUALS(lastOp.getWallClockTime(), _lastApplied.getValue().wallTime); } TEST_F(InitialSyncerTest, @@ -4270,7 +4270,7 @@ TEST_F(InitialSyncerTest, GetInitialSyncProgressReturnsCorrectProgress) { ASSERT_OK(_lastApplied.getStatus()); auto dummyEntry = makeOplogEntry(7); ASSERT_EQUALS(dummyEntry.getOpTime(), _lastApplied.getValue().opTime); - ASSERT_EQUALS(dummyEntry.getWallClockTime().get(), _lastApplied.getValue().wallTime); + ASSERT_EQUALS(dummyEntry.getWallClockTime(), _lastApplied.getValue().wallTime); progress = initialSyncer->getInitialSyncProgress(); log() << "Progress at end: " << progress; diff --git a/src/mongo/db/repl/multiapplier_test.cpp b/src/mongo/db/repl/multiapplier_test.cpp index 0dc922945f6..663f85db19e 100644 --- a/src/mongo/db/repl/multiapplier_test.cpp +++ b/src/mongo/db/repl/multiapplier_test.cpp @@ -77,7 +77,7 @@ OplogEntry makeOplogEntry(int ts) { boost::none, // o2 {}, // sessionInfo boost::none, // upsert - boost::none, // wall clock time + Date_t(), // wall clock time boost::none, // statement id boost::none, // optime of previous write within same transaction boost::none, // pre-image optime diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp index 5bdbe14843f..64aed7ab370 100644 --- a/src/mongo/db/repl/oplog.cpp +++ b/src/mongo/db/repl/oplog.cpp @@ -405,7 +405,6 @@ OpTime logOp(OperationContext* opCtx, MutableOplogEntry* oplogEntry) { auto oplog = oplogInfo->getCollection(); auto wallClockTime = oplogEntry->getWallClockTime(); - invariant(wallClockTime); auto bsonOplogEntry = oplogEntry->toBSON(); // The storage engine will assign the RecordId based on the "ts" field of the oplog entry, see @@ -413,7 +412,7 @@ OpTime logOp(OperationContext* opCtx, MutableOplogEntry* oplogEntry) { std::vector<Record> records{ {RecordId(), RecordData(bsonOplogEntry.objdata(), bsonOplogEntry.objsize())}}; std::vector<Timestamp> timestamps{slot.getTimestamp()}; - _logOpsInner(opCtx, oplogEntry->getNss(), &records, timestamps, oplog, slot, *wallClockTime); + _logOpsInner(opCtx, oplogEntry->getNss(), &records, timestamps, oplog, slot, wallClockTime); wuow.commit(); return slot; } @@ -491,8 +490,7 @@ std::vector<OpTime> logInsertOps(OperationContext* opCtx, invariant(!lastOpTime.isNull()); auto oplog = oplogInfo->getCollection(); auto wallClockTime = oplogEntryTemplate->getWallClockTime(); - invariant(wallClockTime); - _logOpsInner(opCtx, nss, &records, timestamps, oplog, lastOpTime, *wallClockTime); + _logOpsInner(opCtx, nss, &records, timestamps, oplog, lastOpTime, wallClockTime); wuow.commit(); return opTimes; } diff --git a/src/mongo/db/repl/oplog_entry.cpp b/src/mongo/db/repl/oplog_entry.cpp index f41558f2e4c..4da5afdc4dc 100644 --- a/src/mongo/db/repl/oplog_entry.cpp +++ b/src/mongo/db/repl/oplog_entry.cpp @@ -100,7 +100,7 @@ BSONObj makeOplogEntryDoc(OpTime opTime, const boost::optional<BSONObj>& o2Field, const OperationSessionInfo& sessionInfo, const boost::optional<bool>& isUpsert, - const boost::optional<mongo::Date_t>& wallClockTime, + const mongo::Date_t& wallClockTime, const boost::optional<StmtId>& statementId, const boost::optional<OpTime>& prevWriteOpTimeInTransaction, const boost::optional<OpTime>& preImageOpTime, @@ -112,6 +112,7 @@ BSONObj makeOplogEntryDoc(OpTime opTime, builder.append(OplogEntryBase::kVersionFieldName, version); builder.append(OplogEntryBase::kOpTypeFieldName, OpType_serializer(opType)); builder.append(OplogEntryBase::kNssFieldName, nss.toString()); + builder.append(OplogEntryBase::kWallClockTimeFieldName, wallClockTime); if (hash) { builder.append(OplogEntryBase::kHashFieldName, hash.get()); } @@ -129,9 +130,6 @@ BSONObj makeOplogEntryDoc(OpTime opTime, invariant(o2Field); builder.append(OplogEntryBase::kUpsertFieldName, isUpsert.get()); } - if (wallClockTime) { - builder.append(OplogEntryBase::kWallClockTimeFieldName, wallClockTime.get()); - } if (statementId) { builder.append(OplogEntryBase::kStatementIdFieldName, statementId.get()); } @@ -251,7 +249,7 @@ OplogEntry::OplogEntry(OpTime opTime, const boost::optional<BSONObj>& o2Field, const OperationSessionInfo& sessionInfo, const boost::optional<bool>& isUpsert, - const boost::optional<mongo::Date_t>& wallClockTime, + const mongo::Date_t& wallClockTime, const boost::optional<StmtId>& statementId, const boost::optional<OpTime>& prevWriteOpTimeInTransaction, const boost::optional<OpTime>& preImageOpTime, diff --git a/src/mongo/db/repl/oplog_entry.h b/src/mongo/db/repl/oplog_entry.h index 5ae170a8730..190de25a9cc 100644 --- a/src/mongo/db/repl/oplog_entry.h +++ b/src/mongo/db/repl/oplog_entry.h @@ -236,7 +236,7 @@ public: const boost::optional<BSONObj>& o2Field, const OperationSessionInfo& sessionInfo, const boost::optional<bool>& isUpsert, - const boost::optional<mongo::Date_t>& wallClockTime, + const mongo::Date_t& wallClockTime, const boost::optional<StmtId>& statementId, const boost::optional<OpTime>& prevWriteOpTimeInTransaction, const boost::optional<OpTime>& preImageOpTime, diff --git a/src/mongo/db/repl/oplog_entry.idl b/src/mongo/db/repl/oplog_entry.idl index f242eec69d4..f2d1586914e 100644 --- a/src/mongo/db/repl/oplog_entry.idl +++ b/src/mongo/db/repl/oplog_entry.idl @@ -121,7 +121,6 @@ structs: wall: cpp_name: wallClockTime type: date - optional: true # Optional for older than 3.6 releases description: "A wallclock time with MS resolution" stmtId: cpp_name: statementId diff --git a/src/mongo/db/repl/replication_recovery_test.cpp b/src/mongo/db/repl/replication_recovery_test.cpp index ab77100a66e..ca678ebce17 100644 --- a/src/mongo/db/repl/replication_recovery_test.cpp +++ b/src/mongo/db/repl/replication_recovery_test.cpp @@ -227,7 +227,7 @@ repl::OplogEntry _makeOplogEntry(repl::OpTime opTime, BSONObj object, boost::optional<BSONObj> object2 = boost::none, OperationSessionInfo sessionInfo = {}, - boost::optional<Date_t> wallTime = boost::none) { + Date_t wallTime = Date_t()) { return repl::OplogEntry(opTime, // optime boost::none, // hash opType, // opType diff --git a/src/mongo/db/repl/roll_back_local_operations.h b/src/mongo/db/repl/roll_back_local_operations.h index 986f1ebbf22..6c6e6c148ab 100644 --- a/src/mongo/db/repl/roll_back_local_operations.h +++ b/src/mongo/db/repl/roll_back_local_operations.h @@ -72,20 +72,20 @@ public: return _opTime; } - boost::optional<Date_t> getWallClockTime() const { + Date_t getWallClockTime() const { return _wallClockTime; } - boost::optional<Date_t> getFirstOpWallClockTimeAfterCommonPoint() { + Date_t getFirstOpWallClockTimeAfterCommonPoint() { return _firstWallClockTimeAfterCommonPoint; } private: RecordId _recordId; OpTime _opTime; - boost::optional<Date_t> _wallClockTime; + Date_t _wallClockTime; // The wall clock time of the first operation after the common point if it exists. - boost::optional<Date_t> _firstWallClockTimeAfterCommonPoint; + Date_t _firstWallClockTimeAfterCommonPoint; }; /** diff --git a/src/mongo/db/repl/roll_back_local_operations_test.cpp b/src/mongo/db/repl/roll_back_local_operations_test.cpp index 67fff417d0a..6d4261938ea 100644 --- a/src/mongo/db/repl/roll_back_local_operations_test.cpp +++ b/src/mongo/db/repl/roll_back_local_operations_test.cpp @@ -46,32 +46,20 @@ namespace { using namespace mongo; using namespace mongo::repl; -BSONObj makeOp(long long seconds, long long term = 1LL) { +BSONObj makeOp(long long seconds, long long term = 1LL, long wallClockMillis = 0) { auto uuid = unittest::assertGet(UUID::parse("b4c66a44-c1ca-4d86-8d25-12e82fa2de5b")); return BSON("ts" << Timestamp(seconds, seconds) << "t" << term << "op" << "n" << "o" << BSONObj() << "ns" << "roll_back_local_operations.test" - << "ui" << uuid); -} - -BSONObj makeOpWithWallClockTime(long count, long wallClockMillis, long long term = 1LL) { - auto uuid = unittest::assertGet(UUID::parse("b4c66a44-c1ca-4d86-8d25-12e82fa2de5b")); - return BSON("ts" << Timestamp(count, count) << "t" << term << "op" - << "n" - << "o" << BSONObj() << "ns" - << "roll_back_local_operations.test" << "ui" << uuid << "wall" << Date_t::fromMillisSinceEpoch(wallClockMillis)); -}; +} int recordId = 0; -OplogInterfaceMock::Operation makeOpAndRecordId(long long seconds, long long term = 1LL) { - return std::make_pair(makeOp(seconds), RecordId(++recordId)); -} -OplogInterfaceMock::Operation makeOpWithWallClockTimeAndRecordId(long long seconds, - long wallClockMillis, - long long term = 1LL) { - return std::make_pair(makeOpWithWallClockTime(seconds, wallClockMillis), RecordId(++recordId)); +OplogInterfaceMock::Operation makeOpAndRecordId(long long seconds, + long long term = 1LL, + long long wallClockMillis = 0) { + return std::make_pair(makeOp(seconds, term, wallClockMillis), RecordId(++recordId)); } TEST(RollBackLocalOperationsTest, InvalidLocalOplogIterator) { @@ -236,8 +224,8 @@ TEST(SyncRollBackLocalOperationsTest, RemoteOplogMissing) { } TEST(SyncRollBackLocalOperationsTest, RollbackTwoOperations) { - auto commonOperation = makeOpWithWallClockTimeAndRecordId(1, 1 * 5000); - auto firstOpAfterCommonPoint = makeOpWithWallClockTimeAndRecordId(2, 2 * 60 * 60 * 24 * 1000); + auto commonOperation = makeOpAndRecordId(1, 1LL, 1 * 5000); + auto firstOpAfterCommonPoint = makeOpAndRecordId(2, 1LL, 2 * 60 * 60 * 24 * 1000); OplogInterfaceMock::Operations localOperations({ makeOpAndRecordId(3), firstOpAfterCommonPoint, @@ -259,8 +247,8 @@ TEST(SyncRollBackLocalOperationsTest, RollbackTwoOperations) { ASSERT_BSONOBJ_EQ(commonOperation.first, i->first); auto firstOplogEntryAfterCommonPoint = uassertStatusOK(OplogEntry::parse(firstOpAfterCommonPoint.first)); - ASSERT_EQUALS(*result.getValue().getFirstOpWallClockTimeAfterCommonPoint(), - *firstOplogEntryAfterCommonPoint.getWallClockTime()); + ASSERT_EQUALS(result.getValue().getFirstOpWallClockTimeAfterCommonPoint(), + firstOplogEntryAfterCommonPoint.getWallClockTime()); i++; ASSERT_TRUE(i == localOperations.cend()); } diff --git a/src/mongo/db/repl/rollback_impl.cpp b/src/mongo/db/repl/rollback_impl.cpp index 3739e8039a0..1e450f9968b 100644 --- a/src/mongo/db/repl/rollback_impl.cpp +++ b/src/mongo/db/repl/rollback_impl.cpp @@ -970,42 +970,33 @@ Status RollbackImpl::_checkAgainstTimeLimit( _rollbackStats.lastLocalOptime = topOfOplog.getOpTime(); - auto topOfOplogWallOpt = topOfOplog.getWallClockTime(); + auto topOfOplogWallTime = topOfOplog.getWallClockTime(); // We check the difference between the top of the oplog and the first oplog entry after the // common point when computing the rollback time limit. - auto firstOpWallClockTimeAfterCommonPointOpt = + auto firstOpWallClockTimeAfterCommonPoint = commonPoint.getFirstOpWallClockTimeAfterCommonPoint(); + if (topOfOplogWallTime >= firstOpWallClockTimeAfterCommonPoint) { - // Only compute the difference if both the top of the oplog and the first oplog entry after the - // common point have wall clock times. - if (firstOpWallClockTimeAfterCommonPointOpt && topOfOplogWallOpt) { - auto topOfOplogWallTime = topOfOplogWallOpt.get(); - auto firstOpWallClockTimeAfterCommonPoint = firstOpWallClockTimeAfterCommonPointOpt.get(); + unsigned long long diff = durationCount<Seconds>( + Milliseconds(topOfOplogWallTime - firstOpWallClockTimeAfterCommonPoint)); - if (topOfOplogWallTime >= firstOpWallClockTimeAfterCommonPoint) { + _rollbackStats.lastLocalWallClockTime = topOfOplogWallTime; + _rollbackStats.firstOpWallClockTimeAfterCommonPoint = firstOpWallClockTimeAfterCommonPoint; - unsigned long long diff = durationCount<Seconds>( - Milliseconds(topOfOplogWallTime - firstOpWallClockTimeAfterCommonPoint)); - - _rollbackStats.lastLocalWallClockTime = topOfOplogWallTime; - _rollbackStats.firstOpWallClockTimeAfterCommonPoint = - firstOpWallClockTimeAfterCommonPoint; - - auto timeLimit = static_cast<unsigned long long>(gRollbackTimeLimitSecs.loadRelaxed()); - if (diff > timeLimit) { - return Status(ErrorCodes::UnrecoverableRollbackError, - str::stream() << "not willing to roll back more than " << timeLimit - << " seconds of data. Have: " << diff << " seconds."); - } - - } else { - warning() - << "Wall clock times on oplog entries not monotonically increasing. This " - "might indicate a backward clock skew. Time at first oplog after common point: " - << firstOpWallClockTimeAfterCommonPoint - << ". Time at top of oplog: " << topOfOplogWallTime; + auto timeLimit = static_cast<unsigned long long>(gRollbackTimeLimitSecs.loadRelaxed()); + if (diff > timeLimit) { + return Status(ErrorCodes::UnrecoverableRollbackError, + str::stream() << "not willing to roll back more than " << timeLimit + << " seconds of data. Have: " << diff << " seconds."); } + + } else { + warning() + << "Wall clock times on oplog entries not monotonically increasing. This " + "might indicate a backward clock skew. Time at first oplog after common point: " + << firstOpWallClockTimeAfterCommonPoint + << ". Time at top of oplog: " << topOfOplogWallTime; } return Status::OK(); diff --git a/src/mongo/db/repl/rollback_impl_test.cpp b/src/mongo/db/repl/rollback_impl_test.cpp index e3cb9c970c9..4d19ac681fc 100644 --- a/src/mongo/db/repl/rollback_impl_test.cpp +++ b/src/mongo/db/repl/rollback_impl_test.cpp @@ -69,21 +69,21 @@ std::string kGenericUUIDStr = "b4c66a44-c1ca-4d86-8d25-12e82fa2de5b"; BSONObj makeInsertOplogEntry(long long time, BSONObj obj, StringData ns, UUID uuid) { return BSON("ts" << Timestamp(time, time) << "t" << time << "op" << "i" - << "o" << obj << "ns" << ns << "ui" << uuid); + << "o" << obj << "ns" << ns << "ui" << uuid << "wall" << Date_t()); } BSONObj makeUpdateOplogEntry( long long time, BSONObj query, BSONObj update, StringData ns, UUID uuid) { return BSON("ts" << Timestamp(time, time) << "t" << time << "op" << "u" - << "ns" << ns << "ui" << uuid << "o2" << query << "o" - << BSON("$set" << update)); + << "ns" << ns << "ui" << uuid << "o2" << query << "o" << BSON("$set" << update) + << "wall" << Date_t()); } BSONObj makeDeleteOplogEntry(long long time, BSONObj id, StringData ns, UUID uuid) { return BSON("ts" << Timestamp(time, time) << "t" << time << "op" << "d" - << "ns" << ns << "ui" << uuid << "o" << id); + << "ns" << ns << "ui" << uuid << "o" << id << "wall" << Date_t()); } class RollbackImplForTest final : public RollbackImpl { @@ -364,7 +364,8 @@ BSONObj makeOp(OpTime time) { auto kGenericUUID = unittest::assertGet(UUID::parse(kGenericUUIDStr)); return BSON("ts" << time.getTimestamp() << "t" << time.getTerm() << "op" << "n" - << "o" << BSONObj() << "ns" << nss.ns() << "ui" << kGenericUUID); + << "o" << BSONObj() << "ns" << nss.ns() << "ui" << kGenericUUID << "wall" + << Date_t()); } BSONObj makeOp(int count) { @@ -929,10 +930,10 @@ TEST_F(RollbackImplTest, RollbackDoesNotWriteRollbackFilesIfNoInsertsOrUpdatesAf const auto uuid = UUID::gen(); const auto nss = NamespaceString("db.coll"); const auto coll = _initializeCollection(_opCtx.get(), uuid, nss); - const auto oplogEntry = - BSON("ts" << Timestamp(3, 3) << "t" << 3LL << "op" - << "c" - << "o" << BSON("create" << nss.coll()) << "ns" << nss.ns() << "ui" << uuid); + const auto oplogEntry = BSON("ts" << Timestamp(3, 3) << "t" << 3LL << "op" + << "c" + << "wall" << Date_t() << "o" << BSON("create" << nss.coll()) + << "ns" << nss.ns() << "ui" << uuid); ASSERT_OK(_insertOplogEntry(oplogEntry)); ASSERT_OK(_rollback->runRollback(_opCtx.get())); @@ -1154,7 +1155,8 @@ TEST_F(RollbackImplTest, RollbackProperlySavesFilesWhenInsertsAndDropOfCollectio const auto oplogEntry = BSON("ts" << dropOpTime.getTimestamp() << "t" << dropOpTime.getTerm() << "op" << "c" - << "o" << BSON("drop" << nss.coll()) << "ns" << nss.ns() << "ui" << uuid); + << "wall" << Date_t() << "o" << BSON("drop" << nss.coll()) << "ns" << nss.ns() + << "ui" << uuid); ASSERT_OK(_insertOplogEntry(oplogEntry)); ASSERT_OK(_rollback->runRollback(_opCtx.get())); @@ -1179,10 +1181,10 @@ TEST_F(RollbackImplTest, RollbackProperlySavesFilesWhenCreateCollAndInsertsAreRo const auto nss = NamespaceString("db.people"); const auto uuid = UUID::gen(); const auto coll = _initializeCollection(_opCtx.get(), uuid, nss); - const auto oplogEntry = - BSON("ts" << Timestamp(3, 3) << "t" << 3LL << "op" - << "c" - << "o" << BSON("create" << nss.coll()) << "ns" << nss.ns() << "ui" << uuid); + const auto oplogEntry = BSON("ts" << Timestamp(3, 3) << "t" << 3LL << "op" + << "c" + << "wall" << Date_t() << "o" << BSON("create" << nss.coll()) + << "ns" << nss.ns() << "ui" << uuid); ASSERT_OK(_insertOplogEntry(oplogEntry)); // Insert documents into the collection. @@ -1429,7 +1431,7 @@ RollbackImplTest::_setUpUnpreparedTransactionForCountTest(UUID collId) { boost::none, // o2Field sessionInfo, // sessionInfo boost::none, // isUpsert - boost::none, // wallClockTime + Date_t(), // wallClockTime boost::none, // statementId OpTime(), // prevWriteOpTimeInTransaction boost::none, // preImageOpTime @@ -1454,7 +1456,7 @@ RollbackImplTest::_setUpUnpreparedTransactionForCountTest(UUID collId) { boost::none, // o2Field sessionInfo, // sessionInfo boost::none, // isUpsert - boost::none, // wallClockTime + Date_t(), // wallClockTime boost::none, // statementId partialApplyOpsOpTime, // prevWriteOpTimeInTransaction boost::none, // preImageOpTime @@ -1536,6 +1538,7 @@ public: collId.appendToBuilder(&bob, "ui"); bob.append("ns", nss.ns()); bob.append("o", doc); + bob.append("wall", Date_t()); bob.append("lsid", BSON("id" << sessionId << "uid" << BSONBinData(std::string(32, 'x').data(), 32, BinDataGeneral))); diff --git a/src/mongo/db/repl/rollback_test_fixture.cpp b/src/mongo/db/repl/rollback_test_fixture.cpp index b5824819380..881a0b2c612 100644 --- a/src/mongo/db/repl/rollback_test_fixture.cpp +++ b/src/mongo/db/repl/rollback_test_fixture.cpp @@ -160,6 +160,7 @@ std::pair<BSONObj, RecordId> RollbackTest::makeCRUDOp(OpTypeEnum opType, if (o2) { bob.append("o2", *o2); } + bob.append("wall", Date_t()); return std::make_pair(bob.obj(), RecordId(recordId)); } @@ -183,6 +184,7 @@ std::pair<BSONObj, RecordId> RollbackTest::makeCommandOp(Timestamp ts, if (o2) { bob.append("o2", *o2); } + bob.append("wall", Date_t()); return std::make_pair(bob.obj(), RecordId(recordId)); } @@ -297,7 +299,7 @@ void RollbackResyncsCollectionOptionsTest::resyncCollectionOptionsTest( << "n" << "o" << BSONObj() << "ns" << "rollback_test.test" - << "ui" << commonOpUuid); + << "wall" << Date_t() << "ui" << commonOpUuid); auto commonOperation = std::make_pair(commonOpBson, RecordId(1)); diff --git a/src/mongo/db/repl/rs_rollback.cpp b/src/mongo/db/repl/rs_rollback.cpp index d7f2382d120..911c822f9f7 100644 --- a/src/mongo/db/repl/rs_rollback.cpp +++ b/src/mongo/db/repl/rs_rollback.cpp @@ -234,11 +234,16 @@ Status rollback_internal::updateFixUpInfoFromLocalOplogEntry(OperationContext* o // and populate them with dummy values before parsing ourObj as an oplog entry. BSONObjBuilder bob; if (isNestedApplyOpsCommand) { - if (!ourObj.hasField("ts")) { - bob.appendTimestamp("ts"); + if (!ourObj.hasField(OplogEntry::kTimestampFieldName)) { + bob.appendTimestamp(OplogEntry::kTimestampFieldName); + } + if (!ourObj.hasField(OplogEntry::kWallClockTimeFieldName)) { + bob.append(OplogEntry::kWallClockTimeFieldName, Date_t()); } } + bob.appendElements(ourObj); + BSONObj fixedObj = bob.obj(); // Parse the oplog entry. diff --git a/src/mongo/db/repl/rs_rollback_test.cpp b/src/mongo/db/repl/rs_rollback_test.cpp index 6408443af27..85d13299072 100644 --- a/src/mongo/db/repl/rs_rollback_test.cpp +++ b/src/mongo/db/repl/rs_rollback_test.cpp @@ -90,7 +90,7 @@ OplogInterfaceMock::Operation makeDropIndexOplogEntry(Collection* collection, << "ui" << collection->uuid() << "ns" << "test.$cmd" << "o" << BSON("dropIndexes" << collection->ns().coll() << "index" << indexName) - << "o2" << indexSpec), + << "o2" << indexSpec << "wall" << Date_t()), RecordId(time)); } @@ -106,7 +106,8 @@ OplogInterfaceMock::Operation makeCreateIndexOplogEntry(Collection* collection, << "c" << "ns" << "test.$cmd" - << "ui" << collection->uuid() << "o" << indexSpec), + << "ui" << collection->uuid() << "o" << indexSpec << "wall" + << Date_t()), RecordId(time)); } @@ -129,7 +130,7 @@ OplogInterfaceMock::Operation makeRenameCollectionOplogEntry(const NamespaceStri return std::make_pair(BSON("ts" << opTime.getTimestamp() << "t" << opTime.getTerm() << "op" << "c" << "ui" << collectionUUID << "ns" << renameFrom.ns() << "o" - << obj), + << obj << "wall" << Date_t()), RecordId(opTime.getTimestamp().getSecs())); } @@ -139,7 +140,7 @@ BSONObj makeOp(long long seconds) { << "n" << "o" << BSONObj() << "ns" << "rs_rollback.test" - << "ui" << uuid); + << "ui" << uuid << "wall" << Date_t()); } int recordId = 0; @@ -273,12 +274,13 @@ int _testRollbackDelete(OperationContext* opCtx, const BSONObj& documentAtSource, const bool collectionAtSourceExists = true) { auto commonOperation = makeOpAndRecordId(1); - auto deleteOperation = std::make_pair(BSON("ts" << Timestamp(Seconds(2), 0) << "op" - << "d" - << "ui" << uuid << "ns" - << "test.t" - << "o" << BSON("_id" << 0)), - RecordId(2)); + auto deleteOperation = + std::make_pair(BSON("ts" << Timestamp(Seconds(2), 0) << "op" + << "d" + << "ui" << uuid << "ns" + << "test.t" + << "o" << BSON("_id" << 0) << "wall" << Date_t()), + RecordId(2)); class RollbackSourceLocal : public RollbackSourceMock { public: RollbackSourceLocal(const BSONObj& documentAtSource, @@ -397,12 +399,13 @@ TEST_F(RSRollbackTest, RollbackDeleteRestoreDocument) { TEST_F(RSRollbackTest, RollbackInsertDocumentWithNoId) { createOplog(_opCtx.get()); auto commonOperation = makeOpAndRecordId(1); - auto insertDocumentOperation = std::make_pair(BSON("ts" << Timestamp(Seconds(2), 0) << "op" - << "i" - << "ui" << UUID::gen() << "ns" - << "test.t" - << "o" << BSON("a" << 1)), - RecordId(2)); + auto insertDocumentOperation = + std::make_pair(BSON("ts" << Timestamp(Seconds(2), 0) << "op" + << "i" + << "ui" << UUID::gen() << "ns" + << "test.t" + << "wall" << Date_t() << "o" << BSON("a" << 1)), + RecordId(2)); class RollbackSourceLocal : public RollbackSourceMock { public: RollbackSourceLocal(std::unique_ptr<OplogInterface> oplog) @@ -740,15 +743,16 @@ TEST_F(RSRollbackTest, RollbackCreateIndexCommandMissingIndexName) { << "t" << "ns" << "test.t" - << "v" << static_cast<int>(kIndexVersion) << "key" << BSON("a" << 1)); - - auto createIndexOperation = - std::make_pair(BSON("ts" << Timestamp(Seconds(2), 0) << "op" - << "c" - << "ns" - << "test.$cmd" - << "ui" << collection->uuid() << "o" << command), - RecordId(2)); + << "wall" << Date_t() << "v" << static_cast<int>(kIndexVersion) << "key" + << BSON("a" << 1)); + + auto createIndexOperation = std::make_pair(BSON("ts" << Timestamp(Seconds(2), 0) << "op" + << "c" + << "ns" + << "test.$cmd" + << "wall" << Date_t() << "ui" + << collection->uuid() << "o" << command), + RecordId(2)); RollbackSourceMock rollbackSource(std::unique_ptr<OplogInterface>(new OplogInterfaceMock({ commonOperation, }))); @@ -938,7 +942,7 @@ TEST_F(RSRollbackTest, RollbackUnknownCommand) { << "c" << "ui" << UUID::gen() << "ns" << "test.t" - << "o" + << "wall" << Date_t() << "o" << BSON("convertToCapped" << "t")), RecordId(2)); @@ -972,7 +976,7 @@ TEST_F(RSRollbackTest, RollbackDropCollectionCommand) { << "c" << "ui" << coll->uuid() << "ns" << "test.t" - << "o" + << "wall" << Date_t() << "o" << BSON("drop" << "t")), RecordId(2)); @@ -1294,7 +1298,7 @@ TEST_F(RSRollbackTest, RollbackDropCollectionThenRenameCollectionToDroppedCollec << "c" << "ui" << droppedCollectionUUID << "ns" << "test.x" - << "o" + << "wall" << Date_t() << "o" << BSON("drop" << "x")), RecordId(2)); @@ -1367,7 +1371,7 @@ TEST_F(RSRollbackTest, RollbackRenameCollectionThenCreateNewCollectionWithOldNam << "c" << "ui" << createdCollectionUUID << "ns" << "test.x" - << "o" + << "wall" << Date_t() << "o" << BSON("create" << "x")), RecordId(3)); @@ -1413,7 +1417,7 @@ TEST_F(RSRollbackTest, RollbackCollModCommandFailsIfRBIDChangesWhileSyncingColle << "c" << "ui" << coll->uuid() << "ns" << "test.t" - << "o" + << "wall" << Date_t() << "o" << BSON("collMod" << "t" << "validationLevel" @@ -1451,12 +1455,13 @@ TEST_F(RSRollbackTest, RollbackDropDatabaseCommand) { createOplog(_opCtx.get()); auto commonOperation = makeOpAndRecordId(1); // 'dropDatabase' operations are special and do not include a UUID field. - auto dropDatabaseOperation = std::make_pair(BSON("ts" << Timestamp(Seconds(2), 0) << "op" - << "c" - << "ns" - << "test.$cmd" - << "o" << BSON("dropDatabase" << 1)), - RecordId(2)); + auto dropDatabaseOperation = + std::make_pair(BSON("ts" << Timestamp(Seconds(2), 0) << "op" + << "c" + << "ns" + << "test.$cmd" + << "wall" << Date_t() << "o" << BSON("dropDatabase" << 1)), + RecordId(2)); RollbackSourceMock rollbackSource(std::unique_ptr<OplogInterface>(new OplogInterfaceMock({ commonOperation, }))); @@ -1474,7 +1479,8 @@ BSONObj makeApplyOpsOplogEntry(Timestamp ts, std::initializer_list<BSONObj> ops) entry << "ts" << ts << "op" << "c" << "ns" - << "admin"; + << "admin" + << "wall" << Date_t(); { BSONObjBuilder cmd(entry.subobjStart("o")); BSONArrayBuilder subops(entry.subarrayStart("applyOps")); @@ -1529,41 +1535,41 @@ TEST_F(RSRollbackTest, RollbackApplyOpsCommand) { << "u" << "ui" << uuid << "ts" << Timestamp(1, 1) << "t" << 1LL << "ns" << "test.t" - << "o2" << BSON("_id" << 1) << "o" + << "o2" << BSON("_id" << 1) << "wall" << Date_t() << "o" << BSON("_id" << 1 << "v" << 2)), BSON("op" << "u" << "ui" << uuid << "ts" << Timestamp(2, 1) << "t" << 1LL << "ns" << "test.t" - << "o2" << BSON("_id" << 2) << "o" + << "o2" << BSON("_id" << 2) << "wall" << Date_t() << "o" << BSON("_id" << 2 << "v" << 4)), BSON("op" << "d" << "ui" << uuid << "ts" << Timestamp(3, 1) << "t" << 1LL << "ns" << "test.t" - << "o" << BSON("_id" << 3)), + << "wall" << Date_t() << "o" << BSON("_id" << 3)), BSON("op" << "i" << "ui" << uuid << "ts" << Timestamp(4, 1) << "t" << 1LL << "ns" << "test.t" - << "o" << BSON("_id" << 4)), + << "wall" << Date_t() << "o" << BSON("_id" << 4)), // applyOps internal oplog entries are not required // to have a timestamp. BSON("op" << "i" << "ui" << uuid << "ts" << Timestamp(4, 1) << "t" << 1LL << "ns" << "test.t" - << "o" << BSON("_id" << 4)), + << "wall" << Date_t() << "o" << BSON("_id" << 4)), BSON("op" << "i" << "ui" << uuid << "t" << 1LL << "ns" << "test.t" - << "o" << BSON("_id" << 4)), + << "wall" << Date_t() << "o" << BSON("_id" << 4)), BSON("op" << "i" << "ui" << uuid << "t" << 1LL << "ns" << "test.t" - << "o" << BSON("_id" << 4))}), + << "wall" << Date_t() << "o" << BSON("_id" << 4))}), RecordId(2)); class RollbackSourceLocal : public RollbackSourceMock { @@ -1633,7 +1639,7 @@ TEST_F(RSRollbackTest, RollbackCreateCollectionCommand) { << "c" << "ui" << coll->uuid() << "ns" << "test.t" - << "o" + << "wall" << Date_t() << "o" << BSON("create" << "t")), RecordId(2)); @@ -1862,7 +1868,7 @@ TEST(RSRollbackTest, LocalEntryWithoutNsIsFatal) { << "ui" << UUID::gen() << "ts" << Timestamp(1, 1) << "t" << 1LL << "ns" << "test.t" - << "o" << BSON("_id" << 1 << "a" << 1)); + << "wall" << Date_t() << "o" << BSON("_id" << 1 << "a" << 1)); FixUpInfo fui; ASSERT_OK(updateFixUpInfoFromLocalOplogEntry( nullptr /* opCtx */, OplogInterfaceMock(), fui, validOplogEntry, false)); @@ -1871,7 +1877,8 @@ TEST(RSRollbackTest, LocalEntryWithoutNsIsFatal) { << "ui" << UUID::gen() << "ts" << Timestamp(1, 1) << "t" << 1LL << "ns" << "" - << "o" << BSON("_id" << 1 << "a" << 1)); + << "wall" << Date_t() << "o" + << BSON("_id" << 1 << "a" << 1)); ASSERT_THROWS(updateFixUpInfoFromLocalOplogEntry( nullptr /* opCtx */, OplogInterfaceMock(), fui, invalidOplogEntry, false), RSFatalException); @@ -1883,7 +1890,7 @@ TEST(RSRollbackTest, LocalEntryWithoutOIsFatal) { << "ui" << UUID::gen() << "ts" << Timestamp(1, 1) << "t" << 1LL << "ns" << "test.t" - << "o" << BSON("_id" << 1 << "a" << 1)); + << "wall" << Date_t() << "o" << BSON("_id" << 1 << "a" << 1)); FixUpInfo fui; ASSERT_OK(updateFixUpInfoFromLocalOplogEntry( nullptr /* opCtx */, OplogInterfaceMock(), fui, validOplogEntry, false)); @@ -1892,7 +1899,7 @@ TEST(RSRollbackTest, LocalEntryWithoutOIsFatal) { << "ui" << UUID::gen() << "ts" << Timestamp(1, 1) << "t" << 1LL << "ns" << "test.t" - << "o" << BSONObj()); + << "wall" << Date_t() << "o" << BSONObj()); ASSERT_THROWS(updateFixUpInfoFromLocalOplogEntry( nullptr /* opCtx */, OplogInterfaceMock(), fui, invalidOplogEntry, false), RSFatalException); @@ -1904,7 +1911,8 @@ DEATH_TEST_F(RSRollbackTest, LocalUpdateEntryWithoutO2IsFatal, "Fatal Assertion" << "ui" << UUID::gen() << "ts" << Timestamp(1, 1) << "t" << 1LL << "ns" << "test.t" - << "o" << BSON("_id" << 1 << "a" << 1)); + << "wall" << Date_t() << "o" + << BSON("_id" << 1 << "a" << 1)); FixUpInfo fui; updateFixUpInfoFromLocalOplogEntry( nullptr /* opCtx */, OplogInterfaceMock(), fui, invalidOplogEntry, false) @@ -1917,8 +1925,8 @@ TEST(RSRollbackTest, LocalUpdateEntryWithEmptyO2IsFatal) { << "ui" << UUID::gen() << "ts" << Timestamp(1, 1) << "t" << 1LL << "ns" << "test.t" - << "o" << BSON("_id" << 1 << "a" << 1) << "o2" - << BSON("_id" << 1)); + << "wall" << Date_t() << "o" << BSON("_id" << 1 << "a" << 1) + << "o2" << BSON("_id" << 1)); FixUpInfo fui; ASSERT_OK(updateFixUpInfoFromLocalOplogEntry( nullptr /* opCtx */, OplogInterfaceMock(), fui, validOplogEntry, false)); @@ -1927,8 +1935,8 @@ TEST(RSRollbackTest, LocalUpdateEntryWithEmptyO2IsFatal) { << "ui" << UUID::gen() << "ts" << Timestamp(1, 1) << "t" << 1LL << "ns" << "test.t" - << "o" << BSON("_id" << 1 << "a" << 1) << "o2" - << BSONObj()); + << "wall" << Date_t() << "o" << BSON("_id" << 1 << "a" << 1) + << "o2" << BSONObj()); ASSERT_THROWS(updateFixUpInfoFromLocalOplogEntry( nullptr /* opCtx */, OplogInterfaceMock(), fui, invalidOplogEntry, false), RSFatalException); @@ -1939,7 +1947,7 @@ DEATH_TEST_F(RSRollbackTest, LocalEntryWithTxnNumberWithoutSessionIdIsFatal, "in << "i" << "ui" << UUID::gen() << "ns" << "test.t" - << "o" << BSON("_id" << 1 << "a" << 1)); + << "wall" << Date_t() << "o" << BSON("_id" << 1 << "a" << 1)); FixUpInfo fui; ASSERT_OK(updateFixUpInfoFromLocalOplogEntry( nullptr /* opCtx */, OplogInterfaceMock(), fui, validOplogEntry, false)); @@ -1958,12 +1966,13 @@ TEST_F(RSRollbackTest, LocalEntryWithTxnNumberWithoutTxnTableUUIDIsFatal) { // If txnNumber is present, but the transaction collection has no UUID, rollback fails. UUID uuid = UUID::gen(); auto lsid = makeLogicalSessionIdForTest(); - auto entryWithTxnNumber = BSON("ts" << Timestamp(Seconds(1), 0) << "t" << 1LL << "op" - << "i" - << "ui" << uuid << "ns" - << "test.t" - << "o" << BSON("_id" << 1 << "a" << 1) << "txnNumber" << 1LL - << "stmtId" << 1 << "lsid" << lsid.toBSON()); + auto entryWithTxnNumber = + BSON("ts" << Timestamp(Seconds(1), 0) << "t" << 1LL << "op" + << "i" + << "ui" << uuid << "ns" + << "test.t" + << "wall" << Date_t() << "o" << BSON("_id" << 1 << "a" << 1) << "txnNumber" << 1LL + << "stmtId" << 1 << "lsid" << lsid.toBSON()); FixUpInfo fui; ASSERT_THROWS(updateFixUpInfoFromLocalOplogEntry( @@ -1975,11 +1984,12 @@ TEST_F(RSRollbackTest, LocalEntryWithTxnNumberAddsTransactionTableDocToBeRefetch FixUpInfo fui; // With no txnNumber present, no extra documents need to be refetched. - auto entryWithoutTxnNumber = BSON("ts" << Timestamp(Seconds(1), 0) << "t" << 1LL << "op" - << "i" - << "ui" << UUID::gen() << "ns" - << "test.t2" - << "o" << BSON("_id" << 2 << "a" << 2)); + auto entryWithoutTxnNumber = + BSON("ts" << Timestamp(Seconds(1), 0) << "t" << 1LL << "op" + << "i" + << "ui" << UUID::gen() << "ns" + << "test.t2" + << "wall" << Date_t() << "o" << BSON("_id" << 2 << "a" << 2)); ASSERT_OK(updateFixUpInfoFromLocalOplogEntry( nullptr /* opCtx */, OplogInterfaceMock(), fui, entryWithoutTxnNumber, false)); @@ -1990,12 +2000,13 @@ TEST_F(RSRollbackTest, LocalEntryWithTxnNumberAddsTransactionTableDocToBeRefetch // refetched. UUID uuid = UUID::gen(); auto lsid = makeLogicalSessionIdForTest(); - auto entryWithTxnNumber = BSON("ts" << Timestamp(Seconds(1), 0) << "t" << 1LL << "op" - << "i" - << "ui" << uuid << "ns" - << "test.t" - << "o" << BSON("_id" << 1 << "a" << 1) << "txnNumber" << 1LL - << "stmtId" << 1 << "lsid" << lsid.toBSON()); + auto entryWithTxnNumber = + BSON("ts" << Timestamp(Seconds(1), 0) << "t" << 1LL << "op" + << "i" + << "ui" << uuid << "ns" + << "test.t" + << "wall" << Date_t() << "o" << BSON("_id" << 1 << "a" << 1) << "txnNumber" << 1LL + << "stmtId" << 1 << "lsid" << lsid.toBSON()); UUID transactionTableUUID = UUID::gen(); fui.transactionTableUUID = transactionTableUUID; @@ -2022,7 +2033,7 @@ TEST_F(RSRollbackTest, LocalEntryWithPartialTxnAddsTransactionTableDocToBeRefetc << "c" << "ns" << "admin.$cmd" - << "o" + << "wall" << Date_t() << "o" << BSON("applyOps" << BSON_ARRAY(BSON("op" << "i" << "ui" << uuid << "ns" @@ -2048,13 +2059,14 @@ TEST_F(RSRollbackTest, LocalAbortTxnRefetchesTransactionTableEntry) { FixUpInfo fui; auto lsid = makeLogicalSessionIdForTest(); - auto abortTxnEntry = BSON("ts" << Timestamp(Seconds(1), 1) << "t" << 1LL << "op" - << "c" - << "ns" - << "admin.$cmd" - << "o" << BSON("abortTransaction" << 1) << "txnNumber" << 1LL - << "stmtId" << 1 << "lsid" << lsid.toBSON() << "prevOpTime" - << BSON("ts" << Timestamp(Seconds(1), 0) << "t" << 1LL)); + auto abortTxnEntry = + BSON("ts" << Timestamp(Seconds(1), 1) << "t" << 1LL << "op" + << "c" + << "ns" + << "admin.$cmd" + << "wall" << Date_t() << "o" << BSON("abortTransaction" << 1) << "txnNumber" + << 1LL << "stmtId" << 1 << "lsid" << lsid.toBSON() << "prevOpTime" + << BSON("ts" << Timestamp(Seconds(1), 0) << "t" << 1LL)); UUID transactionTableUUID = UUID::gen(); fui.transactionTableUUID = transactionTableUUID; @@ -2077,20 +2089,21 @@ TEST_F(RSRollbackTest, LocalEntryWithAbortedPartialTxnRefetchesOnlyTransactionTa // that may not have been committed, and even if it is known that the transaction aborted. UUID uuid = UUID::gen(); auto lsid = makeLogicalSessionIdForTest(); - auto abortTxnEntry = BSON("ts" << Timestamp(Seconds(1), 2) << "t" << 1LL << "op" - << "c" - << "ns" - << "admin.$cmd" - << "o" << BSON("abortTransaction" << 1) << "txnNumber" << 1LL - << "stmtId" << 1 << "lsid" << lsid.toBSON() << "prevOpTime" - << BSON("ts" << Timestamp(Seconds(1), 1) << "t" << 1LL)); + auto abortTxnEntry = + BSON("ts" << Timestamp(Seconds(1), 2) << "t" << 1LL << "op" + << "c" + << "ns" + << "admin.$cmd" + << "wall" << Date_t() << "o" << BSON("abortTransaction" << 1) << "txnNumber" + << 1LL << "stmtId" << 1 << "lsid" << lsid.toBSON() << "prevOpTime" + << BSON("ts" << Timestamp(Seconds(1), 1) << "t" << 1LL)); auto entryWithTxnNumber = BSON("ts" << Timestamp(Seconds(1), 1) << "t" << 1LL << "op" << "c" << "ns" << "admin.$cmd" - << "o" + << "wall" << Date_t() << "o" << BSON("applyOps" << BSON_ARRAY(BSON("op" << "i" << "ui" << uuid << "ns" @@ -2121,7 +2134,7 @@ TEST_F(RSRollbackTest, LocalEntryWithCommittedTxnRefetchesDocsAndTransactionTabl << "c" << "ns" << "admin.$cmd" - << "o" + << "wall" << Date_t() << "o" << BSON("applyOps" << BSON_ARRAY(BSON("op" << "i" << "ui" << uuid << "ns" @@ -2137,7 +2150,7 @@ TEST_F(RSRollbackTest, LocalEntryWithCommittedTxnRefetchesDocsAndTransactionTabl << "c" << "ns" << "admin.$cmd" - << "o" + << "wall" << Date_t() << "o" << BSON("applyOps" << BSON_ARRAY(BSON("op" << "i" << "ui" << uuid << "ns" @@ -2194,7 +2207,7 @@ TEST_F(RSRollbackTest, RollbackFetchesTransactionOperationBeforeCommonPoint) { << "c" << "ns" << "admin.$cmd" - << "o" + << "wall" << Date_t() << "o" << BSON("applyOps" << BSON_ARRAY(BSON("op" << "i" << "ui" << uuid << "ns" @@ -2210,7 +2223,7 @@ TEST_F(RSRollbackTest, RollbackFetchesTransactionOperationBeforeCommonPoint) { << "c" << "ns" << "admin.$cmd" - << "o" + << "wall" << Date_t() << "o" << BSON("applyOps" << BSON_ARRAY(BSON("op" << "i" << "ui" << uuid << "ns" @@ -2226,7 +2239,7 @@ TEST_F(RSRollbackTest, RollbackFetchesTransactionOperationBeforeCommonPoint) { << "c" << "ns" << "admin.$cmd" - << "o" + << "wall" << Date_t() << "o" << BSON("applyOps" << BSON_ARRAY(BSON("op" << "i" << "ui" << uuid << "ns" @@ -2308,7 +2321,7 @@ TEST_F(RSRollbackTest, RollbackIncompleteTransactionReturnsUnrecoverableRollback << "c" << "ns" << "admin.$cmd" - << "o" + << "wall" << Date_t() << "o" << BSON("applyOps" << BSON_ARRAY(BSON("op" << "i" << "ui" << uuid << "ns" @@ -2324,7 +2337,7 @@ TEST_F(RSRollbackTest, RollbackIncompleteTransactionReturnsUnrecoverableRollback << "c" << "ns" << "admin.$cmd" - << "o" + << "wall" << Date_t() << "o" << BSON("applyOps" << BSON_ARRAY(BSON("op" << "i" << "ui" << uuid << "ns" @@ -2379,8 +2392,8 @@ TEST_F(RSRollbackTest, RollbackFailsIfTransactionDocumentRefetchReturnsDifferent << "i" << "ui" << UUID::gen() << "ns" << "test.t" - << "o" << BSON("_id" << 1 << "a" << 1) << "txnNumber" << 1LL << "stmtId" << 1 - << "lsid" << makeLogicalSessionIdForTest().toBSON()); + << "wall" << Date_t() << "o" << BSON("_id" << 1 << "a" << 1) << "txnNumber" << 1LL + << "stmtId" << 1 << "lsid" << makeLogicalSessionIdForTest().toBSON()); UUID transactionTableUUID = UUID::gen(); fui.transactionTableUUID = transactionTableUUID; diff --git a/src/mongo/db/repl/session_update_tracker.cpp b/src/mongo/db/repl/session_update_tracker.cpp index a251414e014..c539e608670 100644 --- a/src/mongo/db/repl/session_update_tracker.cpp +++ b/src/mongo/db/repl/session_update_tracker.cpp @@ -86,14 +86,13 @@ boost::optional<repl::OplogEntry> createMatchingTransactionTableUpdate( } invariant(sessionInfo.getSessionId()); - invariant(entry.getWallClockTime()); const auto updateBSON = [&] { SessionTxnRecord newTxnRecord; newTxnRecord.setSessionId(*sessionInfo.getSessionId()); newTxnRecord.setTxnNum(*sessionInfo.getTxnNumber()); newTxnRecord.setLastWriteOpTime(entry.getOpTime()); - newTxnRecord.setLastWriteDate(*entry.getWallClockTime()); + newTxnRecord.setLastWriteDate(entry.getWallClockTime()); return newTxnRecord.toBSON(); }(); @@ -102,7 +101,7 @@ boost::optional<repl::OplogEntry> createMatchingTransactionTableUpdate( entry.getOpTime(), updateBSON, BSON(SessionTxnRecord::kSessionIdFieldName << sessionInfo.getSessionId()->toBSON()), - *entry.getWallClockTime()); + entry.getWallClockTime()); } /** @@ -263,14 +262,13 @@ boost::optional<OplogEntry> SessionUpdateTracker::_createTransactionTableUpdateF return boost::none; } invariant(sessionInfo.getSessionId()); - invariant(entry.getWallClockTime()); const auto updateBSON = [&] { SessionTxnRecord newTxnRecord; newTxnRecord.setSessionId(*sessionInfo.getSessionId()); newTxnRecord.setTxnNum(*sessionInfo.getTxnNumber()); newTxnRecord.setLastWriteOpTime(entry.getOpTime()); - newTxnRecord.setLastWriteDate(*entry.getWallClockTime()); + newTxnRecord.setLastWriteDate(entry.getWallClockTime()); if (entry.isPartialTransaction()) { invariant(entry.getPrevWriteOpTimeInTransaction()->isNull()); @@ -310,7 +308,7 @@ boost::optional<OplogEntry> SessionUpdateTracker::_createTransactionTableUpdateF entry.getOpTime(), updateBSON, BSON(SessionTxnRecord::kSessionIdFieldName << sessionInfo.getSessionId()->toBSON()), - *entry.getWallClockTime()); + entry.getWallClockTime()); } } // namespace repl diff --git a/src/mongo/db/repl/sync_source_resolver_test.cpp b/src/mongo/db/repl/sync_source_resolver_test.cpp index 4337f834c25..a10280c8491 100644 --- a/src/mongo/db/repl/sync_source_resolver_test.cpp +++ b/src/mongo/db/repl/sync_source_resolver_test.cpp @@ -309,7 +309,7 @@ BSONObj _makeOplogEntry(Timestamp ts, long long term) { boost::none, // o2 {}, // sessionInfo boost::none, // upsert - boost::none, // wall clock time + Date_t(), // wall clock time boost::none, // statement id boost::none, // optime of previous write within same transaction boost::none, // pre-image optime diff --git a/src/mongo/db/repl/sync_tail.cpp b/src/mongo/db/repl/sync_tail.cpp index ebbf4745f9b..a80c26d0af3 100644 --- a/src/mongo/db/repl/sync_tail.cpp +++ b/src/mongo/db/repl/sync_tail.cpp @@ -761,9 +761,8 @@ void SyncTail::_oplogApplication(ReplicationCoordinator* replCoord, auto consistency = (lastOpTimeInBatch >= minValid) ? ReplicationCoordinator::DataConsistency::Consistent : ReplicationCoordinator::DataConsistency::Inconsistent; - // Wall clock time is non-optional post 3.6. - invariant(lastWallTimeInBatch); - finalizer->record({lastOpTimeInBatch, lastWallTimeInBatch.get()}, consistency); + + finalizer->record({lastOpTimeInBatch, lastWallTimeInBatch}, consistency); } } diff --git a/src/mongo/db/repl/sync_tail_test.cpp b/src/mongo/db/repl/sync_tail_test.cpp index ea9005f4040..bd445689df9 100644 --- a/src/mongo/db/repl/sync_tail_test.cpp +++ b/src/mongo/db/repl/sync_tail_test.cpp @@ -92,7 +92,7 @@ OplogEntry makeOplogEntry(OpTypeEnum opType, NamespaceString nss, OptionalCollec boost::none, // o2 {}, // sessionInfo boost::none, // upsert - boost::none, // wall clock time + Date_t(), // wall clock time boost::none, // statement id boost::none, // optime of previous write within same transaction boost::none, // pre-image optime @@ -278,10 +278,11 @@ TEST_F(SyncTailTest, SyncApplyDeleteDocumentCollectionLockedByUUID) { TEST_F(SyncTailTest, SyncApplyCommand) { NamespaceString nss("test.t"); - auto op = BSON("op" - << "c" - << "ns" << nss.getCommandNS().ns() << "o" << BSON("create" << nss.coll()) << "ts" - << Timestamp(1, 1) << "ui" << UUID::gen()); + auto op = + BSON("op" + << "c" + << "ns" << nss.getCommandNS().ns() << "wall" << Date_t() << "o" + << BSON("create" << nss.coll()) << "ts" << Timestamp(1, 1) << "ui" << UUID::gen()); bool applyCmdCalled = false; _opObserver->onCreateCollectionFn = [&](OperationContext* opCtx, Collection*, @@ -508,7 +509,7 @@ TEST_F(MultiOplogEntrySyncTailTest, MultiApplyUnpreparedTransactionSeparate) { checkTxnTable(_lsid, _txnNum, _insertOp1->getOpTime(), - *_insertOp1->getWallClockTime(), + _insertOp1->getWallClockTime(), expectedStartOpTime, DurableTxnStateEnum::kInProgress); @@ -525,7 +526,7 @@ TEST_F(MultiOplogEntrySyncTailTest, MultiApplyUnpreparedTransactionSeparate) { checkTxnTable(_lsid, _txnNum, _insertOp1->getOpTime(), - *_insertOp1->getWallClockTime(), + _insertOp1->getWallClockTime(), expectedStartOpTime, DurableTxnStateEnum::kInProgress); @@ -539,7 +540,7 @@ TEST_F(MultiOplogEntrySyncTailTest, MultiApplyUnpreparedTransactionSeparate) { checkTxnTable(_lsid, _txnNum, _commitOp->getOpTime(), - *_commitOp->getWallClockTime(), + _commitOp->getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); } @@ -563,7 +564,7 @@ TEST_F(MultiOplogEntrySyncTailTest, MultiApplyUnpreparedTransactionAllAtOnce) { checkTxnTable(_lsid, _txnNum, _commitOp->getOpTime(), - *_commitOp->getWallClockTime(), + _commitOp->getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); } @@ -617,7 +618,7 @@ TEST_F(MultiOplogEntrySyncTailTest, MultiApplyUnpreparedTransactionTwoBatches) { checkTxnTable(_lsid, _txnNum, insertOps[0].getOpTime(), - *insertOps[0].getWallClockTime(), + insertOps[0].getWallClockTime(), expectedStartOpTime, DurableTxnStateEnum::kInProgress); @@ -631,7 +632,7 @@ TEST_F(MultiOplogEntrySyncTailTest, MultiApplyUnpreparedTransactionTwoBatches) { checkTxnTable(_lsid, _txnNum, commitOp.getOpTime(), - *commitOp.getWallClockTime(), + commitOp.getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); @@ -738,7 +739,7 @@ TEST_F(MultiOplogEntrySyncTailTest, MultiApplyTwoTransactionsOneBatch) { checkTxnTable(_lsid, txnNum2, commitOp2.getOpTime(), - *commitOp2.getWallClockTime(), + commitOp2.getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); @@ -843,7 +844,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, MultiApplyPreparedTransactionStea checkTxnTable(_lsid, _txnNum, _insertOp1->getOpTime(), - *_insertOp1->getWallClockTime(), + _insertOp1->getWallClockTime(), expectedStartOpTime, DurableTxnStateEnum::kInProgress); @@ -858,7 +859,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, MultiApplyPreparedTransactionStea checkTxnTable(_lsid, _txnNum, _prepareWithPrevOp->getOpTime(), - *_prepareWithPrevOp->getWallClockTime(), + _prepareWithPrevOp->getWallClockTime(), expectedStartOpTime, DurableTxnStateEnum::kPrepared); @@ -871,7 +872,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, MultiApplyPreparedTransactionStea checkTxnTable(_lsid, _txnNum, _commitPrepareWithPrevOp->getOpTime(), - *_commitPrepareWithPrevOp->getWallClockTime(), + _commitPrepareWithPrevOp->getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); } @@ -892,7 +893,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, MultiApplyAbortPreparedTransactio checkTxnTable(_lsid, _txnNum, _insertOp1->getOpTime(), - *_insertOp1->getWallClockTime(), + _insertOp1->getWallClockTime(), expectedStartOpTime, DurableTxnStateEnum::kInProgress); @@ -903,7 +904,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, MultiApplyAbortPreparedTransactio checkTxnTable(_lsid, _txnNum, _prepareWithPrevOp->getOpTime(), - *_prepareWithPrevOp->getWallClockTime(), + _prepareWithPrevOp->getWallClockTime(), expectedStartOpTime, DurableTxnStateEnum::kPrepared); @@ -916,7 +917,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, MultiApplyAbortPreparedTransactio checkTxnTable(_lsid, _txnNum, _abortPrepareWithPrevOp->getOpTime(), - *_abortPrepareWithPrevOp->getWallClockTime(), + _abortPrepareWithPrevOp->getWallClockTime(), boost::none, DurableTxnStateEnum::kAborted); } @@ -942,7 +943,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, MultiApplyPreparedTransactionInit checkTxnTable(_lsid, _txnNum, _insertOp1->getOpTime(), - *_insertOp1->getWallClockTime(), + _insertOp1->getWallClockTime(), expectedStartOpTime, DurableTxnStateEnum::kInProgress); @@ -956,7 +957,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, MultiApplyPreparedTransactionInit checkTxnTable(_lsid, _txnNum, _prepareWithPrevOp->getOpTime(), - *_prepareWithPrevOp->getWallClockTime(), + _prepareWithPrevOp->getWallClockTime(), expectedStartOpTime, DurableTxnStateEnum::kPrepared); @@ -969,7 +970,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, MultiApplyPreparedTransactionInit checkTxnTable(_lsid, _txnNum, _commitPrepareWithPrevOp->getOpTime(), - *_commitPrepareWithPrevOp->getWallClockTime(), + _commitPrepareWithPrevOp->getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); } @@ -1004,7 +1005,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, MultiApplyPreparedTransactionReco checkTxnTable(_lsid, _txnNum, _insertOp1->getOpTime(), - *_insertOp1->getWallClockTime(), + _insertOp1->getWallClockTime(), expectedStartOpTime, DurableTxnStateEnum::kInProgress); @@ -1017,7 +1018,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, MultiApplyPreparedTransactionReco checkTxnTable(_lsid, _txnNum, _prepareWithPrevOp->getOpTime(), - *_prepareWithPrevOp->getWallClockTime(), + _prepareWithPrevOp->getWallClockTime(), expectedStartOpTime, DurableTxnStateEnum::kPrepared); @@ -1030,7 +1031,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, MultiApplyPreparedTransactionReco checkTxnTable(_lsid, _txnNum, _commitPrepareWithPrevOp->getOpTime(), - *_commitPrepareWithPrevOp->getWallClockTime(), + _commitPrepareWithPrevOp->getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); } @@ -1054,7 +1055,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, MultiApplySingleApplyOpsPreparedT checkTxnTable(_lsid, _txnNum, _singlePrepareApplyOp->getOpTime(), - *_singlePrepareApplyOp->getWallClockTime(), + _singlePrepareApplyOp->getWallClockTime(), expectedStartOpTime, DurableTxnStateEnum::kPrepared); @@ -1067,7 +1068,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, MultiApplySingleApplyOpsPreparedT checkTxnTable(_lsid, _txnNum, _commitSinglePrepareApplyOp->getOpTime(), - *_commitSinglePrepareApplyOp->getWallClockTime(), + _commitSinglePrepareApplyOp->getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); } @@ -1099,7 +1100,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, MultiApplyEmptyApplyOpsPreparedTr checkTxnTable(_lsid, _txnNum, emptyPrepareApplyOp.getOpTime(), - *emptyPrepareApplyOp.getWallClockTime(), + emptyPrepareApplyOp.getWallClockTime(), expectedStartOpTime, DurableTxnStateEnum::kPrepared); @@ -1112,7 +1113,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, MultiApplyEmptyApplyOpsPreparedTr checkTxnTable(_lsid, _txnNum, _commitSinglePrepareApplyOp->getOpTime(), - *_commitSinglePrepareApplyOp->getWallClockTime(), + _commitSinglePrepareApplyOp->getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); } @@ -1132,7 +1133,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, MultiApplyAbortSingleApplyOpsPrep checkTxnTable(_lsid, _txnNum, _singlePrepareApplyOp->getOpTime(), - *_singlePrepareApplyOp->getWallClockTime(), + _singlePrepareApplyOp->getWallClockTime(), expectedStartOpTime, DurableTxnStateEnum::kPrepared); @@ -1145,7 +1146,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, MultiApplyAbortSingleApplyOpsPrep checkTxnTable(_lsid, _txnNum, _abortSinglePrepareApplyOp->getOpTime(), - *_abortSinglePrepareApplyOp->getWallClockTime(), + _abortSinglePrepareApplyOp->getWallClockTime(), boost::none, DurableTxnStateEnum::kAborted); } @@ -1171,7 +1172,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, checkTxnTable(_lsid, _txnNum, _singlePrepareApplyOp->getOpTime(), - *_singlePrepareApplyOp->getWallClockTime(), + _singlePrepareApplyOp->getWallClockTime(), expectedStartOpTime, DurableTxnStateEnum::kPrepared); @@ -1184,7 +1185,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, checkTxnTable(_lsid, _txnNum, _commitSinglePrepareApplyOp->getOpTime(), - *_commitSinglePrepareApplyOp->getWallClockTime(), + _commitSinglePrepareApplyOp->getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); } @@ -1220,7 +1221,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, checkTxnTable(_lsid, _txnNum, _singlePrepareApplyOp->getOpTime(), - *_singlePrepareApplyOp->getWallClockTime(), + _singlePrepareApplyOp->getWallClockTime(), expectedStartOpTime, DurableTxnStateEnum::kPrepared); @@ -1233,7 +1234,7 @@ TEST_F(MultiOplogEntryPreparedTransactionTest, checkTxnTable(_lsid, _txnNum, _commitSinglePrepareApplyOp->getOpTime(), - *_commitSinglePrepareApplyOp->getWallClockTime(), + _commitSinglePrepareApplyOp->getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); } @@ -2202,7 +2203,8 @@ TEST_F(SyncTailTest, LogSlowOpApplicationWhenSuccessful) { // Use a builder for easier escaping. We expect the operation to be logged. StringBuilder expected; - expected << "applied op: CRUD { ts: Timestamp(1, 1), t: 1, v: 2, op: \"i\", ns: \"test.t\", o: " + expected << "applied op: CRUD { ts: Timestamp(1, 1), t: 1, v: 2, op: \"i\", ns: \"test.t\", " + "wall: new Date(0), o: " "{ _id: 0 } }, took " << applyDuration << "ms"; ASSERT_EQUALS(1, countLogLinesContaining(expected.str())); @@ -2554,7 +2556,7 @@ TEST_F(SyncTailTxnTableTest, RetryableWriteThenMultiStatementTxnWriteOnSameSessi *sessionInfo.getSessionId(), *sessionInfo.getTxnNumber(), txnCommitOpTime, - *txnCommitOp.getWallClockTime(), + txnCommitOp.getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); } @@ -2619,7 +2621,7 @@ TEST_F(SyncTailTxnTableTest, MultiStatementTxnWriteThenRetryableWriteOnSameSessi *sessionInfo.getSessionId(), *sessionInfo.getTxnNumber(), retryableInsertOpTime, - *retryableInsertOp.getWallClockTime(), + retryableInsertOp.getWallClockTime(), boost::none, boost::none); } @@ -2879,7 +2881,7 @@ TEST_F(IdempotencyTestTxns, CommitUnpreparedTransaction) { lsid, txnNum, commitOp.getOpTime(), - *commitOp.getWallClockTime(), + commitOp.getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); ASSERT_TRUE(docExists(_opCtx.get(), nss, doc)); @@ -2917,7 +2919,7 @@ TEST_F(IdempotencyTestTxns, CommitUnpreparedTransactionDataPartiallyApplied) { lsid, txnNum, commitOp.getOpTime(), - *commitOp.getWallClockTime(), + commitOp.getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); ASSERT_TRUE(docExists(_opCtx.get(), nss, doc)); @@ -2943,7 +2945,7 @@ TEST_F(IdempotencyTestTxns, CommitPreparedTransaction) { lsid, txnNum, commitOp.getOpTime(), - *commitOp.getWallClockTime(), + commitOp.getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); ASSERT_TRUE(docExists(_opCtx.get(), nss, doc)); @@ -2983,7 +2985,7 @@ TEST_F(IdempotencyTestTxns, CommitPreparedTransactionDataPartiallyApplied) { lsid, txnNum, commitOp.getOpTime(), - *commitOp.getWallClockTime(), + commitOp.getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); ASSERT_TRUE(docExists(_opCtx.get(), nss, doc)); @@ -3008,7 +3010,7 @@ TEST_F(IdempotencyTestTxns, AbortPreparedTransaction) { lsid, txnNum, abortOp.getOpTime(), - *abortOp.getWallClockTime(), + abortOp.getWallClockTime(), boost::none, DurableTxnStateEnum::kAborted); ASSERT_FALSE(docExists(_opCtx.get(), nss, doc)); @@ -3032,7 +3034,7 @@ TEST_F(IdempotencyTestTxns, SinglePartialTxnOp) { lsid, txnNum, partialOp.getOpTime(), - *partialOp.getWallClockTime(), + partialOp.getWallClockTime(), expectedStartOpTime, DurableTxnStateEnum::kInProgress); @@ -3062,7 +3064,7 @@ TEST_F(IdempotencyTestTxns, MultiplePartialTxnOps) { lsid, txnNum, partialOp1.getOpTime(), - *partialOp1.getWallClockTime(), + partialOp1.getWallClockTime(), expectedStartOpTime, DurableTxnStateEnum::kInProgress); // Document should not be visible yet. @@ -3093,7 +3095,7 @@ TEST_F(IdempotencyTestTxns, CommitUnpreparedTransactionWithPartialTxnOps) { lsid, txnNum, commitOp.getOpTime(), - *commitOp.getWallClockTime(), + commitOp.getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); ASSERT_TRUE(docExists(_opCtx.get(), nss, doc)); @@ -3132,7 +3134,7 @@ TEST_F(IdempotencyTestTxns, CommitTwoUnpreparedTransactionsWithPartialTxnOpsAtOn lsid, txnNum2, commitOp2.getOpTime(), - *commitOp2.getWallClockTime(), + commitOp2.getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); ASSERT_TRUE(docExists(_opCtx.get(), nss, doc)); @@ -3170,7 +3172,7 @@ TEST_F(IdempotencyTestTxns, CommitAndAbortTwoTransactionsWithPartialTxnOpsAtOnce lsid, txnNum2, commitOp2.getOpTime(), - *commitOp2.getWallClockTime(), + commitOp2.getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); ASSERT_FALSE(docExists(_opCtx.get(), nss, doc)); @@ -3209,7 +3211,7 @@ TEST_F(IdempotencyTestTxns, CommitUnpreparedTransactionWithPartialTxnOpsAndDataP lsid, txnNum, commitOp.getOpTime(), - *commitOp.getWallClockTime(), + commitOp.getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); ASSERT_TRUE(docExists(_opCtx.get(), nss, doc)); @@ -3238,7 +3240,7 @@ TEST_F(IdempotencyTestTxns, PrepareTransactionWithPartialTxnOps) { lsid, txnNum, prepareOp.getOpTime(), - *prepareOp.getWallClockTime(), + prepareOp.getWallClockTime(), partialOp.getOpTime(), DurableTxnStateEnum::kPrepared); // Document should not be visible yet. @@ -3261,7 +3263,7 @@ TEST_F(IdempotencyTestTxns, EmptyPrepareTransaction) { lsid, txnNum, prepareOp.getOpTime(), - *prepareOp.getWallClockTime(), + prepareOp.getWallClockTime(), prepareOp.getOpTime(), DurableTxnStateEnum::kPrepared); } @@ -3289,7 +3291,7 @@ TEST_F(IdempotencyTestTxns, CommitPreparedTransactionWithPartialTxnOps) { lsid, txnNum, commitOp.getOpTime(), - *commitOp.getWallClockTime(), + commitOp.getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); ASSERT_TRUE(docExists(_opCtx.get(), nss, doc)); @@ -3328,7 +3330,7 @@ TEST_F(IdempotencyTestTxns, CommitTwoPreparedTransactionsWithPartialTxnOpsAtOnce lsid, txnNum2, commitOp2.getOpTime(), - *commitOp2.getWallClockTime(), + commitOp2.getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); ASSERT_TRUE(docExists(_opCtx.get(), nss, doc)); @@ -3367,7 +3369,7 @@ TEST_F(IdempotencyTestTxns, CommitPreparedTransactionWithPartialTxnOpsAndDataPar lsid, txnNum, commitOp.getOpTime(), - *commitOp.getWallClockTime(), + commitOp.getWallClockTime(), boost::none, DurableTxnStateEnum::kCommitted); ASSERT_TRUE(docExists(_opCtx.get(), nss, doc)); @@ -3397,7 +3399,7 @@ TEST_F(IdempotencyTestTxns, AbortPreparedTransactionWithPartialTxnOps) { lsid, txnNum, abortOp.getOpTime(), - *abortOp.getWallClockTime(), + abortOp.getWallClockTime(), boost::none, DurableTxnStateEnum::kAborted); ASSERT_FALSE(docExists(_opCtx.get(), nss, doc)); @@ -3422,7 +3424,7 @@ TEST_F(IdempotencyTestTxns, AbortInProgressTransaction) { lsid, txnNum, abortOp.getOpTime(), - *abortOp.getWallClockTime(), + abortOp.getWallClockTime(), boost::none, DurableTxnStateEnum::kAborted); ASSERT_FALSE(docExists(_opCtx.get(), nss, doc)); diff --git a/src/mongo/db/s/session_catalog_migration_destination.cpp b/src/mongo/db/s/session_catalog_migration_destination.cpp index 18e16428f63..ea24c80f7e3 100644 --- a/src/mongo/db/s/session_catalog_migration_destination.cpp +++ b/src/mongo/db/s/session_catalog_migration_destination.cpp @@ -126,10 +126,6 @@ void setPrePostImageTs(const ProcessOplogResult& lastResult, repl::MutableOplogE repl::MutableOplogEntry parseOplog(const BSONObj& oplogBSON) { auto oplogEntry = uassertStatusOK(repl::MutableOplogEntry::parse(oplogBSON)); - // Session oplog entries must always contain wall clock time, because we will not be - // transferring anything from a previous version of the server - invariant(oplogEntry.getWallClockTime()); - const auto& sessionInfo = oplogEntry.getOperationSessionInfo(); uassert(ErrorCodes::UnsupportedFormat, @@ -292,7 +288,7 @@ ProcessOplogResult processSessionOplog(const BSONObj& oplogBSON, sessionTxnRecord.setSessionId(result.sessionId); sessionTxnRecord.setTxnNum(result.txnNum); sessionTxnRecord.setLastWriteOpTime(oplogOpTime); - sessionTxnRecord.setLastWriteDate(*oplogEntry.getWallClockTime()); + sessionTxnRecord.setLastWriteDate(oplogEntry.getWallClockTime()); // We do not migrate transaction oplog entries so don't set the txn state. txnParticipant.onMigrateCompletedOnPrimary(opCtx, {stmtId}, sessionTxnRecord); } diff --git a/src/mongo/db/s/session_catalog_migration_destination_test.cpp b/src/mongo/db/s/session_catalog_migration_destination_test.cpp index 9305b610070..bf0f3dbf976 100644 --- a/src/mongo/db/s/session_catalog_migration_destination_test.cpp +++ b/src/mongo/db/s/session_catalog_migration_destination_test.cpp @@ -87,7 +87,7 @@ repl::OplogEntry makeOplogEntry(repl::OpTime opTime, BSONObj object, boost::optional<BSONObj> object2, OperationSessionInfo sessionInfo, - boost::optional<Date_t> wallClockTime, + Date_t wallClockTime, boost::optional<StmtId> stmtId, boost::optional<repl::OpTime> preImageOpTime = boost::none, boost::optional<repl::OpTime> postImageOpTime = boost::none) { @@ -596,7 +596,7 @@ TEST_F(SessionCatalogMigrationDestinationTest, ShouldNotNestAlreadyNestedOplog) BSON("x" << 100), // o boost::none, // o2 sessionInfo, // session info - boost::none, // wall clock time + Date_t(), // wall clock time 23); // statement id auto origInnerOplog2 = makeOplogEntry(OpTime(Timestamp(80, 2), 1), // optime @@ -604,7 +604,7 @@ TEST_F(SessionCatalogMigrationDestinationTest, ShouldNotNestAlreadyNestedOplog) BSON("x" << 80), // o boost::none, // o2 sessionInfo, // session info - boost::none, // wall clock time + Date_t(), // wall clock time 45); // statement id auto oplog1 = makeOplogEntry(OpTime(Timestamp(1100, 2), 1), // optime diff --git a/src/mongo/db/s/session_catalog_migration_source_test.cpp b/src/mongo/db/s/session_catalog_migration_source_test.cpp index 3d87181a6bf..5773559a5ea 100644 --- a/src/mongo/db/s/session_catalog_migration_source_test.cpp +++ b/src/mongo/db/s/session_catalog_migration_source_test.cpp @@ -59,7 +59,7 @@ repl::OplogEntry makeOplogEntry(repl::OpTime opTime, NamespaceString nss, BSONObj object, boost::optional<BSONObj> object2, - boost::optional<Date_t> wallClockTime, + Date_t wallClockTime, StmtId stmtId, repl::OpTime prevWriteOpTimeInTransaction, boost::optional<repl::OpTime> preImageOpTime, @@ -87,7 +87,7 @@ repl::OplogEntry makeOplogEntry(repl::OpTime opTime, repl::OpTypeEnum opType, BSONObj object, boost::optional<BSONObj> object2, - boost::optional<Date_t> wallClockTime, + Date_t wallClockTime, StmtId stmtId, repl::OpTime prevWriteOpTimeInTransaction, boost::optional<repl::OpTime> preImageOpTime = boost::none, @@ -135,7 +135,7 @@ TEST_F(SessionCatalogMigrationSourceTest, OneSessionWithTwoWrites) { sessionRecord.setSessionId(makeLogicalSessionIdForTest()); sessionRecord.setTxnNum(1); sessionRecord.setLastWriteOpTime(entry2.getOpTime()); - sessionRecord.setLastWriteDate(*entry2.getWallClockTime()); + sessionRecord.setLastWriteDate(entry2.getWallClockTime()); DBDirectClient client(opCtx()); client.insert(NamespaceString::kSessionTransactionsTableNamespace.ns(), sessionRecord.toBSON()); @@ -187,7 +187,7 @@ TEST_F(SessionCatalogMigrationSourceTest, TwoSessionWithTwoWrites) { sessionRecord1.setSessionId(makeLogicalSessionIdForTest()); sessionRecord1.setTxnNum(1); sessionRecord1.setLastWriteOpTime(entry1b.getOpTime()); - sessionRecord1.setLastWriteDate(*entry1b.getWallClockTime()); + sessionRecord1.setLastWriteDate(entry1b.getWallClockTime()); DBDirectClient client(opCtx()); client.insert(NamespaceString::kSessionTransactionsTableNamespace.ns(), @@ -215,7 +215,7 @@ TEST_F(SessionCatalogMigrationSourceTest, TwoSessionWithTwoWrites) { sessionRecord2.setSessionId(makeLogicalSessionIdForTest()); sessionRecord2.setTxnNum(1); sessionRecord2.setLastWriteOpTime(entry2b.getOpTime()); - sessionRecord2.setLastWriteDate(*entry2b.getWallClockTime()); + sessionRecord2.setLastWriteDate(entry2b.getWallClockTime()); client.insert(NamespaceString::kSessionTransactionsTableNamespace.ns(), sessionRecord2.toBSON()); @@ -316,7 +316,7 @@ TEST_F(SessionCatalogMigrationSourceTest, OneSessionWithFindAndModifyPreImageAnd sessionRecord.setSessionId(makeLogicalSessionIdForTest()); sessionRecord.setTxnNum(1); sessionRecord.setLastWriteOpTime(entry4.getOpTime()); - sessionRecord.setLastWriteDate(*entry4.getWallClockTime()); + sessionRecord.setLastWriteDate(entry4.getWallClockTime()); DBDirectClient client(opCtx()); client.insert(NamespaceString::kSessionTransactionsTableNamespace.ns(), sessionRecord.toBSON()); @@ -353,7 +353,7 @@ TEST_F(SessionCatalogMigrationSourceTest, OplogWithOtherNsShouldBeIgnored) { sessionRecord1.setSessionId(makeLogicalSessionIdForTest()); sessionRecord1.setTxnNum(1); sessionRecord1.setLastWriteOpTime(entry1.getOpTime()); - sessionRecord1.setLastWriteDate(*entry1.getWallClockTime()); + sessionRecord1.setLastWriteDate(entry1.getWallClockTime()); DBDirectClient client(opCtx()); client.insert(NamespaceString::kSessionTransactionsTableNamespace.ns(), @@ -377,7 +377,7 @@ TEST_F(SessionCatalogMigrationSourceTest, OplogWithOtherNsShouldBeIgnored) { sessionRecord2.setSessionId(makeLogicalSessionIdForTest()); sessionRecord2.setTxnNum(1); sessionRecord2.setLastWriteOpTime(entry2.getOpTime()); - sessionRecord2.setLastWriteDate(*entry2.getWallClockTime()); + sessionRecord2.setLastWriteDate(entry2.getWallClockTime()); client.insert(NamespaceString::kSessionTransactionsTableNamespace.ns(), sessionRecord2.toBSON()); @@ -411,7 +411,7 @@ TEST_F(SessionCatalogMigrationSourceTest, SessionDumpWithMultipleNewWrites) { sessionRecord1.setSessionId(makeLogicalSessionIdForTest()); sessionRecord1.setTxnNum(1); sessionRecord1.setLastWriteOpTime(entry1.getOpTime()); - sessionRecord1.setLastWriteDate(*entry1.getWallClockTime()); + sessionRecord1.setLastWriteDate(entry1.getWallClockTime()); DBDirectClient client(opCtx()); client.insert(NamespaceString::kSessionTransactionsTableNamespace.ns(), @@ -579,7 +579,7 @@ TEST_F(SessionCatalogMigrationSourceTest, ReturnsDeadEndSentinelForIncompleteHis sessionRecord.setSessionId(sessionId); sessionRecord.setTxnNum(31); sessionRecord.setLastWriteOpTime(entry.getOpTime()); - sessionRecord.setLastWriteDate(*entry.getWallClockTime()); + sessionRecord.setLastWriteDate(entry.getWallClockTime()); DBDirectClient client(opCtx()); client.insert(NamespaceString::kSessionTransactionsTableNamespace.ns(), sessionRecord.toBSON()); @@ -606,8 +606,7 @@ TEST_F(SessionCatalogMigrationSourceTest, ReturnsDeadEndSentinelForIncompleteHis ASSERT_BSONOBJ_EQ(TransactionParticipant::kDeadEndSentinel, *oplog.getObject2()); ASSERT_TRUE(oplog.getStatementId()); ASSERT_EQ(kIncompleteHistoryStmtId, *oplog.getStatementId()); - ASSERT_TRUE(oplog.getWallClockTime()); - ASSERT_NE(Date_t{}, *oplog.getWallClockTime()); + ASSERT_NE(Date_t{}, oplog.getWallClockTime()); auto sessionInfo = oplog.getOperationSessionInfo(); ASSERT_TRUE(sessionInfo.getSessionId()); @@ -637,7 +636,7 @@ TEST_F(SessionCatalogMigrationSourceTest, ShouldAssertWhenRollbackDetected) { sessionRecord.setSessionId(sessionId); sessionRecord.setTxnNum(31); sessionRecord.setLastWriteOpTime(entry.getOpTime()); - sessionRecord.setLastWriteDate(*entry.getWallClockTime()); + sessionRecord.setLastWriteDate(entry.getWallClockTime()); DBDirectClient client(opCtx()); client.insert(NamespaceString::kSessionTransactionsTableNamespace.ns(), sessionRecord.toBSON()); @@ -762,7 +761,7 @@ TEST_F(SessionCatalogMigrationSourceTest, retryableWriteRecord.setSessionId(makeLogicalSessionIdForTest()); retryableWriteRecord.setTxnNum(1); retryableWriteRecord.setLastWriteOpTime(insertOplog.getOpTime()); - retryableWriteRecord.setLastWriteDate(*insertOplog.getWallClockTime()); + retryableWriteRecord.setLastWriteDate(insertOplog.getWallClockTime()); // Create a config.transaction entry pointing to an imaginary commitTransaction entry. SessionTxnRecord txnRecord; @@ -847,7 +846,7 @@ TEST_F(SessionCatalogMigrationSourceTest, FindAndModifyDeleteNotTouchingChunkIsI sessionRecord.setSessionId(makeLogicalSessionIdForTest()); sessionRecord.setTxnNum(1); sessionRecord.setLastWriteOpTime(entry2.getOpTime()); - sessionRecord.setLastWriteDate(*entry2.getWallClockTime()); + sessionRecord.setLastWriteDate(entry2.getWallClockTime()); DBDirectClient client(opCtx()); client.insert(NamespaceString::kSessionTransactionsTableNamespace.ns(), sessionRecord.toBSON()); @@ -882,7 +881,7 @@ TEST_F(SessionCatalogMigrationSourceTest, FindAndModifyUpdatePrePostNotTouchingC sessionRecord.setSessionId(makeLogicalSessionIdForTest()); sessionRecord.setTxnNum(1); sessionRecord.setLastWriteOpTime(entry2.getOpTime()); - sessionRecord.setLastWriteDate(*entry2.getWallClockTime()); + sessionRecord.setLastWriteDate(entry2.getWallClockTime()); DBDirectClient client(opCtx()); client.insert(NamespaceString::kSessionTransactionsTableNamespace.ns(), sessionRecord.toBSON()); @@ -919,7 +918,7 @@ TEST_F(SessionCatalogMigrationSourceTest, sessionRecord.setSessionId(makeLogicalSessionIdForTest()); sessionRecord.setTxnNum(1); sessionRecord.setLastWriteOpTime(entry2.getOpTime()); - sessionRecord.setLastWriteDate(*entry2.getWallClockTime()); + sessionRecord.setLastWriteDate(entry2.getWallClockTime()); DBDirectClient client(opCtx()); client.insert(NamespaceString::kSessionTransactionsTableNamespace.ns(), sessionRecord.toBSON()); @@ -969,7 +968,7 @@ TEST_F(SessionCatalogMigrationSourceTest, sessionRecord.setSessionId(makeLogicalSessionIdForTest()); sessionRecord.setTxnNum(1); sessionRecord.setLastWriteOpTime(entry2.getOpTime()); - sessionRecord.setLastWriteDate(*entry2.getWallClockTime()); + sessionRecord.setLastWriteDate(entry2.getWallClockTime()); DBDirectClient client(opCtx()); client.insert(NamespaceString::kSessionTransactionsTableNamespace.ns(), sessionRecord.toBSON()); @@ -1005,7 +1004,7 @@ TEST_F(SessionCatalogMigrationSourceTest, FindAndModifyUpdateNotTouchingChunkSho sessionRecord.setSessionId(makeLogicalSessionIdForTest()); sessionRecord.setTxnNum(1); sessionRecord.setLastWriteOpTime(entry2.getOpTime()); - sessionRecord.setLastWriteDate(*entry2.getWallClockTime()); + sessionRecord.setLastWriteDate(entry2.getWallClockTime()); DBDirectClient client(opCtx()); client.insert(NamespaceString::kSessionTransactionsTableNamespace.ns(), sessionRecord.toBSON()); @@ -1044,7 +1043,7 @@ TEST_F(SessionCatalogMigrationSourceTest, TwoSessionWithTwoWritesContainingWrite sessionRecord1.setSessionId(higherSessionId); sessionRecord1.setTxnNum(1); sessionRecord1.setLastWriteOpTime(entry1b.getOpTime()); - sessionRecord1.setLastWriteDate(*entry1b.getWallClockTime()); + sessionRecord1.setLastWriteDate(entry1b.getWallClockTime()); DBDirectClient client(opCtx()); client.insert(NamespaceString::kSessionTransactionsTableNamespace.ns(), @@ -1072,7 +1071,7 @@ TEST_F(SessionCatalogMigrationSourceTest, TwoSessionWithTwoWritesContainingWrite sessionRecord2.setSessionId(lowerSessionId); sessionRecord2.setTxnNum(1); sessionRecord2.setLastWriteOpTime(entry2b.getOpTime()); - sessionRecord2.setLastWriteDate(*entry2b.getWallClockTime()); + sessionRecord2.setLastWriteDate(entry2b.getWallClockTime()); client.insert(NamespaceString::kSessionTransactionsTableNamespace.ns(), sessionRecord2.toBSON()); diff --git a/src/mongo/db/transaction_history_iterator_test.cpp b/src/mongo/db/transaction_history_iterator_test.cpp index 50f8a51192d..e57c1d1e7ca 100644 --- a/src/mongo/db/transaction_history_iterator_test.cpp +++ b/src/mongo/db/transaction_history_iterator_test.cpp @@ -72,7 +72,7 @@ repl::OplogEntry makeOplogEntry(repl::OpTime opTime, boost::none, // o2 {}, // sessionInfo boost::none, // upsert - boost::none, // wall clock time + Date_t(), // wall clock time boost::none, // statement id prevWriteOpTimeInTransaction, // optime of previous write within same transaction boost::none, // pre-image optime diff --git a/src/mongo/db/transaction_participant_retryable_writes_test.cpp b/src/mongo/db/transaction_participant_retryable_writes_test.cpp index 7203a1c1ddf..a9ffbfaf35c 100644 --- a/src/mongo/db/transaction_participant_retryable_writes_test.cpp +++ b/src/mongo/db/transaction_participant_retryable_writes_test.cpp @@ -64,7 +64,7 @@ repl::OplogEntry makeOplogEntry(repl::OpTime opTime, repl::OpTypeEnum opType, BSONObj object, OperationSessionInfo sessionInfo, - boost::optional<Date_t> wallClockTime, + Date_t wallClockTime, boost::optional<StmtId> stmtId, boost::optional<repl::OpTime> prevWriteOpTimeInTransaction) { return repl::OplogEntry( @@ -554,7 +554,7 @@ TEST_F(TransactionParticipantRetryableWritesTest, IncompleteHistoryDueToOpLogTru sessionRecord.setSessionId(sessionId); sessionRecord.setTxnNum(txnNum); sessionRecord.setLastWriteOpTime(entry2.getOpTime()); - sessionRecord.setLastWriteDate(*entry2.getWallClockTime()); + sessionRecord.setLastWriteDate(entry2.getWallClockTime()); return sessionRecord.toBSON(); }()); } diff --git a/src/mongo/db/transaction_participant_test.cpp b/src/mongo/db/transaction_participant_test.cpp index 88bec24896e..c80293146ad 100644 --- a/src/mongo/db/transaction_participant_test.cpp +++ b/src/mongo/db/transaction_participant_test.cpp @@ -72,7 +72,7 @@ repl::OplogEntry makeOplogEntry(repl::OpTime opTime, repl::OpTypeEnum opType, BSONObj object, OperationSessionInfo sessionInfo, - boost::optional<Date_t> wallClockTime, + Date_t wallClockTime, boost::optional<StmtId> stmtId, boost::optional<repl::OpTime> prevWriteOpTimeInTransaction) { return repl::OplogEntry( diff --git a/src/mongo/dbtests/repltests.cpp b/src/mongo/dbtests/repltests.cpp index 51eb8702c3d..f91068cfabb 100644 --- a/src/mongo/dbtests/repltests.cpp +++ b/src/mongo/dbtests/repltests.cpp @@ -80,7 +80,7 @@ repl::OplogEntry makeOplogEntry(repl::OpTime opTime, object2, // o2 {}, // sessionInfo boost::none, // upsert - boost::none, // wall clock time + Date_t(), // wall clock time boost::none, // statement id boost::none, // optime of previous write within same transaction boost::none, // pre-image optime diff --git a/src/mongo/dbtests/storage_timestamp_tests.cpp b/src/mongo/dbtests/storage_timestamp_tests.cpp index 23d66829265..2c81636f857 100644 --- a/src/mongo/dbtests/storage_timestamp_tests.cpp +++ b/src/mongo/dbtests/storage_timestamp_tests.cpp @@ -712,13 +712,14 @@ public: << "v" << 2 << "op" << "i" << "ns" << nss.ns() << "ui" << autoColl.getCollection()->uuid() - << "o" << BSON("_id" << idx)) + << "wall" << Date_t() << "o" << BSON("_id" << idx)) << BSON("ts" << firstInsertTime.addTicks(idx).asTimestamp() << "t" << 1LL << "op" << "c" << "ns" << "test.$cmd" - << "o" << BSON("applyOps" << BSONArrayBuilder().obj())))), + << "wall" << Date_t() << "o" + << BSON("applyOps" << BSONArrayBuilder().obj())))), repl::OplogApplication::Mode::kApplyOpsCmd, &result)); } @@ -752,7 +753,8 @@ public: BSONObjBuilder oplogCommonBuilder; oplogCommonBuilder << "v" << 2 << "op" << "i" - << "ns" << nss.ns() << "ui" << autoColl.getCollection()->uuid(); + << "ns" << nss.ns() << "ui" << autoColl.getCollection()->uuid() << "wall" + << Date_t(); auto oplogCommon = oplogCommonBuilder.done(); std::vector<repl::OplogEntry> oplogEntries; @@ -767,6 +769,8 @@ public: oplogEntryBuilders[idx] << "t" << 1LL; // Populate the "o" field. oplogEntryBuilders[idx] << "o" << o; + // Populate the "wall" field + oplogEntryBuilders[idx] << "wall" << Date_t(); // Populate the other common fields. oplogEntryBuilders[idx].appendElementsUnique(oplogCommon); // Insert ops to be applied. @@ -824,7 +828,7 @@ public: << "v" << 2 << "op" << "d" << "ns" << nss.ns() << "ui" << autoColl.getCollection()->uuid() - << "o" << BSON("_id" << num))}) + << "wall" << Date_t() << "o" << BSON("_id" << num))}) .getStatus()); } @@ -883,7 +887,8 @@ public: << "v" << 2 << "op" << "u" << "ns" << nss.ns() << "ui" << autoColl.getCollection()->uuid() - << "o2" << BSON("_id" << 0) << "o" << updates[idx].first)}) + << "wall" << Date_t() << "o2" << BSON("_id" << 0) << "o" + << updates[idx].first)}) .getStatus()); } @@ -921,12 +926,12 @@ public: nss.db().toString(), {BSON("ts" << insertTime.asTimestamp() << "t" << 1LL << "op" << "i" - << "ns" << nss.ns() << "ui" << autoColl.getCollection()->uuid() << "o" - << BSON("_id" << 0 << "field" << 0)), + << "ns" << nss.ns() << "ui" << autoColl.getCollection()->uuid() << "wall" + << Date_t() << "o" << BSON("_id" << 0 << "field" << 0)), BSON("ts" << insertTime.addTicks(1).asTimestamp() << "t" << 1LL << "op" << "i" - << "ns" << nss.ns() << "ui" << autoColl.getCollection()->uuid() << "o" - << BSON("_id" << 0))})); + << "ns" << nss.ns() << "ui" << autoColl.getCollection()->uuid() << "wall" + << Date_t() << "o" << BSON("_id" << 0))})); ASSERT_EQ(2, result.getIntField("applied")); ASSERT(result["results"].Array()[0].Bool()); @@ -1068,8 +1073,8 @@ public: { BSON("ts" << presentTs << "t" << 1LL << "op" << "c" - << "ui" << UUID::gen() << "ns" << nss.getCommandNS().ns() << "o" - << BSON("create" << nss.coll())), + << "ui" << UUID::gen() << "ns" << nss.getCommandNS().ns() << "wall" + << Date_t() << "o" << BSON("create" << nss.coll())), }); ASSERT_OK(swResult); @@ -1106,12 +1111,12 @@ public: { BSON("ts" << presentTs << "t" << 1LL << "op" << "c" - << "ui" << UUID::gen() << "ns" << nss1.getCommandNS().ns() << "o" - << BSON("create" << nss1.coll())), + << "ui" << UUID::gen() << "ns" << nss1.getCommandNS().ns() << "wall" + << Date_t() << "o" << BSON("create" << nss1.coll())), BSON("ts" << futureTs << "t" << 1LL << "op" << "c" - << "ui" << UUID::gen() << "ns" << nss2.getCommandNS().ns() << "o" - << BSON("create" << nss2.coll())), + << "ui" << UUID::gen() << "ns" << nss2.getCommandNS().ns() << "wall" + << Date_t() << "o" << BSON("create" << nss2.coll())), }); ASSERT_OK(swResult); @@ -1166,14 +1171,15 @@ public: BSON("ts" << presentTs << "t" << 1LL << "op" << "i" << "ns" << nss1.ns() << "ui" << autoColl.getCollection()->uuid() - << "o" << doc1), + << "wall" << Date_t() << "o" << doc1), BSON("ts" << futureTs << "t" << 1LL << "op" << "c" - << "ui" << uuid2 << "ns" << nss2.getCommandNS().ns() << "o" - << BSON("create" << nss2.coll())), + << "ui" << uuid2 << "ns" << nss2.getCommandNS().ns() << "wall" + << Date_t() << "o" << BSON("create" << nss2.coll())), BSON("ts" << insert2Ts << "t" << 1LL << "op" << "i" - << "ns" << nss2.ns() << "ui" << uuid2 << "o" << doc2), + << "ns" << nss2.ns() << "ui" << uuid2 << "wall" << Date_t() << "o" + << doc2), }); ASSERT_OK(swResult); } @@ -1224,8 +1230,8 @@ public: { BSON("ts" << presentTs << "t" << 1LL << "op" << "c" - << "ui" << UUID::gen() << "ns" << nss.getCommandNS().ns() << "o" - << BSON("create" << nss.coll())), + << "ui" << UUID::gen() << "ns" << nss.getCommandNS().ns() << "wall" + << Date_t() << "o" << BSON("create" << nss.coll())), }); ASSERT_OK(swResult); @@ -1278,18 +1284,18 @@ public: BSONObj doc0 = BSON("_id" << 0 << "a" << 3); BSONObj doc1 = BSON("_id" << 1 << "a" << BSON_ARRAY(1 << 2)); BSONObj doc2 = BSON("_id" << 2 << "a" << BSON_ARRAY(1 << 2)); - auto op0 = repl::OplogEntry(BSON("ts" << insertTime0.asTimestamp() << "t" << 1LL << "v" << 2 - << "op" - << "i" - << "ns" << nss.ns() << "ui" << uuid << "o" << doc0)); - auto op1 = repl::OplogEntry(BSON("ts" << insertTime1.asTimestamp() << "t" << 1LL << "v" << 2 - << "op" - << "i" - << "ns" << nss.ns() << "ui" << uuid << "o" << doc1)); - auto op2 = repl::OplogEntry(BSON("ts" << insertTime2.asTimestamp() << "t" << 1LL << "v" << 2 - << "op" - << "i" - << "ns" << nss.ns() << "ui" << uuid << "o" << doc2)); + auto op0 = repl::OplogEntry( + BSON("ts" << insertTime0.asTimestamp() << "t" << 1LL << "v" << 2 << "op" + << "i" + << "ns" << nss.ns() << "ui" << uuid << "wall" << Date_t() << "o" << doc0)); + auto op1 = repl::OplogEntry( + BSON("ts" << insertTime1.asTimestamp() << "t" << 1LL << "v" << 2 << "op" + << "i" + << "ns" << nss.ns() << "ui" << uuid << "wall" << Date_t() << "o" << doc1)); + auto op2 = repl::OplogEntry( + BSON("ts" << insertTime2.asTimestamp() << "t" << 1LL << "v" << 2 << "op" + << "i" + << "ns" << nss.ns() << "ui" << uuid << "wall" << Date_t() << "o" << doc2)); std::vector<repl::OplogEntry> ops = {op0, op1, op2}; DoNothingOplogApplierObserver observer; @@ -1349,18 +1355,18 @@ public: BSONObj doc0 = BSON("_id" << 0 << "a" << 3); BSONObj doc1 = BSON("_id" << 1 << "a" << BSON_ARRAY(1 << 2)); BSONObj doc2 = BSON("_id" << 2 << "a" << BSON_ARRAY(1 << 2)); - auto op0 = repl::OplogEntry(BSON("ts" << insertTime0.asTimestamp() << "t" << 1LL << "v" << 2 - << "op" - << "i" - << "ns" << nss.ns() << "ui" << uuid << "o" << doc0)); - auto op1 = repl::OplogEntry(BSON("ts" << insertTime1.asTimestamp() << "t" << 1LL << "v" << 2 - << "op" - << "i" - << "ns" << nss.ns() << "ui" << uuid << "o" << doc1)); - auto op2 = repl::OplogEntry(BSON("ts" << insertTime2.asTimestamp() << "t" << 1LL << "v" << 2 - << "op" - << "i" - << "ns" << nss.ns() << "ui" << uuid << "o" << doc2)); + auto op0 = repl::OplogEntry( + BSON("ts" << insertTime0.asTimestamp() << "t" << 1LL << "v" << 2 << "op" + << "i" + << "ns" << nss.ns() << "ui" << uuid << "wall" << Date_t() << "o" << doc0)); + auto op1 = repl::OplogEntry( + BSON("ts" << insertTime1.asTimestamp() << "t" << 1LL << "v" << 2 << "op" + << "i" + << "ns" << nss.ns() << "ui" << uuid << "wall" << Date_t() << "o" << doc1)); + auto op2 = repl::OplogEntry( + BSON("ts" << insertTime2.asTimestamp() << "t" << 1LL << "v" << 2 << "op" + << "i" + << "ns" << nss.ns() << "ui" << uuid << "wall" << Date_t() << "o" << doc2)); auto indexSpec2 = BSON("createIndexes" << nss.coll() << "v" << static_cast<int>(kIndexVersion) << "key" << BSON("b" << 1) << "name" @@ -1368,7 +1374,8 @@ public: auto createIndexOp = repl::OplogEntry( BSON("ts" << indexBuildTime.asTimestamp() << "t" << 1LL << "v" << 2 << "op" << "c" - << "ns" << nss.getCommandNS().ns() << "ui" << uuid << "o" << indexSpec2)); + << "ns" << nss.getCommandNS().ns() << "ui" << uuid << "wall" << Date_t() + << "o" << indexSpec2)); // We add in an index creation op to test that we restart tracking multikey path info // after bulk index builds. @@ -2435,10 +2442,10 @@ public: // Make a simple insert operation. BSONObj doc0 = BSON("_id" << 0 << "a" << 0); - auto insertOp = - repl::OplogEntry(BSON("ts" << futureTs << "t" << 1LL << "v" << 2 << "op" - << "i" - << "ns" << ns.ns() << "ui" << uuid << "o" << doc0)); + auto insertOp = repl::OplogEntry(BSON("ts" << futureTs << "t" << 1LL << "v" << 2 << "op" + << "i" + << "ns" << ns.ns() << "ui" << uuid << "wall" + << Date_t() << "o" << doc0)); // Apply the operation. auto storageInterface = repl::StorageInterface::get(_opCtx); @@ -2528,7 +2535,7 @@ public: auto createIndexOp = BSON("ts" << startBuildTs << "t" << 1LL << "v" << 2 << "op" << "c" << "ns" << nss.getCommandNS().ns() << "ui" << collUUID - << "o" << indexSpec); + << "wall" << Date_t() << "o" << indexSpec); ASSERT_OK(doAtomicApplyOps(nss.db().toString(), {createIndexOp})); |