diff options
-rw-r--r-- | src/mongo/db/catalog/drop_indexes.cpp | 8 | ||||
-rw-r--r-- | src/mongo/db/catalog_raii.cpp | 13 | ||||
-rw-r--r-- | src/mongo/dbtests/storage_timestamp_tests.cpp | 1 |
3 files changed, 17 insertions, 5 deletions
diff --git a/src/mongo/db/catalog/drop_indexes.cpp b/src/mongo/db/catalog/drop_indexes.cpp index 98c2025918d..93bc44b3a0f 100644 --- a/src/mongo/db/catalog/drop_indexes.cpp +++ b/src/mongo/db/catalog/drop_indexes.cpp @@ -397,14 +397,14 @@ Status dropIndexes(OperationContext* opCtx, hangAfterAbortingIndexes.pauseWhileSet(); } - // Take an exclusive lock on the collection now to be able to perform index catalog writes - // when removing ready indexes from disk. - collection.emplace(opCtx, dbAndUUID, MODE_X); - // Abandon the snapshot as the index catalog will compare the in-memory state to the disk // state, which may have changed when we released the lock temporarily. opCtx->recoveryUnit()->abandonSnapshot(); + // Take an exclusive lock on the collection now to be able to perform index catalog writes + // when removing ready indexes from disk. + collection.emplace(opCtx, dbAndUUID, MODE_X); + db = collection->getDb(); if (!*collection) { return Status(ErrorCodes::NamespaceNotFound, diff --git a/src/mongo/db/catalog_raii.cpp b/src/mongo/db/catalog_raii.cpp index d0a91958cc3..0f29d258bcd 100644 --- a/src/mongo/db/catalog_raii.cpp +++ b/src/mongo/db/catalog_raii.cpp @@ -79,12 +79,23 @@ AutoGetCollection::AutoGetCollection(OperationContext* opCtx, !nsOrUUID.dbname().empty() ? nsOrUUID.dbname() : nsOrUUID.nss()->db(), isSharedLockMode(modeColl) ? MODE_IS : MODE_IX, deadline) { - if (auto& nss = nsOrUUID.nss()) { + auto& nss = nsOrUUID.nss(); + if (nss) { uassert(ErrorCodes::InvalidNamespace, str::stream() << "Namespace " << *nss << " is not a valid collection name", nss->isValid()); } + // Out of an abundance of caution, force operations to acquire new snapshots after + // acquiring exclusive collection locks. Operations that hold MODE_X locks make an + // assumption that all writes are visible in their snapshot and no new writes will commit. + // This may not be the case if an operation already has a snapshot open before acquiring an + // exclusive lock. + if (modeColl == MODE_X) { + invariant(!opCtx->recoveryUnit()->inActiveTxn(), + str::stream() << "Snapshot opened before acquiring X lock for " << *nss); + } + _collLock.emplace(opCtx, nsOrUUID, modeColl, deadline); _resolvedNss = CollectionCatalog::get(opCtx).resolveNamespaceStringOrUUID(opCtx, nsOrUUID); diff --git a/src/mongo/dbtests/storage_timestamp_tests.cpp b/src/mongo/dbtests/storage_timestamp_tests.cpp index ab385218c86..05d87f448da 100644 --- a/src/mongo/dbtests/storage_timestamp_tests.cpp +++ b/src/mongo/dbtests/storage_timestamp_tests.cpp @@ -237,6 +237,7 @@ public: void reset(NamespaceString nss) const { ::mongo::writeConflictRetry(_opCtx, "deleteAll", nss.ns(), [&] { _opCtx->recoveryUnit()->setTimestampReadSource(RecoveryUnit::ReadSource::kNoTimestamp); + _opCtx->recoveryUnit()->abandonSnapshot(); AutoGetCollection collRaii(_opCtx, nss, LockMode::MODE_X); if (collRaii) { |