summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVesselina Ratcheva <vesselina.ratcheva@10gen.com>2020-07-15 20:48:48 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-07-16 00:31:40 +0000
commitd520082a3f8568b9303ab7e37c111d436d1dd50b (patch)
treec7ea20c32c86d225f01ad1c47ae3970da5d9f042
parent525a83552575efba3274bebb2d4f94b8554c5e16 (diff)
downloadmongo-d520082a3f8568b9303ab7e37c111d436d1dd50b.tar.gz
SERVER-48525 Forbid dropping config.transactions when there are prepared transactions
This reverts commit 2e53e13f576ab96188e2f27221c657ef02d15dd0.
-rw-r--r--etc/backports_required_for_multiversion_tests.yml2
-rw-r--r--jstests/core/txns/no_writes_to_config_transactions_with_prepared_transaction.js10
-rw-r--r--src/mongo/db/op_observer_impl.cpp16
3 files changed, 26 insertions, 2 deletions
diff --git a/etc/backports_required_for_multiversion_tests.yml b/etc/backports_required_for_multiversion_tests.yml
index c21d8a6e04c..b65a00a46e5 100644
--- a/etc/backports_required_for_multiversion_tests.yml
+++ b/etc/backports_required_for_multiversion_tests.yml
@@ -46,6 +46,8 @@ replica_sets_jscore_multiversion_passthrough:
test_file: jstests/core/wildcard_index_partial_index.js
- ticket: SERVER-48993
test_file: jstests/core/explode_for_sort_collation.js
+- ticket: SERVER-48525
+ test_file: jstests/core/txns/no_writes_to_config_transactions_with_prepared_transaction.js
sharding_jscore_multiversion_passthrough:
- ticket: SERVER-47773
diff --git a/jstests/core/txns/no_writes_to_config_transactions_with_prepared_transaction.js b/jstests/core/txns/no_writes_to_config_transactions_with_prepared_transaction.js
index 067bf1482fa..4302a131c36 100644
--- a/jstests/core/txns/no_writes_to_config_transactions_with_prepared_transaction.js
+++ b/jstests/core/txns/no_writes_to_config_transactions_with_prepared_transaction.js
@@ -70,11 +70,17 @@ transactionEntry = config.transactions.findOne();
assert(transactionEntry);
jsTestLog("Test that dropping config.transactions fails when there is a prepared transaction" +
- " on the session");
+ " present");
+jsTestLog("[1] collection drop in the same session");
assert.commandFailedWithCode(assert.throws(function() {
sessionConfigDB.transactions.drop();
}),
- 40528);
+ [4852500, 40528]);
+jsTestLog("[2] collection drop not in a session");
+assert.commandFailedWithCode(assert.throws(function() {
+ config.transactions.drop();
+ }),
+ 4852500);
jsTestLog("Test that we can prepare a transaction on a different session");
const session2 = db.getMongo().startSession({causalConsistency: false});
diff --git a/src/mongo/db/op_observer_impl.cpp b/src/mongo/db/op_observer_impl.cpp
index bb935f1cfb7..78b15ad003e 100644
--- a/src/mongo/db/op_observer_impl.cpp
+++ b/src/mongo/db/op_observer_impl.cpp
@@ -778,6 +778,22 @@ repl::OpTime OpObserverImpl::onDropCollection(OperationContext* opCtx,
if (collectionName.coll() == DurableViewCatalog::viewsCollectionName()) {
DurableViewCatalog::onSystemViewsCollectionDrop(opCtx, collectionName);
} else if (collectionName == NamespaceString::kSessionTransactionsTableNamespace) {
+ // Disallow this drop if there are currently prepared transactions.
+ const auto sessionCatalog = SessionCatalog::get(opCtx);
+ SessionKiller::Matcher matcherAllSessions(
+ KillAllSessionsByPatternSet{makeKillAllSessionsByPattern(opCtx)});
+ bool noPreparedTxns = true;
+ sessionCatalog->scanSessions(matcherAllSessions, [&](const ObservableSession& session) {
+ auto txnParticipant = TransactionParticipant::get(session);
+ if (txnParticipant.transactionIsPrepared()) {
+ noPreparedTxns = false;
+ }
+ });
+ uassert(4852500,
+ "Unable to drop transactions table (config.transactions) while prepared "
+ "transactions are present.",
+ noPreparedTxns);
+
MongoDSessionCatalog::invalidateAllSessions(opCtx);
} else if (collectionName == NamespaceString::kConfigSettingsNamespace) {
ReadWriteConcernDefaults::get(opCtx).invalidate();