summaryrefslogtreecommitdiff
path: root/src/mongo/db/repl
diff options
context:
space:
mode:
authorEric Milkie <milkie@10gen.com>2020-07-01 12:26:30 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-07-08 15:01:42 +0000
commit13d756e1645f3d41439f336d2312777dd0cb1999 (patch)
tree8d606be068e140261e8d7f915fc78734031d0a07 /src/mongo/db/repl
parent9d4f0f264a6e0035abd3d541583a615bc8085a86 (diff)
downloadmongo-13d756e1645f3d41439f336d2312777dd0cb1999.tar.gz
SERVER-48628 sort oplog entries first in applier batches, for create ops in transactions
Diffstat (limited to 'src/mongo/db/repl')
-rw-r--r--src/mongo/db/repl/oplog_applier_impl.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/mongo/db/repl/oplog_applier_impl.cpp b/src/mongo/db/repl/oplog_applier_impl.cpp
index 39f7a1ac94a..d0c2aa9cf56 100644
--- a/src/mongo/db/repl/oplog_applier_impl.cpp
+++ b/src/mongo/db/repl/oplog_applier_impl.cpp
@@ -273,6 +273,21 @@ void _addOplogChainOpsToWriterVectors(OperationContext* opCtx,
void stableSortByNamespace(std::vector<const OplogEntry*>* oplogEntryPointers) {
auto nssComparator = [](const OplogEntry* l, const OplogEntry* r) {
+ // Specially sort collections that are $cmd first, before everything else. This will
+ // move commands with the special $cmd collection name to the beginning, rather than sorting
+ // them potentially in the middle of the sorted vector of insert/update/delete ops.
+ // This special sort behavior is required because DDL operations need to run before
+ // create/update/delete operations in a multi-doc transaction.
+ if (l->getNss().isCommand()) {
+ if (r->getNss().isCommand())
+ // l == r; now compare the namespace
+ return l->getNss() < r->getNss();
+ // l < r
+ return true;
+ }
+ if (r->getNss().isCommand())
+ // l > r
+ return false;
return l->getNss() < r->getNss();
};
std::stable_sort(oplogEntryPointers->begin(), oplogEntryPointers->end(), nssComparator);
@@ -1027,6 +1042,8 @@ Status OplogApplierImpl::applyOplogBatchPerWorker(OperationContext* opCtx,
opCtx->recoveryUnit()->setPrepareConflictBehavior(
PrepareConflictBehavior::kIgnoreConflictsAllowWrites);
+ // Group the operations by namespace in order to get larger groups for bulk inserts, but do not
+ // mix up the current order of oplog entries within the same namespace (thus *stable* sort).
stableSortByNamespace(ops);
const auto oplogApplicationMode = getOptions().mode;