summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLingzhi Deng <lingzhi.deng@mongodb.com>2019-05-09 11:24:40 -0400
committerLingzhi Deng <lingzhi.deng@mongodb.com>2019-05-09 14:43:02 -0400
commit204352fb65123323bb50800741b1b322fe648f15 (patch)
tree36b35ae03170c836f4ae1b5da74db8fe154351af
parent399fad74e2f313b87886c9511a66ae2bab102a24 (diff)
downloadmongo-204352fb65123323bb50800741b1b322fe648f15.tar.gz
SERVER-41008: Check lastCommittedOpTime instead of awaitReplication for tests that prepare with {w: 1}
-rw-r--r--jstests/core/txns/libs/prepare_helpers.js21
-rw-r--r--jstests/replsets/prepare_transaction_index_build.js13
-rw-r--r--jstests/replsets/recover_prepared_transactions_startup_secondary_application.js8
3 files changed, 35 insertions, 7 deletions
diff --git a/jstests/core/txns/libs/prepare_helpers.js b/jstests/core/txns/libs/prepare_helpers.js
index 1bbabf2d224..f6a33bbcfc6 100644
--- a/jstests/core/txns/libs/prepare_helpers.js
+++ b/jstests/core/txns/libs/prepare_helpers.js
@@ -123,6 +123,24 @@ const PrepareHelpers = (function() {
}
}
+ /**
+ * Waits for the oplog entry of the given timestamp to be majority committed.
+ */
+ function awaitMajorityCommitted(replSet, timestamp) {
+ print(`Waiting for majority commit point to advance past the given timestamp ${timestamp}`);
+ const primary = replSet.getPrimary();
+ assert.soon(() => {
+ const ts = assert.commandWorked(primary.adminCommand({replSetGetStatus: 1}))
+ .optimes.lastCommittedOpTime.ts;
+ if (ts >= timestamp) {
+ return true;
+ } else {
+ print(`Awaiting lastCommittedOpTime.ts, now at ${ts}`);
+ return false;
+ }
+ }, "Timeout waiting for majority commit point", ReplSetTest.kDefaultTimeoutMS, 1000);
+ }
+
return {
prepareTransaction: prepareTransaction,
commitTransaction: commitTransaction,
@@ -131,6 +149,7 @@ const PrepareHelpers = (function() {
oplogSizeBytes: oplogSizeBytes,
replSetStartSetOptions: {oplogSize: oplogSizeMB},
growOplogPastMaxSize: growOplogPastMaxSize,
- awaitOplogTruncation: awaitOplogTruncation
+ awaitOplogTruncation: awaitOplogTruncation,
+ awaitMajorityCommitted: awaitMajorityCommitted
};
})();
diff --git a/jstests/replsets/prepare_transaction_index_build.js b/jstests/replsets/prepare_transaction_index_build.js
index 543d9b919e9..cac5445c139 100644
--- a/jstests/replsets/prepare_transaction_index_build.js
+++ b/jstests/replsets/prepare_transaction_index_build.js
@@ -48,6 +48,7 @@
assert.commandWorked(sessionColl.insert({x: 1000}));
const prepareTimestamp = PrepareHelpers.prepareTransaction(session, {w: 1});
+ jsTestLog("Prepared a transaction at " + prepareTimestamp);
jsTestLog("Unblocking index build.");
@@ -55,11 +56,13 @@
secondary.getDB("admin").runCommand(
{configureFailPoint: 'hangAfterStartingIndexBuild', mode: 'off'});
- jsTestLog("Waiting for all index builds to finish on all nodes.");
-
- // wait for the index build to finish; we know it's done if the prepare has finished on the
- // secondary.
- replTest.awaitReplication();
+ // It's illegal to commit a prepared transaction before its prepare oplog entry has been
+ // majority committed. So wait for prepare oplog entry to be majority committed before issuing
+ // the commitTransaction command. We know the index build is also done if the prepare has
+ // finished on the secondary.
+ jsTestLog(
+ "Waiting for prepare oplog entry to be majority committed and all index builds to finish on all nodes.");
+ PrepareHelpers.awaitMajorityCommitted(replTest, prepareTimestamp);
jsTestLog("Committing txn");
// Commit the transaction.
diff --git a/jstests/replsets/recover_prepared_transactions_startup_secondary_application.js b/jstests/replsets/recover_prepared_transactions_startup_secondary_application.js
index cd7a6ddefc0..215d97b5157 100644
--- a/jstests/replsets/recover_prepared_transactions_startup_secondary_application.js
+++ b/jstests/replsets/recover_prepared_transactions_startup_secondary_application.js
@@ -47,10 +47,12 @@
session.startTransaction();
assert.commandWorked(sessionColl.update({_id: 1}, {_id: 1, a: 1}));
let prepareTimestamp = PrepareHelpers.prepareTransaction(session, {w: 1});
+ jsTestLog("Prepared a transaction at " + prepareTimestamp);
session2.startTransaction();
assert.commandWorked(sessionColl2.update({_id: 2}, {_id: 2, a: 1}));
const prepareTimestamp2 = PrepareHelpers.prepareTransaction(session2, {w: 1});
+ jsTestLog("Prepared another transaction at " + prepareTimestamp2);
const lsid = session.getSessionId();
const txnNumber = session.getTxnNumber_forTesting();
@@ -71,7 +73,11 @@
assert.commandWorked(
primary.adminCommand({configureFailPoint: "disableSnapshotting", mode: "off"}));
- replTest.awaitReplication();
+
+ // It's illegal to commit a prepared transaction before its prepare oplog entry has been
+ // majority committed. So wait for prepare oplog entry to be majority committed before issuing
+ // the commitTransaction command.
+ PrepareHelpers.awaitMajorityCommitted(replTest, prepareTimestamp2);
jsTestLog("Checking that the first transaction is properly prepared");