summaryrefslogtreecommitdiff
path: root/jstests/replsets
diff options
context:
space:
mode:
authorSuganthi Mani <suganthi.mani@mongodb.com>2023-04-06 13:30:39 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-04-06 14:16:10 +0000
commit723595c779147f85d49ec0bc727bdc977ee5d98c (patch)
tree9cadaf8792be1dc57857bb109cd004a6e40e740c /jstests/replsets
parent3857cb150c258819541362b2f5e2711e4bac5a2c (diff)
downloadmongo-723595c779147f85d49ec0bc727bdc977ee5d98c.tar.gz
SERVER-72199 Shard merge handles initial sync, resync and unclean restarts.
Diffstat (limited to 'jstests/replsets')
-rw-r--r--jstests/replsets/tenant_migration_recipient_forget_migration.js9
-rw-r--r--jstests/replsets/tenant_migration_recipient_shard_merge_import_survives_unclean_restart.js92
-rw-r--r--jstests/replsets/tenant_migration_recipient_shard_merge_learn_files.js11
3 files changed, 111 insertions, 1 deletions
diff --git a/jstests/replsets/tenant_migration_recipient_forget_migration.js b/jstests/replsets/tenant_migration_recipient_forget_migration.js
index 145d837c63a..2d34605ab77 100644
--- a/jstests/replsets/tenant_migration_recipient_forget_migration.js
+++ b/jstests/replsets/tenant_migration_recipient_forget_migration.js
@@ -38,12 +38,17 @@ const isShardMergeEnabledOnDonorPrimary =
const oplogBufferCollectionName = (migrationIdString) =>
`repl.migration.oplog_${migrationIdString}`;
const donatedFilesCollectionName = (migrationIdString) => `donatedFiles.${migrationIdString}`;
+const importMarkerCollName = (migrationIdString) => `importDoneMarker.${migrationIdString}`;
const assertTempCollectionsExist = (conn, migrationIdString) => {
const collections = conn.getDB("config").getCollectionNames();
assert(collections.includes(oplogBufferCollectionName(migrationIdString)), collections);
if (isShardMergeEnabledOnDonorPrimary) {
assert(collections.includes(donatedFilesCollectionName(migrationIdString)), collections);
+ assert.eq(1,
+ conn.getDB("local")
+ .getCollectionInfos({name: importMarkerCollName(migrationIdString)})
+ .length);
}
};
@@ -52,6 +57,10 @@ const assertTempCollectionsDoNotExist = (conn, migrationIdString) => {
assert(!collections.includes(oplogBufferCollectionName(migrationIdString)), collections);
if (isShardMergeEnabledOnDonorPrimary) {
assert(!collections.includes(donatedFilesCollectionName(migrationIdString)), collections);
+ assert.eq(0,
+ conn.getDB("local")
+ .getCollectionInfos({name: importMarkerCollName(migrationIdString)})
+ .length);
}
};
diff --git a/jstests/replsets/tenant_migration_recipient_shard_merge_import_survives_unclean_restart.js b/jstests/replsets/tenant_migration_recipient_shard_merge_import_survives_unclean_restart.js
new file mode 100644
index 00000000000..3bb2281bb90
--- /dev/null
+++ b/jstests/replsets/tenant_migration_recipient_shard_merge_import_survives_unclean_restart.js
@@ -0,0 +1,92 @@
+/**
+ * Tests that the donor data copied via shard merge protocol by recipient is present even after
+ * unclean restarts.
+ *
+ * @tags: [
+ * incompatible_with_macos,
+ * incompatible_with_windows_tls,
+ * requires_majority_read_concern,
+ * requires_persistence,
+ * serverless,
+ * featureFlagShardMerge,
+ * ]
+ */
+
+import {TenantMigrationTest} from "jstests/replsets/libs/tenant_migration_test.js";
+import {
+ isShardMergeEnabled,
+ makeX509OptionsForTest
+} from "jstests/replsets/libs/tenant_migration_util.js";
+
+load("jstests/libs/fail_point_util.js");
+load("jstests/libs/uuid_util.js");
+
+// Setting syncdelay to 0 will disable the checkpoint on the recipient.
+const recipientRst = new ReplSetTest({
+ nodes: 1,
+ name: "recipient",
+ serverless: true,
+ nodeOptions: Object.assign(makeX509OptionsForTest().recipient, {
+ setParameter:
+ {syncdelay: 0, tenantMigrationGarbageCollectionDelayMS: 0, ttlMonitorSleepSecs: 1}
+ })
+});
+
+recipientRst.startSet();
+recipientRst.initiate();
+
+const recipientPrimary = recipientRst.getPrimary();
+
+// Note: Including this explicit early return here due to the fact that multiversion
+// suites will execute this test without featureFlagShardMerge enabled (despite the
+// presence of the featureFlagShardMerge tag above), which means the test will attempt
+// to run a multi-tenant migration and fail.
+if (!isShardMergeEnabled(recipientPrimary.getDB("admin"))) {
+ recipientRst.stop();
+ jsTestLog("Skipping Shard Merge-specific test.");
+ quit();
+}
+
+const tenantMigrationTest = new TenantMigrationTest(
+ {name: jsTestName(), sharedOptions: {nodes: 1}, recipientRst: recipientRst});
+const donorPrimary = tenantMigrationTest.getDonorPrimary();
+
+const tenantId = ObjectId();
+const tenantDB = tenantMigrationTest.tenantDB(tenantId.str, "DB");
+const collName = "testColl";
+
+// Do a majority write.
+tenantMigrationTest.insertDonorDB(tenantDB, collName);
+
+const migrationUuid = UUID();
+const migrationOpts = {
+ migrationIdString: extractUUIDFromObject(migrationUuid),
+ readPreference: {mode: 'primary'},
+ tenantIds: [tenantId],
+};
+
+// Start migration, and then wait for the migration to get committed and garbage collected.
+assert.commandWorked(
+ tenantMigrationTest.runMigration(migrationOpts, {automaticForgetMigration: true}));
+
+jsTestLog("Restart recipient primary.");
+// Do an unclean shutdown of the recipient primary, and then restart.
+recipientRst.restart(recipientPrimary, {allowedExitCode: MongoRunner.EXIT_SIGKILL}, 9);
+// Wait for the recipient primary to get elected.
+recipientRst.getPrimary();
+
+// Verify the imported donor data is still present on recipient even though the "Checkpointer"
+// thread didn’t take a checkpoint before node unclean restart.
+recipientRst.nodes.forEach(node => {
+ jsTestLog(`Checking ${tenantDB}.${collName} on ${node}`);
+ // Use "countDocuments" to check actual docs, "count" to check sizeStorer data.
+ assert.eq(donorPrimary.getDB(tenantDB)[collName].countDocuments({}),
+ node.getDB(tenantDB)[collName].countDocuments({}),
+ "countDocuments");
+ assert.eq(donorPrimary.getDB(tenantDB)[collName].count(),
+ node.getDB(tenantDB)[collName].count(),
+ "count");
+});
+
+tenantMigrationTest.stop();
+recipientRst.stopSet();
diff --git a/jstests/replsets/tenant_migration_recipient_shard_merge_learn_files.js b/jstests/replsets/tenant_migration_recipient_shard_merge_learn_files.js
index a4b8affa7a3..b1e8ab7d6c6 100644
--- a/jstests/replsets/tenant_migration_recipient_shard_merge_learn_files.js
+++ b/jstests/replsets/tenant_migration_recipient_shard_merge_learn_files.js
@@ -22,7 +22,7 @@ const tenantMigrationTest =
const recipientPrimary = tenantMigrationTest.getRecipientPrimary();
-// Note: including this explicit early return here due to the fact that multiversion
+// Note: Including this explicit early return here due to the fact that multiversion
// suites will execute this test without featureFlagShardMerge enabled (despite the
// presence of the featureFlagShardMerge tag above), which means the test will attempt
// to run a multi-tenant migration and fail.
@@ -59,6 +59,14 @@ assert.commandWorked(
waitInFailPoint.wait();
+// Before transitioning to `kConsistent` state, check that all recipient nodes have
+// "importDoneMarker" collection.
+const importMarkerCollName = "importDoneMarker." + extractUUIDFromObject(migrationUuid);
+tenantMigrationTest.getRecipientRst().nodes.forEach(node => {
+ jsTestLog(`Checking if the local.${importMarkerCollName} collection exists on ${node}`);
+ assert.eq(1, node.getDB("local").getCollectionInfos({name: importMarkerCollName}).length);
+});
+
tenantMigrationTest.assertRecipientNodesInExpectedState({
nodes: tenantMigrationTest.getRecipientRst().nodes,
migrationId: migrationUuid,
@@ -75,6 +83,7 @@ const donorPrimaryCountDocumentsResult = donorPrimary.getDB(tenantDB)[collName].
const donorPrimaryCountResult = donorPrimary.getDB(tenantDB)[collName].count();
tenantMigrationTest.getRecipientRst().nodes.forEach(node => {
+ jsTestLog(`Checking ${tenantDB}.${collName} on ${node}`);
// Use "countDocuments" to check actual docs, "count" to check sizeStorer data.
assert.eq(donorPrimaryCountDocumentsResult,
node.getDB(tenantDB)[collName].countDocuments({}),