summaryrefslogtreecommitdiff
path: root/src/mongo/db/repl/transaction_oplog_application.cpp
diff options
context:
space:
mode:
authorMaria van Keulen <maria.vankeulen@mongodb.com>2020-01-14 21:32:54 +0000
committerevergreen <evergreen@mongodb.com>2020-01-14 21:32:54 +0000
commit846c7aa84ac08dbccc7d727e9068406b7b2de033 (patch)
treeb1b1b2c3e8ca99eb9b594e9ab1724d116eead4f3 /src/mongo/db/repl/transaction_oplog_application.cpp
parentc04fde3eca954d9bf9243d544484a90997ba9373 (diff)
downloadmongo-846c7aa84ac08dbccc7d727e9068406b7b2de033.tar.gz
SERVER-44852 Handle transactions with commands during oplog application
Diffstat (limited to 'src/mongo/db/repl/transaction_oplog_application.cpp')
-rw-r--r--src/mongo/db/repl/transaction_oplog_application.cpp39
1 files changed, 35 insertions, 4 deletions
diff --git a/src/mongo/db/repl/transaction_oplog_application.cpp b/src/mongo/db/repl/transaction_oplog_application.cpp
index 986c5664727..2e31f9dc0e5 100644
--- a/src/mongo/db/repl/transaction_oplog_application.cpp
+++ b/src/mongo/db/repl/transaction_oplog_application.cpp
@@ -64,8 +64,9 @@ Status _applyOperationsForTransaction(OperationContext* opCtx,
// Apply each the operations via repl::applyOperation.
for (const auto& op : ops) {
try {
+ Status status = Status::OK();
AutoGetCollection coll(opCtx, op.getNss(), MODE_IX);
- auto status = repl::applyOperation_inlock(
+ status = repl::applyOperation_inlock(
opCtx, coll.getDb(), &op, false /*alwaysUpsert*/, oplogApplicationMode);
if (!status.isOK()) {
return status;
@@ -228,10 +229,12 @@ Status applyAbortTransaction(OperationContext* opCtx,
MONGO_UNREACHABLE;
}
-std::vector<OplogEntry> readTransactionOperationsFromOplogChain(
+std::pair<std::vector<OplogEntry>, bool> _readTransactionOperationsFromOplogChain(
OperationContext* opCtx,
const OplogEntry& lastEntryInTxn,
- const std::vector<OplogEntry*>& cachedOps) noexcept {
+ const std::vector<OplogEntry*>& cachedOps,
+ const bool checkForCommands) noexcept {
+ bool isTransactionWithCommand = false;
// Traverse the oplog chain with its own snapshot and read timestamp.
ReadSourceScope readSourceScope(opCtx);
@@ -293,7 +296,35 @@ std::vector<OplogEntry> readTransactionOperationsFromOplogChain(
// Reconstruct the operations from the prepare or unprepared commit oplog entry.
repl::ApplyOps::extractOperationsTo(prepareOrUnpreparedCommit, lastEntryInTxnObj, &ops);
- return ops;
+
+ // It is safe to assume that any commands inside `ops` are real commands to be applied, as
+ // opposed to auxiliary commands such as "commit" and "abort".
+ if (checkForCommands) {
+ for (auto&& op : ops) {
+ if (op.isCommand()) {
+ isTransactionWithCommand = true;
+ break;
+ }
+ }
+ }
+ return std::make_pair(ops, isTransactionWithCommand);
+}
+
+std::vector<OplogEntry> readTransactionOperationsFromOplogChain(
+ OperationContext* opCtx,
+ const OplogEntry& lastEntryInTxn,
+ const std::vector<OplogEntry*>& cachedOps) noexcept {
+ auto result = _readTransactionOperationsFromOplogChain(
+ opCtx, lastEntryInTxn, cachedOps, false /*checkForCommands*/);
+ return std::get<0>(result);
+}
+
+std::pair<std::vector<OplogEntry>, bool> readTransactionOperationsFromOplogChainAndCheckForCommands(
+ OperationContext* opCtx,
+ const OplogEntry& lastEntryInTxn,
+ const std::vector<OplogEntry*>& cachedOps) noexcept {
+ return _readTransactionOperationsFromOplogChain(
+ opCtx, lastEntryInTxn, cachedOps, true /*checkForCommands*/);
}
namespace {