summaryrefslogtreecommitdiff
path: root/jstests/replsets/reconstruct_prepared_transactions_initial_sync_index_build.js
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/replsets/reconstruct_prepared_transactions_initial_sync_index_build.js')
-rw-r--r--jstests/replsets/reconstruct_prepared_transactions_initial_sync_index_build.js234
1 files changed, 118 insertions, 116 deletions
diff --git a/jstests/replsets/reconstruct_prepared_transactions_initial_sync_index_build.js b/jstests/replsets/reconstruct_prepared_transactions_initial_sync_index_build.js
index 274c2eb4d94..a9f35921e8e 100644
--- a/jstests/replsets/reconstruct_prepared_transactions_initial_sync_index_build.js
+++ b/jstests/replsets/reconstruct_prepared_transactions_initial_sync_index_build.js
@@ -7,120 +7,122 @@
*/
(function() {
- "use strict";
-
- load("jstests/libs/check_log.js");
- load("jstests/core/txns/libs/prepare_helpers.js");
-
- const replTest = new ReplSetTest({nodes: 2});
- replTest.startSet();
-
- const config = replTest.getReplSetConfig();
- // Increase the election timeout so that we do not accidentally trigger an election while the
- // secondary is restarting.
- config.settings = {"electionTimeoutMillis": 12 * 60 * 60 * 1000};
- replTest.initiate(config);
-
- const primary = replTest.getPrimary();
- let secondary = replTest.getSecondary();
-
- const dbName = "test";
- const collName = "reconstruct_prepared_transactions_initial_sync_index_build";
- let testDB = primary.getDB(dbName);
- let testColl = testDB.getCollection(collName);
-
- assert.commandWorked(testColl.insert({_id: 0}));
-
- jsTestLog("Restarting the secondary");
-
- // Restart the secondary with startClean set to true so that it goes through initial sync. Also
- // restart the node with a failpoint turned on that will pause initial sync. This way we can do
- // some writes on the sync source while initial sync is paused and know that its operations
- // won't be copied during collection cloning. Instead, the writes must be applied during oplog
- // application.
- replTest.stop(secondary, undefined /* signal */, {skipValidation: true});
- secondary = replTest.start(
- secondary,
- {
- startClean: true,
- setParameter: {
- 'failpoint.initialSyncHangDuringCollectionClone': tojson(
- {mode: 'alwaysOn', data: {namespace: testColl.getFullName(), numDocsToClone: 1}}),
- 'numInitialSyncAttempts': 1
- }
- },
- true /* wait */);
-
- // Wait for failpoint to be reached so we know that collection cloning is paused.
- checkLog.contains(secondary, "initialSyncHangDuringCollectionClone fail point enabled");
-
- jsTestLog("Running operations while collection cloning is paused");
-
- // Perform writes while collection cloning is paused so that we know they must be applied during
- // the oplog application stage of initial sync.
- assert.commandWorked(testColl.insert({_id: 1, a: 1}));
- assert.commandWorked(testColl.createIndex({a: 1}));
- // Make the index build hang on the secondary so that initial sync gets to the prepared-txn
- // reconstruct stage with the index build still running.
- assert.commandWorked(secondary.adminCommand(
- {configureFailPoint: 'hangAfterStartingIndexBuild', mode: "alwaysOn"}));
-
- let session = primary.startSession();
- let sessionDB = session.getDatabase(dbName);
- const sessionColl = sessionDB.getCollection(collName);
-
- jsTestLog("Preparing the transaction");
-
- // Prepare a transaction while collection cloning is paused so that its oplog entry must be
- // applied during the oplog application phase of initial sync.
- session.startTransaction();
- assert.commandWorked(sessionColl.update({_id: 1, a: 1}, {_id: 1, a: 2}));
- const prepareTimestamp = PrepareHelpers.prepareTransaction(session, {w: 1});
-
- clearRawMongoProgramOutput();
- jsTestLog("Resuming initial sync");
-
- // Resume initial sync.
- assert.commandWorked(secondary.adminCommand(
- {configureFailPoint: "initialSyncHangDuringCollectionClone", mode: "off"}));
-
- // Wait for log message.
- assert.soon(
- () =>
- rawMongoProgramOutput().indexOf(
- "blocking replication until index builds are finished on test.reconstruct_prepared_transactions_initial_sync_index_build, due to prepared transaction") >=
- 0,
- "replication not hanging");
-
- // Unblock index build.
- assert.commandWorked(
- secondary.adminCommand({configureFailPoint: 'hangAfterStartingIndexBuild', mode: "off"}));
-
- // Wait for the secondary to complete initial sync.
- replTest.awaitSecondaryNodes();
-
- jsTestLog("Initial sync completed");
-
- secondary.setSlaveOk();
- const secondaryColl = secondary.getDB(dbName).getCollection(collName);
-
- // Make sure that while reading from the node that went through initial sync, we can't read
- // changes to the documents from the prepared transaction after initial sync. Also, make
- // sure that the writes that happened when collection cloning was paused happened.
- const res = secondaryColl.find().sort({_id: 1}).toArray();
- assert.eq(res, [{_id: 0}, {_id: 1, a: 1}], res);
-
- // Wait for the prepared transaction oplog entry to be majority committed before committing the
- // transaction.
- PrepareHelpers.awaitMajorityCommitted(replTest, prepareTimestamp);
-
- jsTestLog("Committing the transaction");
-
- assert.commandWorked(PrepareHelpers.commitTransaction(session, prepareTimestamp));
- replTest.awaitReplication();
-
- // Make sure that we can see the data from the committed transaction on the secondary.
- assert.docEq(secondaryColl.findOne({_id: 1}), {_id: 1, a: 2});
-
- replTest.stopSet();
+"use strict";
+
+load("jstests/libs/check_log.js");
+load("jstests/core/txns/libs/prepare_helpers.js");
+
+const replTest = new ReplSetTest({nodes: 2});
+replTest.startSet();
+
+const config = replTest.getReplSetConfig();
+// Increase the election timeout so that we do not accidentally trigger an election while the
+// secondary is restarting.
+config.settings = {
+ "electionTimeoutMillis": 12 * 60 * 60 * 1000
+};
+replTest.initiate(config);
+
+const primary = replTest.getPrimary();
+let secondary = replTest.getSecondary();
+
+const dbName = "test";
+const collName = "reconstruct_prepared_transactions_initial_sync_index_build";
+let testDB = primary.getDB(dbName);
+let testColl = testDB.getCollection(collName);
+
+assert.commandWorked(testColl.insert({_id: 0}));
+
+jsTestLog("Restarting the secondary");
+
+// Restart the secondary with startClean set to true so that it goes through initial sync. Also
+// restart the node with a failpoint turned on that will pause initial sync. This way we can do
+// some writes on the sync source while initial sync is paused and know that its operations
+// won't be copied during collection cloning. Instead, the writes must be applied during oplog
+// application.
+replTest.stop(secondary, undefined /* signal */, {skipValidation: true});
+secondary = replTest.start(
+ secondary,
+ {
+ startClean: true,
+ setParameter: {
+ 'failpoint.initialSyncHangDuringCollectionClone': tojson(
+ {mode: 'alwaysOn', data: {namespace: testColl.getFullName(), numDocsToClone: 1}}),
+ 'numInitialSyncAttempts': 1
+ }
+ },
+ true /* wait */);
+
+// Wait for failpoint to be reached so we know that collection cloning is paused.
+checkLog.contains(secondary, "initialSyncHangDuringCollectionClone fail point enabled");
+
+jsTestLog("Running operations while collection cloning is paused");
+
+// Perform writes while collection cloning is paused so that we know they must be applied during
+// the oplog application stage of initial sync.
+assert.commandWorked(testColl.insert({_id: 1, a: 1}));
+assert.commandWorked(testColl.createIndex({a: 1}));
+// Make the index build hang on the secondary so that initial sync gets to the prepared-txn
+// reconstruct stage with the index build still running.
+assert.commandWorked(
+ secondary.adminCommand({configureFailPoint: 'hangAfterStartingIndexBuild', mode: "alwaysOn"}));
+
+let session = primary.startSession();
+let sessionDB = session.getDatabase(dbName);
+const sessionColl = sessionDB.getCollection(collName);
+
+jsTestLog("Preparing the transaction");
+
+// Prepare a transaction while collection cloning is paused so that its oplog entry must be
+// applied during the oplog application phase of initial sync.
+session.startTransaction();
+assert.commandWorked(sessionColl.update({_id: 1, a: 1}, {_id: 1, a: 2}));
+const prepareTimestamp = PrepareHelpers.prepareTransaction(session, {w: 1});
+
+clearRawMongoProgramOutput();
+jsTestLog("Resuming initial sync");
+
+// Resume initial sync.
+assert.commandWorked(secondary.adminCommand(
+ {configureFailPoint: "initialSyncHangDuringCollectionClone", mode: "off"}));
+
+// Wait for log message.
+assert.soon(
+ () =>
+ rawMongoProgramOutput().indexOf(
+ "blocking replication until index builds are finished on test.reconstruct_prepared_transactions_initial_sync_index_build, due to prepared transaction") >=
+ 0,
+ "replication not hanging");
+
+// Unblock index build.
+assert.commandWorked(
+ secondary.adminCommand({configureFailPoint: 'hangAfterStartingIndexBuild', mode: "off"}));
+
+// Wait for the secondary to complete initial sync.
+replTest.awaitSecondaryNodes();
+
+jsTestLog("Initial sync completed");
+
+secondary.setSlaveOk();
+const secondaryColl = secondary.getDB(dbName).getCollection(collName);
+
+// Make sure that while reading from the node that went through initial sync, we can't read
+// changes to the documents from the prepared transaction after initial sync. Also, make
+// sure that the writes that happened when collection cloning was paused happened.
+const res = secondaryColl.find().sort({_id: 1}).toArray();
+assert.eq(res, [{_id: 0}, {_id: 1, a: 1}], res);
+
+// Wait for the prepared transaction oplog entry to be majority committed before committing the
+// transaction.
+PrepareHelpers.awaitMajorityCommitted(replTest, prepareTimestamp);
+
+jsTestLog("Committing the transaction");
+
+assert.commandWorked(PrepareHelpers.commitTransaction(session, prepareTimestamp));
+replTest.awaitReplication();
+
+// Make sure that we can see the data from the committed transaction on the secondary.
+assert.docEq(secondaryColl.findOne({_id: 1}), {_id: 1, a: 2});
+
+replTest.stopSet();
})();