summaryrefslogtreecommitdiff
path: root/src/mongo/db/repl/oplog.cpp
diff options
context:
space:
mode:
authorSamy Lanka <samy.lanka@mongodb.com>2018-10-12 11:28:51 -0400
committerSamy Lanka <samy.lanka@mongodb.com>2018-10-23 15:29:46 -0400
commit1fea1df1ee21cac90a2217f219f1ba12244fc4fa (patch)
tree5ee156668667be375c0d551485e348736a0c9832 /src/mongo/db/repl/oplog.cpp
parent485491d5839e11f47c6696d1bcf3a449bfbc56cf (diff)
downloadmongo-1fea1df1ee21cac90a2217f219f1ba12244fc4fa.tar.gz
SERVER-35879 Deal with commitTransaction oplog entries during startup recovery
Diffstat (limited to 'src/mongo/db/repl/oplog.cpp')
-rw-r--r--src/mongo/db/repl/oplog.cpp30
1 files changed, 29 insertions, 1 deletions
diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp
index 43ea709440a..bd41e12bd1e 100644
--- a/src/mongo/db/repl/oplog.cpp
+++ b/src/mongo/db/repl/oplog.cpp
@@ -86,6 +86,7 @@
#include "mongo/db/stats/counters.h"
#include "mongo/db/storage/storage_engine.h"
#include "mongo/db/storage/storage_options.h"
+#include "mongo/db/transaction_history_iterator.h"
#include "mongo/db/transaction_participant.h"
#include "mongo/platform/random.h"
#include "mongo/scripting/engine.h"
@@ -1010,7 +1011,34 @@ std::map<std::string, ApplyOpMetadata> opsMap = {
BSONObj& cmd,
const OpTime& opTime,
const OplogEntry& entry,
- OplogApplication::Mode mode) -> Status { return Status::OK(); }}},
+ OplogApplication::Mode mode) -> Status {
+ if (mode == OplogApplication::Mode::kRecovering) {
+ const auto replCoord = ReplicationCoordinator::get(opCtx);
+ const auto recoveryTimestamp = replCoord->getRecoveryTimestamp();
+ invariant(recoveryTimestamp);
+
+ // If the commitTimestamp is before the recoveryTimestamp, then the data already
+ // reflects the operations from the transaction.
+ const auto commitTimestamp = cmd["commitTimestamp"].timestamp();
+ if (recoveryTimestamp.get() > commitTimestamp) {
+ return Status::OK();
+ }
+
+ // Get the corresponding prepareTransaction oplog entry.
+ TransactionHistoryIterator iter(opTime);
+ invariant(iter.hasNext());
+ const auto commitOplogEntry = iter.next(opCtx);
+ invariant(iter.hasNext());
+ const auto prepareOplogEntry = iter.next(opCtx);
+
+ // Transform prepare command into a normal applyOps command.
+ const auto prepareCmd = prepareOplogEntry.getOperationToApply().removeField("prepare");
+
+ BSONObjBuilder resultWeDontCareAbout;
+ return applyOps(opCtx, nsToDatabase(ns), prepareCmd, mode, &resultWeDontCareAbout);
+ }
+ return Status::OK();
+ }}},
{"abortTransaction",
{[](OperationContext* opCtx,
const char* ns,