diff options
author | Jason Chan <jason.chan@mongodb.com> | 2021-11-15 21:16:54 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-11-15 22:28:15 +0000 |
commit | 634a3411d8f2f8e7dc10149f7907527af8e06204 (patch) | |
tree | 5bd29468f5005fe2c2a3d9f3a65b277d89c655e7 /src/mongo/db/op_observer_impl.cpp | |
parent | f72a3ac7a30c06ac470d137a44eb4a9281027728 (diff) | |
download | mongo-634a3411d8f2f8e7dc10149f7907527af8e06204.tar.gz |
SERVER-61188 Account for preImageRecordingEnabled when reserving oplog slots for new retryable findAndModify format
Diffstat (limited to 'src/mongo/db/op_observer_impl.cpp')
-rw-r--r-- | src/mongo/db/op_observer_impl.cpp | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/src/mongo/db/op_observer_impl.cpp b/src/mongo/db/op_observer_impl.cpp index 474456d2ea1..ab5cd06a0f2 100644 --- a/src/mongo/db/op_observer_impl.cpp +++ b/src/mongo/db/op_observer_impl.cpp @@ -195,6 +195,20 @@ OpTimeBundle replLogUpdate(OperationContext* opCtx, invariant(args.updateArgs->preImageDoc); noopEntry.setOpType(repl::OpTypeEnum::kNoop); noopEntry.setObject(*args.updateArgs->preImageDoc); + if (args.updateArgs->preImageRecordingEnabledForCollection && + args.retryableFindAndModifyLocation == + RetryableFindAndModifyLocation::kSideCollection) { + // We are writing a no-op pre-image oplog entry and storing a post-image into a side + // collection. In this case, we expect to have already reserved 3 oplog slots: + // TS - 2: Oplog slot for the current no-op preimage oplog entry + // TS - 1: Oplog slot for the forged no-op oplog entry that may eventually get used by + // tenant migrations or resharding. + // TS: Oplog slot for the actual update oplog entry. + const auto reservedOplogSlots = args.updateArgs->oplogSlots; + invariant(reservedOplogSlots.size() == 3); + noopEntry.setOpTime(repl::OpTime(reservedOplogSlots.front().getTimestamp(), + reservedOplogSlots.front().getTerm())); + } oplogLink.preImageOpTime = logOperation(opCtx, &noopEntry); if (storePreImageInOplogForRetryableWrite) { opTimes.prePostImageOpTime = oplogLink.preImageOpTime; @@ -218,8 +232,8 @@ OpTimeBundle replLogUpdate(OperationContext* opCtx, oplogEntry->setFromMigrateIfTrue(args.updateArgs->source == OperationSource::kFromMigrate); // oplogLink could have been changed to include pre/postImageOpTime by the previous no-op write. repl::appendOplogEntryChainInfo(opCtx, oplogEntry, &oplogLink, args.updateArgs->stmtIds); - if (args.updateArgs->oplogSlot) { - oplogEntry->setOpTime(*args.updateArgs->oplogSlot); + if (!args.updateArgs->oplogSlots.empty()) { + oplogEntry->setOpTime(args.updateArgs->oplogSlots.back()); } opTimes.writeOpTime = logOperation(opCtx, oplogEntry); opTimes.wallClockTime = oplogEntry->getWallClockTime(); @@ -843,8 +857,8 @@ void OpObserverImpl::onDelete(OperationContext* opCtx, invariant(opCtx->getTxnNumber()); oplogEntry.setNeedsRetryImage({repl::RetryImageEnum::kPreImage}); - if (args.oplogSlot) { - oplogEntry.setOpTime(*args.oplogSlot); + if (!args.oplogSlots.empty()) { + oplogEntry.setOpTime(args.oplogSlots.back()); } } opTime = replLogDelete( |