diff options
Diffstat (limited to 'jstests/replsets/recovery_preserves_active_txns.js')
-rw-r--r-- | jstests/replsets/recovery_preserves_active_txns.js | 155 |
1 files changed, 77 insertions, 78 deletions
diff --git a/jstests/replsets/recovery_preserves_active_txns.js b/jstests/replsets/recovery_preserves_active_txns.js index 5896a1e01fc..005286cf152 100644 --- a/jstests/replsets/recovery_preserves_active_txns.js +++ b/jstests/replsets/recovery_preserves_active_txns.js @@ -11,83 +11,82 @@ */ (function() { - "use strict"; - load("jstests/core/txns/libs/prepare_helpers.js"); - load("jstests/libs/check_log.js"); - - // A new replica set for both the commit and abort tests to ensure the same clean state. - function doTest(commitOrAbort) { - const replSet = new ReplSetTest({ - // Oplog can be truncated each "sync" cycle. Increase its frequency to once per second. - nodeOptions: - {syncdelay: 1, setParameter: {logComponentVerbosity: tojson({storage: 1})}}, - nodes: [{}, {rsConfig: {priority: 0, votes: 0}}] - }); - - replSet.startSet(PrepareHelpers.replSetStartSetOptions); - replSet.initiate(); - const primary = replSet.getPrimary(); - const primaryOplog = primary.getDB("local").oplog.rs; - assert.lte(primaryOplog.dataSize(), PrepareHelpers.oplogSizeBytes); - - const coll = primary.getDB("test").test; - assert.commandWorked(coll.insert({}, {writeConcern: {w: "majority"}})); - - jsTestLog("Prepare a transaction"); - - const session = primary.startSession(); - session.startTransaction(); - assert.commandWorked(session.getDatabase("test").test.insert({myTransaction: 1})); - const prepareTimestamp = PrepareHelpers.prepareTransaction(session); - - const oldestRequiredTimestampForCrashRecovery = - PrepareHelpers.getOldestRequiredTimestampForCrashRecovery(primary.getDB("test")); - assert.lte(oldestRequiredTimestampForCrashRecovery, prepareTimestamp); - - jsTestLog("Insert documents until oplog exceeds oplogSize"); - - // Oplog with prepared txn grows indefinitely - let it reach twice its supposed max size. - PrepareHelpers.growOplogPastMaxSize(replSet); - - // Oplog grew past maxSize, and it includes the oldest active transaction's entry. - var secondary = replSet.getSecondary(); - function checkSecondaryOplog() { - const secondaryOplog = secondary.getDB("local").oplog.rs; - assert.soon(() => { - return secondaryOplog.dataSize() >= PrepareHelpers.oplogSizeBytes; - }, "waiting for secondary oplog to grow", ReplSetTest.kDefaultTimeoutMS); - const secondaryOplogEntry = PrepareHelpers.findPrepareEntry(secondaryOplog); - assert.eq(secondaryOplogEntry.ts, prepareTimestamp, tojson(secondaryOplogEntry)); - } - checkSecondaryOplog(); - - jsTestLog("Restart the secondary"); - - const secondaryId = replSet.getSecondary().nodeId; - // Validation can't complete while the active transaction holds a lock. - replSet.stop(secondaryId, undefined, {skipValidation: true}); - secondary = replSet.start(secondaryId, {}, true /* restart */); - - jsTestLog("Restarted"); - - replSet.awaitSecondaryNodes(); - checkSecondaryOplog(); - - if (commitOrAbort === "commit") { - jsTestLog("Commit prepared transaction and wait for oplog to shrink to max oplogSize"); - PrepareHelpers.commitTransaction(session, prepareTimestamp); - } else if (commitOrAbort === "abort") { - jsTestLog("Abort prepared transaction and wait for oplog to shrink to max oplogSize"); - assert.commandWorked(session.abortTransaction_forTesting()); - } else { - throw new Error(`Unrecognized value for commitOrAbort: ${commitOrAbort}`); - } - - PrepareHelpers.awaitOplogTruncation(replSet); - - // ReplSetTest reacts poorly to restarting a node, end it manually. - replSet.stopSet(true, false, {}); +"use strict"; +load("jstests/core/txns/libs/prepare_helpers.js"); +load("jstests/libs/check_log.js"); + +// A new replica set for both the commit and abort tests to ensure the same clean state. +function doTest(commitOrAbort) { + const replSet = new ReplSetTest({ + // Oplog can be truncated each "sync" cycle. Increase its frequency to once per second. + nodeOptions: {syncdelay: 1, setParameter: {logComponentVerbosity: tojson({storage: 1})}}, + nodes: [{}, {rsConfig: {priority: 0, votes: 0}}] + }); + + replSet.startSet(PrepareHelpers.replSetStartSetOptions); + replSet.initiate(); + const primary = replSet.getPrimary(); + const primaryOplog = primary.getDB("local").oplog.rs; + assert.lte(primaryOplog.dataSize(), PrepareHelpers.oplogSizeBytes); + + const coll = primary.getDB("test").test; + assert.commandWorked(coll.insert({}, {writeConcern: {w: "majority"}})); + + jsTestLog("Prepare a transaction"); + + const session = primary.startSession(); + session.startTransaction(); + assert.commandWorked(session.getDatabase("test").test.insert({myTransaction: 1})); + const prepareTimestamp = PrepareHelpers.prepareTransaction(session); + + const oldestRequiredTimestampForCrashRecovery = + PrepareHelpers.getOldestRequiredTimestampForCrashRecovery(primary.getDB("test")); + assert.lte(oldestRequiredTimestampForCrashRecovery, prepareTimestamp); + + jsTestLog("Insert documents until oplog exceeds oplogSize"); + + // Oplog with prepared txn grows indefinitely - let it reach twice its supposed max size. + PrepareHelpers.growOplogPastMaxSize(replSet); + + // Oplog grew past maxSize, and it includes the oldest active transaction's entry. + var secondary = replSet.getSecondary(); + function checkSecondaryOplog() { + const secondaryOplog = secondary.getDB("local").oplog.rs; + assert.soon(() => { + return secondaryOplog.dataSize() >= PrepareHelpers.oplogSizeBytes; + }, "waiting for secondary oplog to grow", ReplSetTest.kDefaultTimeoutMS); + const secondaryOplogEntry = PrepareHelpers.findPrepareEntry(secondaryOplog); + assert.eq(secondaryOplogEntry.ts, prepareTimestamp, tojson(secondaryOplogEntry)); } - doTest("commit"); - doTest("abort"); + checkSecondaryOplog(); + + jsTestLog("Restart the secondary"); + + const secondaryId = replSet.getSecondary().nodeId; + // Validation can't complete while the active transaction holds a lock. + replSet.stop(secondaryId, undefined, {skipValidation: true}); + secondary = replSet.start(secondaryId, {}, true /* restart */); + + jsTestLog("Restarted"); + + replSet.awaitSecondaryNodes(); + checkSecondaryOplog(); + + if (commitOrAbort === "commit") { + jsTestLog("Commit prepared transaction and wait for oplog to shrink to max oplogSize"); + PrepareHelpers.commitTransaction(session, prepareTimestamp); + } else if (commitOrAbort === "abort") { + jsTestLog("Abort prepared transaction and wait for oplog to shrink to max oplogSize"); + assert.commandWorked(session.abortTransaction_forTesting()); + } else { + throw new Error(`Unrecognized value for commitOrAbort: ${commitOrAbort}`); + } + + PrepareHelpers.awaitOplogTruncation(replSet); + + // ReplSetTest reacts poorly to restarting a node, end it manually. + replSet.stopSet(true, false, {}); +} +doTest("commit"); +doTest("abort"); })(); |