diff options
author | Jack Mulrow <jack.mulrow@mongodb.com> | 2019-01-08 16:28:05 -0500 |
---|---|---|
committer | Jack Mulrow <jack.mulrow@mongodb.com> | 2019-03-21 14:55:29 -0400 |
commit | 8284b68fd265df73ab60f15f97ae3ada145f49d2 (patch) | |
tree | 68236aa29f5c004761c77bee772110064a016911 | |
parent | 425f97c9d1aeb14a92730e86a68bc2bdd3200d09 (diff) | |
download | mongo-8284b68fd265df73ab60f15f97ae3ada145f49d2.tar.gz |
SERVER-38436 Add concurrency workload for majority writes alongside transactions
-rw-r--r-- | jstests/concurrency/fsm_workloads/multi_statement_transaction_simple_majority_writes.js | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/jstests/concurrency/fsm_workloads/multi_statement_transaction_simple_majority_writes.js b/jstests/concurrency/fsm_workloads/multi_statement_transaction_simple_majority_writes.js new file mode 100644 index 00000000000..2e52765014c --- /dev/null +++ b/jstests/concurrency/fsm_workloads/multi_statement_transaction_simple_majority_writes.js @@ -0,0 +1,105 @@ +'use strict'; + +/** + * Performs concurrent majority writes alongside transactions to verify both will eventually + * complete as expected. + * + * The base workload assumes transactions run at snapshot read concern, so the tag is copied here. + * @tags: [uses_transactions, assumes_snapshot_transactions] + */ + +load('jstests/concurrency/fsm_libs/extend_workload.js'); // for extendWorkload +load('jstests/concurrency/fsm_workloads/multi_statement_transaction_simple.js'); // for $config +load('jstests/concurrency/fsm_workload_helpers/server_types.js'); // for isMongos + +var $config = extendWorkload($config, function($config, $super) { + + $config.data.majorityWriteCollName = 'majority_writes'; + $config.data.counter = 0; + + /** + * Runs the base workload's init state function and inserts a document to be majority updated + * later by this thread. + */ + $config.states.init = function init(db, collName) { + $super.states.init.apply(this, arguments); + + assertWhenOwnColl.writeOK(db[this.majorityWriteCollName].insert( + {_id: this.tid, counter: this.counter}, {writeConcern: {w: 'majority'}})); + }; + + /** + * Updates a document unrelated to the transaction run in the base workload using majority write + * concern and verifies the update is immediately visible in the majority snapshot once the + * write returns. + */ + $config.states.majorityWriteUnrelatedDoc = function majorityWriteUnrelatedDoc(db, collName) { + this.counter += 1; + assertWhenOwnColl.writeOK(db[this.majorityWriteCollName].update( + {_id: this.tid}, {$set: {counter: this.counter}}, {writeConcern: {w: 'majority'}})); + + // As soon as the write returns, its effects should be visible in the majority snapshot. + const doc = db[this.majorityWriteCollName].findOne({_id: this.tid}); + assertWhenOwnColl.eq( + this.counter, doc.counter, 'unexpected counter value, doc: ' + tojson(doc)); + }; + + /** + * Updates a document that may be written to by the transaction run in the base workload using + * majority write concern and verifies the update is immediately visible in the majority + * snapshot once the write returns. + */ + $config.states.majorityWriteTxnDoc = function majorityWriteTxnDoc(db, collName) { + this.counter += 1; + + // Choose a random document that may be written to by the base workload. The base collection + // contains documents with _id ranging from 0 to the number of accounts. Update a field + // based on the thread's id, since threads may concurrently write to the same document. + const transactionDocId = Random.randInt(this.numAccounts); + const threadUniqueField = 'thread' + this.tid; + assertWhenOwnColl.writeOK(db[collName].update({_id: transactionDocId}, + {$set: {[threadUniqueField]: this.counter}}, + {writeConcern: {w: 'majority'}})); + + // As soon as the write returns, its effects should be visible in the majority snapshot. + const doc = db[collName].findOne({_id: transactionDocId}); + assertWhenOwnColl.eq( + this.counter, + doc[threadUniqueField], + 'unexpected thread unique field value, thread: ' + this.tid + ', doc: ' + tojson(doc)); + }; + + /** + * Runs the base workload's setup and, if necessary, shards the collection that is majority + * written to by this workload. + */ + $config.setup = function setup(db, collName, cluster) { + $super.setup.apply(this, arguments); + + if (isMongos(db)) { + // The database will already have had sharding enabled by the fsm infrastructure. + db.adminCommand({ + shardCollection: db[this.majorityWriteCollName].getFullName(), + key: {_id: 'hashed'} + }); + } + }; + + $config.transitions = { + init: {transferMoney: 1}, + transferMoney: { + transferMoney: 0.5, + checkMoneyBalance: 0.1, + majorityWriteUnrelatedDoc: 0.2, + majorityWriteTxnDoc: 0.2 + }, + checkMoneyBalance: + {transferMoney: 0.5, majorityWriteUnrelatedDoc: 0.25, majorityWriteTxnDoc: 0.25}, + majorityWriteUnrelatedDoc: + {transferMoney: 0.5, majorityWriteUnrelatedDoc: 0.25, majorityWriteTxnDoc: 0.25}, + majorityWriteTxnDoc: + {transferMoney: 0.5, majorityWriteUnrelatedDoc: 0.25, majorityWriteTxnDoc: 0.25}, + }; + + return $config; +}); |