diff options
Diffstat (limited to 'src/mongo/db/session_catalog_mongod.cpp')
-rw-r--r-- | src/mongo/db/session_catalog_mongod.cpp | 61 |
1 files changed, 48 insertions, 13 deletions
diff --git a/src/mongo/db/session_catalog_mongod.cpp b/src/mongo/db/session_catalog_mongod.cpp index fe77c218e91..ba5d503ebd8 100644 --- a/src/mongo/db/session_catalog_mongod.cpp +++ b/src/mongo/db/session_catalog_mongod.cpp @@ -38,6 +38,7 @@ #include "mongo/db/create_indexes_gen.h" #include "mongo/db/dbdirectclient.h" #include "mongo/db/index_builds_coordinator.h" +#include "mongo/db/internal_transactions_feature_flag_gen.h" #include "mongo/db/namespace_string.h" #include "mongo/db/operation_context.h" #include "mongo/db/ops/write_ops.h" @@ -374,25 +375,59 @@ int removeExpiredTransactionSessionsFromDisk( } void createTransactionTable(OperationContext* opCtx) { - auto serviceCtx = opCtx->getServiceContext(); CollectionOptions options; - auto createCollectionStatus = - repl::StorageInterface::get(serviceCtx) - ->createCollection(opCtx, NamespaceString::kSessionTransactionsTableNamespace, options); + auto storageInterface = repl::StorageInterface::get(opCtx); + auto createCollectionStatus = storageInterface->createCollection( + opCtx, NamespaceString::kSessionTransactionsTableNamespace, options); + if (createCollectionStatus == ErrorCodes::NamespaceExists) { - return; - } + bool collectionIsEmpty = false; + { + AutoGetCollection autoColl( + opCtx, NamespaceString::kSessionTransactionsTableNamespace, LockMode::MODE_IS); + invariant(autoColl); + + if (autoColl->getIndexCatalog()->findIndexByName( + opCtx, MongoDSessionCatalog::kConfigTxnsPartialIndexName)) { + // Index already exists, so there's nothing to do. + return; + } - uassertStatusOKWithContext( - createCollectionStatus, - str::stream() << "Failed to create the " - << NamespaceString::kSessionTransactionsTableNamespace.ns() << " collection"); + collectionIsEmpty = autoColl->isEmpty(opCtx); + } + + if (!collectionIsEmpty) { + // Unless explicitly enabled, don't create the index to avoid delaying step up. + if (feature_flags::gFeatureFlagAlwaysCreateConfigTransactionsPartialIndexOnStepUp + .isEnabledAndIgnoreFCV()) { + AutoGetCollection autoColl( + opCtx, NamespaceString::kSessionTransactionsTableNamespace, LockMode::MODE_X); + IndexBuildsCoordinator::get(opCtx)->createIndex( + opCtx, + autoColl->uuid(), + MongoDSessionCatalog::getConfigTxnPartialIndexSpec(), + IndexBuildsManager::IndexConstraints::kEnforce, + false /* fromMigration */); + } + + return; + } + + // The index does not exist and the collection is empty, so fall through to create it on the + // empty collection. This can happen after a failover because the collection and index + // creation are recorded as separate oplog entries. + } else { + uassertStatusOKWithContext(createCollectionStatus, + str::stream() + << "Failed to create the " + << NamespaceString::kSessionTransactionsTableNamespace.ns() + << " collection"); + } auto indexSpec = MongoDSessionCatalog::getConfigTxnPartialIndexSpec(); - const auto createIndexStatus = - repl::StorageInterface::get(opCtx)->createIndexesOnEmptyCollection( - opCtx, NamespaceString::kSessionTransactionsTableNamespace, {indexSpec}); + const auto createIndexStatus = storageInterface->createIndexesOnEmptyCollection( + opCtx, NamespaceString::kSessionTransactionsTableNamespace, {indexSpec}); uassertStatusOKWithContext( createIndexStatus, str::stream() << "Failed to create partial index for the " |