diff options
author | Samy Lanka <samy.lanka@mongodb.com> | 2021-07-06 17:11:01 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-08-20 12:49:42 +0000 |
commit | a34cc0e3e211fa35f8acff1578accb7130d33331 (patch) | |
tree | e749831c2904a793dbfe8f96d3d6779dd4b1aa80 | |
parent | 5abee7caace84bd3f74db406ff1dd30b81a767f3 (diff) | |
download | mongo-a34cc0e3e211fa35f8acff1578accb7130d33331.tar.gz |
SERVER-57615 Reset CWWC to w:majority for tests that don't create/stop the replica set
(cherry picked from commit 56a3215462c4c5f0e6fb98c23beacdb39a6e5b41)
7 files changed, 267 insertions, 159 deletions
diff --git a/jstests/concurrency/fsm_workloads/map_reduce_interrupt.js b/jstests/concurrency/fsm_workloads/map_reduce_interrupt.js index 6130a73c91c..6113d7c9491 100644 --- a/jstests/concurrency/fsm_workloads/map_reduce_interrupt.js +++ b/jstests/concurrency/fsm_workloads/map_reduce_interrupt.js @@ -102,6 +102,26 @@ var $config = extendWorkload($config, function($config, $super) { assertAlways.commandWorked(localTempCollectionsResult); assertAlways.eq( localTempCollectionsResult.cursor.firstBatch.length, 0, localTempCollectionsResult); + + // Unsetting CWWC is not allowed, so explicitly restore the default write concern to be + // majority by setting CWWC to {w: majority}. + if (cluster.isReplication()) { + assert.commandWorked(db.adminCommand({ + setDefaultRWConcern: 1, + defaultWriteConcern: {w: "majority"}, + writeConcern: {w: "majority"} + })); + } + } else { + // Unsetting CWWC is not allowed, so explicitly restore the default write concern to be + // majority by setting CWWC to {w: majority}. + cluster.executeOnMongosNodes(function(db) { + assert.commandWorked(db.adminCommand({ + setDefaultRWConcern: 1, + defaultWriteConcern: {w: "majority"}, + writeConcern: {w: "majority"} + })); + }); } }; diff --git a/jstests/concurrency/fsm_workloads/multi_statement_transaction_atomicity_isolation.js b/jstests/concurrency/fsm_workloads/multi_statement_transaction_atomicity_isolation.js index 9084d01c8ad..58af9e5c798 100644 --- a/jstests/concurrency/fsm_workloads/multi_statement_transaction_atomicity_isolation.js +++ b/jstests/concurrency/fsm_workloads/multi_statement_transaction_atomicity_isolation.js @@ -362,6 +362,24 @@ var $config = (function() { const documents = this.getAllDocuments(this.numDocs, {useTxn: false}); checkTransactionCommitOrder(documents); checkNumUpdatedByEachTransaction(documents); + + // Unsetting CWWC is not allowed, so explicitly restore the default write concern to be + // majority by setting CWWC to {w: majority}. + if (cluster.isSharded()) { + cluster.executeOnMongosNodes(function(db) { + assert.commandWorked(db.adminCommand({ + setDefaultRWConcern: 1, + defaultWriteConcern: {w: "majority"}, + writeConcern: {w: "majority"} + })); + }); + } else if (cluster.isReplication()) { + assert.commandWorked(db.adminCommand({ + setDefaultRWConcern: 1, + defaultWriteConcern: {w: "majority"}, + writeConcern: {w: "majority"} + })); + } } return { diff --git a/jstests/concurrency/fsm_workloads/multi_statement_transaction_simple.js b/jstests/concurrency/fsm_workloads/multi_statement_transaction_simple.js index 86bbf3a0123..ef3178f9dc9 100644 --- a/jstests/concurrency/fsm_workloads/multi_statement_transaction_simple.js +++ b/jstests/concurrency/fsm_workloads/multi_statement_transaction_simple.js @@ -116,6 +116,24 @@ var $config = (function() { assertWhenOwnColl.eq(this.numAccounts * this.initialValue, computeTotalOfAllBalances(documents), () => tojson(documents)); + + // Unsetting CWWC is not allowed, so explicitly restore the default write concern to be + // majority by setting CWWC to {w: majority}. + if (cluster.isSharded()) { + cluster.executeOnMongosNodes(function(db) { + assert.commandWorked(db.adminCommand({ + setDefaultRWConcern: 1, + defaultWriteConcern: {w: "majority"}, + writeConcern: {w: "majority"} + })); + }); + } else if (cluster.isReplication()) { + assert.commandWorked(db.adminCommand({ + setDefaultRWConcern: 1, + defaultWriteConcern: {w: "majority"}, + writeConcern: {w: "majority"} + })); + } } var transitions = { diff --git a/jstests/concurrency/fsm_workloads/snapshot_read_kill_operations.js b/jstests/concurrency/fsm_workloads/snapshot_read_kill_operations.js index 8bdf573e073..ccefd552a3f 100644 --- a/jstests/concurrency/fsm_workloads/snapshot_read_kill_operations.js +++ b/jstests/concurrency/fsm_workloads/snapshot_read_kill_operations.js @@ -156,6 +156,24 @@ var $config = (function() { function teardown(db, collName, cluster) { // Make sure any currently running transactions are aborted. killSessionsFromDocs(db, collName); + + // Unsetting CWWC is not allowed, so explicitly restore the default write concern to be + // majority by setting CWWC to {w: majority}. + if (cluster.isSharded()) { + cluster.executeOnMongosNodes(function(db) { + assert.commandWorked(db.adminCommand({ + setDefaultRWConcern: 1, + defaultWriteConcern: {w: "majority"}, + writeConcern: {w: "majority"} + })); + }); + } else if (cluster.isReplication()) { + assert.commandWorked(db.adminCommand({ + setDefaultRWConcern: 1, + defaultWriteConcern: {w: "majority"}, + writeConcern: {w: "majority"} + })); + } } return { diff --git a/jstests/core/txns/new_transaction_waits_for_previous_txn_table_updates.js b/jstests/core/txns/new_transaction_waits_for_previous_txn_table_updates.js index fa6e611e5b6..0f4a710887e 100644 --- a/jstests/core/txns/new_transaction_waits_for_previous_txn_table_updates.js +++ b/jstests/core/txns/new_transaction_waits_for_previous_txn_table_updates.js @@ -102,46 +102,57 @@ const collName = jsTestName(); const testDB = db.getSiblingDB(dbName); testDB.runCommand({drop: collName}); -// The default WC is majority and this test can't satisfy majority writes. -assert.commandWorked(testDB.adminCommand( - {setDefaultRWConcern: 1, defaultWriteConcern: {w: 1}, writeConcern: {w: "majority"}})); -assert.commandWorked(testDB.runCommand({create: collName, writeConcern: {w: "majority"}})); - -const session = testDB.getMongo().startSession(); -const sessionDb = session.getDatabase(dbName); -const sessionColl = sessionDb.getCollection(collName); -const lsid = session.getSessionId(); - -// Start and prepare a transaction, txn0. -session.startTransaction(); -assert.commandWorked(sessionColl.insert({y: "prepare_insert"})); -const prepareTimestamp = PrepareHelpers.prepareTransaction(session); - -// Launch a concurrent transaction, txn1, which should block behind the active prepared -// transaction. -const awaitTxnShell = runConcurrentTransactionOnSession(dbName, collName, lsid); - -// Try to create a collection, which reserves an oplog slot. This oplog slot should be after the -// prepare oplog entry because we have already successfully prepared txn0 and returned a -// prepareTimestamp. -const awaitWriteShell = runConcurrentCollectionCreate(dbName, "newColl"); - -// Commit the original transaction - this should allow the parallel shell with txn1 to continue -// and start a new transaction. -// Note that we are not using PrepareHelpers.commitTransaction because it calls -// commitTransaction twice, and the second call races with txn1. -assert.commandWorked(session.getDatabase('admin').adminCommand( - {commitTransaction: 1, commitTimestamp: prepareTimestamp})); - -// Release this failpoint so that the createCollection command can finish. -assert.commandWorked(db.adminCommand( - {configureFailPoint: "hangAndFailAfterCreateCollectionReservesOpTime", mode: "off"})); - -// txn1 should be able to commit without getting a WriteConflictError. -awaitTxnShell(); - -// createCollection command fails with the expected error code, 51267. -awaitWriteShell(); - -session.endSession(); + +try { + // The default WC is majority and this test can't satisfy majority writes. + assert.commandWorked(testDB.adminCommand( + {setDefaultRWConcern: 1, defaultWriteConcern: {w: 1}, writeConcern: {w: "majority"}})); + assert.commandWorked(testDB.runCommand({create: collName, writeConcern: {w: "majority"}})); + + const session = testDB.getMongo().startSession(); + const sessionDb = session.getDatabase(dbName); + const sessionColl = sessionDb.getCollection(collName); + const lsid = session.getSessionId(); + + // Start and prepare a transaction, txn0. + session.startTransaction(); + assert.commandWorked(sessionColl.insert({y: "prepare_insert"})); + const prepareTimestamp = PrepareHelpers.prepareTransaction(session); + + // Launch a concurrent transaction, txn1, which should block behind the active prepared + // transaction. + const awaitTxnShell = runConcurrentTransactionOnSession(dbName, collName, lsid); + + // Try to create a collection, which reserves an oplog slot. This oplog slot should be after the + // prepare oplog entry because we have already successfully prepared txn0 and returned a + // prepareTimestamp. + const awaitWriteShell = runConcurrentCollectionCreate(dbName, "newColl"); + + // Commit the original transaction - this should allow the parallel shell with txn1 to continue + // and start a new transaction. + // Note that we are not using PrepareHelpers.commitTransaction because it calls + // commitTransaction twice, and the second call races with txn1. + assert.commandWorked(session.getDatabase('admin').adminCommand( + {commitTransaction: 1, commitTimestamp: prepareTimestamp})); + + // Release this failpoint so that the createCollection command can finish. + assert.commandWorked(db.adminCommand( + {configureFailPoint: "hangAndFailAfterCreateCollectionReservesOpTime", mode: "off"})); + + // txn1 should be able to commit without getting a WriteConflictError. + awaitTxnShell(); + + // createCollection command fails with the expected error code, 51267. + awaitWriteShell(); + + session.endSession(); +} finally { + // Unsetting CWWC is not allowed, so explicitly restore the default write concern to be majority + // by setting CWWC to {w: majority}. + assert.commandWorked(testDB.adminCommand({ + setDefaultRWConcern: 1, + defaultWriteConcern: {w: "majority"}, + writeConcern: {w: "majority"} + })); +} }()); diff --git a/jstests/core/txns/speculative_snapshot_includes_all_writes.js b/jstests/core/txns/speculative_snapshot_includes_all_writes.js index 99ea7beb183..7014ea3fa00 100644 --- a/jstests/core/txns/speculative_snapshot_includes_all_writes.js +++ b/jstests/core/txns/speculative_snapshot_includes_all_writes.js @@ -43,80 +43,92 @@ let checkReads = (session, collExpected, coll2Expected) => { // Clear ramlog so checkLog can't find log messages from previous times this fail point was // enabled. assert.commandWorked(testDB.adminCommand({clearLog: 'global'})); -// The default WC is majority and this test can't satisfy majority writes. -assert.commandWorked(testDB.adminCommand( - {setDefaultRWConcern: 1, defaultWriteConcern: {w: 1}, writeConcern: {w: "majority"}})); - -jsTest.log("Prepopulate the collections."); -assert.commandWorked(testColl.insert([{_id: 0}], {writeConcern: {w: "majority"}})); -assert.commandWorked(testColl2.insert([{_id: "a"}], {writeConcern: {w: "majority"}})); - -jsTest.log("Create the uncommitted write."); - -assert.commandWorked(db.adminCommand({ - configureFailPoint: "hangAfterCollectionInserts", - mode: "alwaysOn", - data: {collectionNS: testColl2.getFullName()} -})); - -const joinHungWrite = startParallelShell(() => { - assert.commandWorked(db.getSiblingDB("test").speculative_snapshot_includes_all_writes_2.insert( - {_id: "b"}, {writeConcern: {w: "majority"}})); -}); - -if (isJsonLog(db.getMongo())) { - checkLog.containsJson(db.getMongo(), 20289); -} else { - checkLog.contains( - db.getMongo(), - "hangAfterCollectionInserts fail point enabled for " + testColl2.getFullName()); -} - -jsTest.log("Create a write following the uncommitted write."); -// Note this write must use local write concern; it cannot be majority committed until -// the prior uncommitted write is committed. -assert.commandWorked(testColl.insert([{_id: 1}])); - -const snapshotSession = startSessionAndTransaction({level: "snapshot"}); -checkReads(snapshotSession, [{_id: 0}], [{_id: "a"}]); - -const majoritySession = startSessionAndTransaction({level: "majority"}); -checkReads(majoritySession, [{_id: 0}, {_id: 1}], [{_id: "a"}]); - -const localSession = startSessionAndTransaction({level: "local"}); -checkReads(localSession, [{_id: 0}, {_id: 1}], [{_id: "a"}]); - -const defaultSession = startSessionAndTransaction({}); -checkReads(defaultSession, [{_id: 0}, {_id: 1}], [{_id: "a"}]); - -jsTestLog("Allow the uncommitted write to finish."); -assert.commandWorked(db.adminCommand({ - configureFailPoint: "hangAfterCollectionInserts", - mode: "off", -})); -joinHungWrite(); - -jsTestLog("Double-checking that writes not committed at start of snapshot cannot appear."); -checkReads(snapshotSession, [{_id: 0}], [{_id: "a"}]); - -jsTestLog( - "Double-checking that writes performed before the start of a transaction of 'majority' or lower must appear."); -checkReads(majoritySession, [{_id: 0}, {_id: 1}], [{_id: "a"}]); -checkReads(localSession, [{_id: 0}, {_id: 1}], [{_id: "a"}]); -checkReads(defaultSession, [{_id: 0}, {_id: 1}], [{_id: "a"}]); - -jsTestLog("Committing transactions."); -assert.commandWorked(snapshotSession.commitTransaction_forTesting()); -assert.commandWorked(majoritySession.commitTransaction_forTesting()); -assert.commandWorked(localSession.commitTransaction_forTesting()); -assert.commandWorked(defaultSession.commitTransaction_forTesting()); - -jsTestLog("A new local read must see all committed writes."); -checkReads(defaultSession, [{_id: 0}, {_id: 1}], [{_id: "a"}, {_id: "b"}]); - -snapshotSession.endSession(); -majoritySession.endSession(); -localSession.endSession(); -defaultSession.endSession(); +try { + // The default WC is majority and this test can't satisfy majority writes. + assert.commandWorked(testDB.adminCommand( + {setDefaultRWConcern: 1, defaultWriteConcern: {w: 1}, writeConcern: {w: "majority"}})); + + jsTest.log("Prepopulate the collections."); + assert.commandWorked(testColl.insert([{_id: 0}], {writeConcern: {w: "majority"}})); + assert.commandWorked(testColl2.insert([{_id: "a"}], {writeConcern: {w: "majority"}})); + + jsTest.log("Create the uncommitted write."); + + assert.commandWorked(db.adminCommand({ + configureFailPoint: "hangAfterCollectionInserts", + mode: "alwaysOn", + data: {collectionNS: testColl2.getFullName()} + })); + + const joinHungWrite = startParallelShell(() => { + assert.commandWorked( + db.getSiblingDB("test").speculative_snapshot_includes_all_writes_2.insert( + {_id: "b"}, {writeConcern: {w: "majority"}})); + }); + + if (isJsonLog(db.getMongo())) { + checkLog.containsJson(db.getMongo(), 20289); + } else { + checkLog.contains( + db.getMongo(), + "hangAfterCollectionInserts fail point enabled for " + testColl2.getFullName()); + } + + jsTest.log("Create a write following the uncommitted write."); + // Note this write must use local write concern; it cannot be majority committed until + // the prior uncommitted write is committed. + assert.commandWorked(testColl.insert([{_id: 1}])); + + const snapshotSession = startSessionAndTransaction({level: "snapshot"}); + checkReads(snapshotSession, [{_id: 0}], [{_id: "a"}]); + + const majoritySession = startSessionAndTransaction({level: "majority"}); + checkReads(majoritySession, [{_id: 0}, {_id: 1}], [{_id: "a"}]); + + const localSession = startSessionAndTransaction({level: "local"}); + checkReads(localSession, [{_id: 0}, {_id: 1}], [{_id: "a"}]); + + const defaultSession = startSessionAndTransaction({}); + checkReads(defaultSession, [{_id: 0}, {_id: 1}], [{_id: "a"}]); + + jsTestLog("Allow the uncommitted write to finish."); + assert.commandWorked(db.adminCommand({ + configureFailPoint: "hangAfterCollectionInserts", + mode: "off", + })); + + joinHungWrite(); + + jsTestLog("Double-checking that writes not committed at start of snapshot cannot appear."); + checkReads(snapshotSession, [{_id: 0}], [{_id: "a"}]); + + jsTestLog( + "Double-checking that writes performed before the start of a transaction of 'majority' or lower must appear."); + checkReads(majoritySession, [{_id: 0}, {_id: 1}], [{_id: "a"}]); + checkReads(localSession, [{_id: 0}, {_id: 1}], [{_id: "a"}]); + checkReads(defaultSession, [{_id: 0}, {_id: 1}], [{_id: "a"}]); + + jsTestLog("Committing transactions."); + assert.commandWorked(snapshotSession.commitTransaction_forTesting()); + assert.commandWorked(majoritySession.commitTransaction_forTesting()); + assert.commandWorked(localSession.commitTransaction_forTesting()); + assert.commandWorked(defaultSession.commitTransaction_forTesting()); + + jsTestLog("A new local read must see all committed writes."); + checkReads(defaultSession, [{_id: 0}, {_id: 1}], [{_id: "a"}, {_id: "b"}]); + + snapshotSession.endSession(); + majoritySession.endSession(); + localSession.endSession(); + defaultSession.endSession(); +} finally { + // Unsetting CWWC is not allowed, so explicitly restore the default write concern to be majority + // by setting CWWC to {w: majority}. + assert.commandWorked(testDB.adminCommand({ + setDefaultRWConcern: 1, + defaultWriteConcern: {w: "majority"}, + writeConcern: {w: "majority"} + })); +} }()); diff --git a/jstests/core/txns/timestamped_reads_wait_for_prepare_oplog_visibility.js b/jstests/core/txns/timestamped_reads_wait_for_prepare_oplog_visibility.js index 6138e4b54df..c44733a8cb2 100644 --- a/jstests/core/txns/timestamped_reads_wait_for_prepare_oplog_visibility.js +++ b/jstests/core/txns/timestamped_reads_wait_for_prepare_oplog_visibility.js @@ -69,54 +69,65 @@ const readThreadFunc = function(readFunc, _collName, hangTimesEntered, logTimesE function runTest(prefix, readFunc) { // Reset the log history between tests. assert.commandWorked(db.adminCommand({clearLog: 'global'})); - // The default WC is majority and this test can't satisfy majority writes. - assert.commandWorked(db.adminCommand( - {setDefaultRWConcern: 1, defaultWriteConcern: {w: 1}, writeConcern: {w: "majority"}})); - jsTestLog('Testing oplog visibility for ' + prefix); - const collName = baseCollName + '_' + prefix; - const testColl = testDB.getCollection(collName); + try { + // The default WC is majority and this test can't satisfy majority writes. + assert.commandWorked(db.adminCommand( + {setDefaultRWConcern: 1, defaultWriteConcern: {w: 1}, writeConcern: {w: "majority"}})); - testColl.drop({writeConcern: {w: "majority"}}); - assert.commandWorked(testDB.runCommand({create: collName, writeConcern: {w: 'majority'}})); + jsTestLog('Testing oplog visibility for ' + prefix); + const collName = baseCollName + '_' + prefix; + const testColl = testDB.getCollection(collName); - let hangFailPoint = configureFailPoint(testDB, "hangAfterReservingPrepareTimestamp"); - let logFailPoint = configureFailPoint(testDB, "waitForPrepareTransactionCommandLogged"); + testColl.drop({writeConcern: {w: "majority"}}); + assert.commandWorked(testDB.runCommand({create: collName, writeConcern: {w: 'majority'}})); - // Insert a document for the transaction. - assert.commandWorked(testColl.insert(TestData.txnDoc)); - // Insert a document untouched by the transaction. - assert.commandWorked(testColl.insert(TestData.otherDoc, {writeConcern: {w: "majority"}})); + let hangFailPoint = configureFailPoint(testDB, "hangAfterReservingPrepareTimestamp"); + let logFailPoint = configureFailPoint(testDB, "waitForPrepareTransactionCommandLogged"); - // Start a transaction with a single update on the 'txnDoc'. - const session = db.getMongo().startSession({causalConsistency: false}); - const sessionDB = session.getDatabase(TestData.dbName); - session.startTransaction({readConcern: {level: 'snapshot'}}); - const updateResult = - assert.commandWorked(sessionDB[collName].update(TestData.txnDoc, {$inc: {x: 1}})); - // Make sure that txnDoc is part of both the snapshot and transaction as an update can still - // succeed if it doesn't find any matching documents to modify. - assert.eq(updateResult["nModified"], 1); - - // We set the log level up to know when 'prepareTransaction' completes. - db.setLogLevel(1); - - // Clear the log history to ensure we only see the most recent 'prepareTransaction' - // failpoint log message. - assert.commandWorked(db.adminCommand({clearLog: 'global'})); - const joinReadThread = startParallelShell(funWithArgs(readThreadFunc, - readFunc, - collName, - hangFailPoint.timesEntered + 1, - logFailPoint.timesEntered + 1)); - - jsTestLog("Preparing the transaction for " + prefix); - const prepareTimestamp = PrepareHelpers.prepareTransaction(session); + // Insert a document for the transaction. + assert.commandWorked(testColl.insert(TestData.txnDoc)); + // Insert a document untouched by the transaction. + assert.commandWorked(testColl.insert(TestData.otherDoc, {writeConcern: {w: "majority"}})); - db.setLogLevel(0); - joinReadThread({checkExitSuccess: true}); - - PrepareHelpers.commitTransaction(session, prepareTimestamp); + // Start a transaction with a single update on the 'txnDoc'. + const session = db.getMongo().startSession({causalConsistency: false}); + const sessionDB = session.getDatabase(TestData.dbName); + session.startTransaction({readConcern: {level: 'snapshot'}}); + const updateResult = + assert.commandWorked(sessionDB[collName].update(TestData.txnDoc, {$inc: {x: 1}})); + // Make sure that txnDoc is part of both the snapshot and transaction as an update can still + // succeed if it doesn't find any matching documents to modify. + assert.eq(updateResult["nModified"], 1); + + // We set the log level up to know when 'prepareTransaction' completes. + db.setLogLevel(1); + + // Clear the log history to ensure we only see the most recent 'prepareTransaction' + // failpoint log message. + assert.commandWorked(db.adminCommand({clearLog: 'global'})); + const joinReadThread = startParallelShell(funWithArgs(readThreadFunc, + readFunc, + collName, + hangFailPoint.timesEntered + 1, + logFailPoint.timesEntered + 1)); + + jsTestLog("Preparing the transaction for " + prefix); + const prepareTimestamp = PrepareHelpers.prepareTransaction(session); + + db.setLogLevel(0); + joinReadThread({checkExitSuccess: true}); + + PrepareHelpers.commitTransaction(session, prepareTimestamp); + } finally { + // Unsetting CWWC is not allowed, so explicitly restore the default write concern to be + // majority by setting CWWC to {w: majority}. + assert.commandWorked(db.adminCommand({ + setDefaultRWConcern: 1, + defaultWriteConcern: {w: "majority"}, + writeConcern: {w: "majority"} + })); + } } const snapshotRead = function(_collName) { |