mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
SERVER-43638 Do not block prepared transactions on index builds on secondaries
This commit is contained in:
parent
b1bd366200
commit
906ac3ca78
@ -5,7 +5,6 @@
|
|||||||
* @tags: [
|
* @tags: [
|
||||||
* requires_document_locking,
|
* requires_document_locking,
|
||||||
* requires_replication,
|
* requires_replication,
|
||||||
* two_phase_index_builds_unsupported,
|
|
||||||
* uses_prepare_transaction,
|
* uses_prepare_transaction,
|
||||||
* uses_transactions,
|
* uses_transactions,
|
||||||
* ]
|
* ]
|
||||||
|
@ -324,14 +324,24 @@ Status _applyPrepareTransaction(OperationContext* opCtx,
|
|||||||
// This will prevent hybrid index builds from corrupting an index on secondary nodes if a
|
// This will prevent hybrid index builds from corrupting an index on secondary nodes if a
|
||||||
// prepared transaction becomes prepared during a build but commits after the index build
|
// prepared transaction becomes prepared during a build but commits after the index build
|
||||||
// commits.
|
// commits.
|
||||||
for (const auto& op : ops) {
|
// When two-phase index builds are in use, this is both unnecessary and unsafe. Due to locking,
|
||||||
auto ns = op.getNss();
|
// we can guarantee that a transaction prepared on a primary during an index build will always
|
||||||
auto uuid = *op.getUuid();
|
// commit before that index build completes. Because two-phase index builds replicate start and
|
||||||
if (BackgroundOperation::inProgForNs(ns)) {
|
// commit oplog entries, it will never be possible to replicate a prepared transaction, commit
|
||||||
warning() << "blocking replication until index builds are finished on "
|
// an index build, then commit the transaction, the bug described above.
|
||||||
<< redact(ns.toString()) << ", due to prepared transaction";
|
// This blocking behavior can also introduce a deadlock with two-phase index builds on
|
||||||
BackgroundOperation::awaitNoBgOpInProgForNs(ns);
|
// a secondary if a prepared transaction blocks on an index build, but the index build can't
|
||||||
IndexBuildsCoordinator::get(opCtx)->awaitNoIndexBuildInProgressForCollection(uuid);
|
// re-acquire its X lock because of the transaction.
|
||||||
|
if (!IndexBuildsCoordinator::get(opCtx)->supportsTwoPhaseIndexBuild()) {
|
||||||
|
for (const auto& op : ops) {
|
||||||
|
auto ns = op.getNss();
|
||||||
|
auto uuid = *op.getUuid();
|
||||||
|
if (BackgroundOperation::inProgForNs(ns)) {
|
||||||
|
warning() << "blocking replication until index builds are finished on "
|
||||||
|
<< redact(ns.toString()) << ", due to prepared transaction";
|
||||||
|
BackgroundOperation::awaitNoBgOpInProgForNs(ns);
|
||||||
|
IndexBuildsCoordinator::get(opCtx)->awaitNoIndexBuildInProgressForCollection(uuid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user