summaryrefslogtreecommitdiff
path: root/jstests/replsets
diff options
context:
space:
mode:
authorA. Jesse Jiryu Davis <jesse@mongodb.com>2021-12-06 18:26:12 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-12-06 18:50:24 +0000
commitea6a59377c01ed48157557aaaae0bd8191b7fa4e (patch)
tree45b158df64366a4fbac7186a55b54234bd865792 /jstests/replsets
parent9707356f1afe773e29b64858835f55a4a93d35d8 (diff)
downloadmongo-ea6a59377c01ed48157557aaaae0bd8191b7fa4e.tar.gz
SERVER-61666 Fix migration for txns before startApplying
Diffstat (limited to 'jstests/replsets')
-rw-r--r--jstests/replsets/tenant_migration_transaction_boundary.js88
1 files changed, 88 insertions, 0 deletions
diff --git a/jstests/replsets/tenant_migration_transaction_boundary.js b/jstests/replsets/tenant_migration_transaction_boundary.js
new file mode 100644
index 00000000000..4696aa61412
--- /dev/null
+++ b/jstests/replsets/tenant_migration_transaction_boundary.js
@@ -0,0 +1,88 @@
+/**
+ * Test a (non-prepared) large-format committed transaction T, with at least one oplog entry before
+ * startFetchingDonorOpTime, and a commit OpTime between startFetchingDonorOpTime and
+ * startApplyingAfterOpTime.
+ *
+ * Donor Oplog
+ * *-------------------*-------------------*-------------------*
+ * T applyOps entry startFetching T commit entry startApplying
+ * |
+ * <-------------- prevOpTime -------------*
+ *
+ * The recipient doesn't need to recover T's oplog chain, since T committed before startApplying,
+ * and trying to recover T would fail because the recipient didn't fetch T's oldest entries.
+ *
+ * @tags: [
+ * incompatible_with_eft,
+ * incompatible_with_macos,
+ * incompatible_with_windows_tls,
+ * requires_majority_read_concern,
+ * requires_persistence,
+ * ]
+ */
+
+(function() {
+"use strict";
+
+load("jstests/replsets/libs/tenant_migration_test.js");
+load("jstests/replsets/libs/tenant_migration_util.js");
+load("jstests/replsets/rslib.js");
+load("jstests/libs/uuid_util.js");
+
+const tenantMigrationTest = new TenantMigrationTest({name: jsTestName()});
+
+const tenantId = "testTenantId";
+const tenantDB = tenantMigrationTest.tenantDB(tenantId, "testDB");
+const collName = "testColl";
+const tenantNS = `${tenantDB}.${collName}`;
+const transactionsNS = "config.transactions";
+
+const donorPrimary = tenantMigrationTest.getDonorPrimary();
+const recipientPrimary = tenantMigrationTest.getRecipientPrimary();
+
+jsTestLog("Running a migration");
+const migrationId = UUID();
+const migrationOpts = {
+ migrationIdString: extractUUIDFromObject(migrationId),
+ tenantId,
+};
+
+jsTestLog("Hang just before getting start opTimes from donor");
+let fp =
+ configureFailPoint(recipientPrimary, "fpAfterComparingRecipientAndDonorFCV", {action: "hang"});
+tenantMigrationTest.startMigration(migrationOpts);
+
+fp.wait();
+
+{
+ // This transaction will straddle startFetching - the oplog entry for the commit will have a
+ // timestamp equal to startFetching, and previous entries will have timestamps earlier than it.
+ jsTestLog("Run and commit a transaction prior to the migration");
+ const session = donorPrimary.startSession({causalConsistency: false});
+ const sessionDb = session.getDatabase(tenantDB);
+ const sessionColl = sessionDb.getCollection(collName);
+
+ function makeLargeDoc(numMB) {
+ return {x: new Array(numMB * 1024 * 1024).join('A')};
+ }
+
+ session.startTransaction();
+ sessionColl.insert({doc: makeLargeDoc(10)});
+ sessionColl.insert({doc: makeLargeDoc(5)});
+ sessionColl.insert({doc: makeLargeDoc(5)});
+ let commitRes = session.commitTransaction_forTesting();
+ assert.eq(1, commitRes.ok);
+ session.endSession();
+}
+
+jsTestLog("LastWriteOpTime of transaction is " +
+ tojson(donorPrimary.getCollection(transactionsNS)
+ .find({}, {"_id": -1, "lastWriteOpTime": 1})
+ .toArray()));
+
+fp.off();
+TenantMigrationTest.assertCommitted(tenantMigrationTest.waitForMigrationToComplete(migrationOpts));
+assert.eq(recipientPrimary.getCollection(tenantNS).countDocuments({}), 3);
+assert.eq(recipientPrimary.getCollection(tenantNS).count(), 3);
+tenantMigrationTest.stop();
+})();