diff options
author | jannaerin <golden.janna@gmail.com> | 2021-12-06 16:19:51 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-01-04 18:06:22 +0000 |
commit | da82e5278ca717d3228e4837a3e815c5ced876e0 (patch) | |
tree | 4a3bdda5c9a9d3d39a15dbcce1264a9e34dc72d2 | |
parent | 863684a584bfa5b4beeffb8d2a79e735299c1de7 (diff) | |
download | mongo-da82e5278ca717d3228e4837a3e815c5ced876e0.tar.gz |
SERVER-61474 Ban directoryPerDb and directoryForIndexes with Merge
-rw-r--r-- | jstests/replsets/shard_merge_invalid_options.js | 74 | ||||
-rw-r--r-- | src/mongo/db/commands/tenant_migration_donor_cmds.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/commands/tenant_migration_recipient_cmds.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/repl/tenant_migration_util.h | 16 | ||||
-rw-r--r-- | src/mongo/db/storage/storage_engine.h | 2 | ||||
-rw-r--r-- | src/mongo/db/storage/storage_engine_impl.h | 4 | ||||
-rw-r--r-- | src/mongo/db/storage/storage_engine_mock.h | 3 |
7 files changed, 103 insertions, 0 deletions
diff --git a/jstests/replsets/shard_merge_invalid_options.js b/jstests/replsets/shard_merge_invalid_options.js new file mode 100644 index 00000000000..4d7eee88a40 --- /dev/null +++ b/jstests/replsets/shard_merge_invalid_options.js @@ -0,0 +1,74 @@ +/** + * Tests that the donorStartMigration and recipientSyncData commands throw when a node has options + * set that are incompatible with protocol shard merge. + * + * @tags: [requires_fcv_53, featureFlagShardMerge] + * ] + */ + +(function() { +"use strict"; + +load("jstests/replsets/libs/tenant_migration_util.js"); +load("jstests/libs/fail_point_util.js"); + +function runTest(nodeOptions, expectedError) { + let rst = new ReplSetTest({nodes: 1, nodeOptions: nodeOptions}); + rst.startSet(); + rst.initiate(); + + let primary = rst.getPrimary(); + let adminDB = primary.getDB("admin"); + const kDummyConnStr = "mongodb://localhost/?replicaSet=foo"; + const readPreference = {mode: 'primary'}; + const migrationCertificates = TenantMigrationUtil.makeMigrationCertificatesForTest(); + + // Enable below fail points to prevent starting the donor/recipient POS instance. + configureFailPoint(primary, "returnResponseCommittedForDonorStartMigrationCmd"); + configureFailPoint(primary, "returnResponseOkForRecipientSyncDataCmd"); + configureFailPoint(primary, "returnResponseOkForRecipientForgetMigrationCmd"); + + // Ensure the feature flag is enabled and FCV is latest + assert(TenantMigrationUtil.isShardMergeEnabled(adminDB)); + assert.eq(getFCVConstants().latest, + adminDB.system.version.findOne({_id: 'featureCompatibilityVersion'}).version); + + // Assert that donorStartMigration fails with the expected code + assert.commandFailedWithCode( + adminDB.runCommand({ + donorStartMigration: 1, + protocol: "shard merge", + migrationId: UUID(), + recipientConnectionString: kDummyConnStr, + readPreference: readPreference, + donorCertificateForRecipient: migrationCertificates.donorCertificateForRecipient, + recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor + }), + expectedError, + "Expected donorStartMigration to fail when protocol is 'shard merge' and node options " + + tojson(nodeOptions) + " are set, but did not"); + + // Assert that recipientSyncData fails with the expected code + assert.commandFailedWithCode( + adminDB.runCommand({ + recipientSyncData: 1, + protocol: "shard merge", + migrationId: UUID(), + donorConnectionString: kDummyConnStr, + readPreference: readPreference, + startMigrationDonorTimestamp: Timestamp(1, 1), + recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor + }), + expectedError, + "Expected recipientSyncData to fail when protocol is 'shard merge' and node options " + + tojson(nodeOptions) + " are set, but did not"); + + rst.stopSet(); +} + +// Shard merge is not allowed when directoryperdb is enabled +runTest({directoryperdb: ""}, ErrorCodes.InvalidOptions); + +// Shard merge is not allowed when directoryForIndexes is enabled +runTest({"wiredTigerDirectoryForIndexes": ""}, ErrorCodes.InvalidOptions); +})(); diff --git a/src/mongo/db/commands/tenant_migration_donor_cmds.cpp b/src/mongo/db/commands/tenant_migration_donor_cmds.cpp index 00e283d8563..e94f865d1cb 100644 --- a/src/mongo/db/commands/tenant_migration_donor_cmds.cpp +++ b/src/mongo/db/commands/tenant_migration_donor_cmds.cpp @@ -76,6 +76,8 @@ public: uassertStatusOK(tenant_migration_util::protocolTenantIdCompatibilityCheck( migrationProtocol, cmd.getTenantId().toString())); + tenant_migration_util::protocolStorageOptionsCompatibilityCheck(opCtx, + migrationProtocol); TenantMigrationDonorDocument stateDoc(cmd.getMigrationId(), cmd.getRecipientConnectionString().toString(), diff --git a/src/mongo/db/commands/tenant_migration_recipient_cmds.cpp b/src/mongo/db/commands/tenant_migration_recipient_cmds.cpp index 9952d301d47..c81f8ecb697 100644 --- a/src/mongo/db/commands/tenant_migration_recipient_cmds.cpp +++ b/src/mongo/db/commands/tenant_migration_recipient_cmds.cpp @@ -74,6 +74,8 @@ public: uassertStatusOK(tenant_migration_util::protocolTenantIdCompatibilityCheck( migrationProtocol, cmd.getTenantId().toString())); + tenant_migration_util::protocolStorageOptionsCompatibilityCheck(opCtx, + migrationProtocol); TenantMigrationRecipientDocument stateDoc(cmd.getMigrationId(), cmd.getDonorConnectionString().toString(), diff --git a/src/mongo/db/repl/tenant_migration_util.h b/src/mongo/db/repl/tenant_migration_util.h index 818ffba2649..f3350458182 100644 --- a/src/mongo/db/repl/tenant_migration_util.h +++ b/src/mongo/db/repl/tenant_migration_util.h @@ -186,6 +186,22 @@ inline Status protocolTenantIdCompatibilityCheck(const MigrationProtocolEnum& pr return Status::OK(); } +inline void protocolStorageOptionsCompatibilityCheck(OperationContext* opCtx, + const MigrationProtocolEnum& protocol) { + if (protocol != MigrationProtocolEnum::kShardMerge) + return; + + uassert(ErrorCodes::InvalidOptions, + str::stream() << "protocol '" << MigrationProtocol_serializer(protocol) + << "' is not allowed when storage option 'directoryPerDb' is enabled", + !storageGlobalParams.directoryperdb); + uassert( + ErrorCodes::InvalidOptions, + str::stream() << "protocol '" << MigrationProtocol_serializer(protocol) + << "' is not allowed when storage option 'directoryForIndexes' is enabled", + !opCtx->getServiceContext()->getStorageEngine()->isUsingDirectoryForIndexes()); +} + /* * Creates an ExternalKeysCollectionDocument representing an config.external_validation_keys * document from the given the admin.system.keys document BSONObj. diff --git a/src/mongo/db/storage/storage_engine.h b/src/mongo/db/storage/storage_engine.h index f7c706b96a6..2160a430aa0 100644 --- a/src/mongo/db/storage/storage_engine.h +++ b/src/mongo/db/storage/storage_engine.h @@ -643,6 +643,8 @@ public: virtual bool isUsingDirectoryPerDb() const = 0; + virtual bool isUsingDirectoryForIndexes() const = 0; + virtual KVEngine* getEngine() = 0; virtual const KVEngine* getEngine() const = 0; virtual DurableCatalog* getCatalog() = 0; diff --git a/src/mongo/db/storage/storage_engine_impl.h b/src/mongo/db/storage/storage_engine_impl.h index f2b69e8d2ee..4f25de8f7d2 100644 --- a/src/mongo/db/storage/storage_engine_impl.h +++ b/src/mongo/db/storage/storage_engine_impl.h @@ -348,6 +348,10 @@ public: return _options.directoryPerDB; } + bool isUsingDirectoryForIndexes() const override { + return _options.directoryForIndexes; + } + StatusWith<Timestamp> pinOldestTimestamp(OperationContext* opCtx, const std::string& requestingServiceName, Timestamp requestedTimestamp, diff --git a/src/mongo/db/storage/storage_engine_mock.h b/src/mongo/db/storage/storage_engine_mock.h index 7032a3afe87..93a187c7615 100644 --- a/src/mongo/db/storage/storage_engine_mock.h +++ b/src/mongo/db/storage/storage_engine_mock.h @@ -179,6 +179,9 @@ public: bool isUsingDirectoryPerDb() const final { return false; } + bool isUsingDirectoryForIndexes() const final { + return false; + } KVEngine* getEngine() final { return nullptr; } |