summaryrefslogtreecommitdiff
path: root/src/mongo/db/session_catalog_mongod.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/session_catalog_mongod.cpp')
-rw-r--r--src/mongo/db/session_catalog_mongod.cpp61
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 "