diff options
author | Lingzhi Deng <lingzhi.deng@mongodb.com> | 2019-05-09 11:24:40 -0400 |
---|---|---|
committer | Lingzhi Deng <lingzhi.deng@mongodb.com> | 2019-05-09 14:43:02 -0400 |
commit | 204352fb65123323bb50800741b1b322fe648f15 (patch) | |
tree | 36b35ae03170c836f4ae1b5da74db8fe154351af | |
parent | 399fad74e2f313b87886c9511a66ae2bab102a24 (diff) | |
download | mongo-204352fb65123323bb50800741b1b322fe648f15.tar.gz |
SERVER-41008: Check lastCommittedOpTime instead of awaitReplication for tests that prepare with {w: 1}
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"); |