diff options
author | Samy Lanka <samy.lanka@mongodb.com> | 2018-09-12 18:38:53 -0400 |
---|---|---|
committer | Samy Lanka <samy.lanka@mongodb.com> | 2018-09-13 13:27:43 -0400 |
commit | ba14a58e71334dda6babb92e89c7ce784f30120f (patch) | |
tree | b9a9f907d211876fadd80ae3658fb8244bca75e4 | |
parent | 061d13d34af2d75f1b3597b1a60478a60a97e7c7 (diff) | |
download | mongo-ba14a58e71334dda6babb92e89c7ce784f30120f.tar.gz |
SERVER-37054 Turn off timestamp reaping to prevent the oldest timestsamp from advancing in prepare_conflict_read_concern_behavior.js
-rw-r--r-- | jstests/core/txns/prepare_conflict_read_concern_behavior.js | 262 |
1 files changed, 144 insertions, 118 deletions
diff --git a/jstests/core/txns/prepare_conflict_read_concern_behavior.js b/jstests/core/txns/prepare_conflict_read_concern_behavior.js index 4ec14ff84a2..db7776673a0 100644 --- a/jstests/core/txns/prepare_conflict_read_concern_behavior.js +++ b/jstests/core/txns/prepare_conflict_read_concern_behavior.js @@ -18,122 +18,148 @@ const testColl = testDB.getCollection(collName); const testColl2 = testDB.getCollection(collName2); - testDB.runCommand({drop: collName, writeConcern: {w: "majority"}}); - assert.commandWorked(testDB.runCommand({create: collName, writeConcern: {w: "majority"}})); - - testDB.runCommand({drop: collName2, writeConcern: {w: "majority"}}); - assert.commandWorked(testDB.runCommand({create: collName2, writeConcern: {w: "majority"}})); - - const session = db.getMongo().startSession({causalConsistency: false}); - const sessionDB = session.getDatabase(dbName); - const sessionColl = sessionDB.getCollection(collName); - - const read = function(read_concern, timeout, db, coll, num_expected) { - let res = db.runCommand({ - find: coll, - filter: {in_prepared_txn: 3}, - readConcern: read_concern, - maxTimeMS: timeout, - }); - - if (num_expected) { - assert(res.cursor, tojson(res)); - assert.eq(res.cursor.firstBatch.length, num_expected, tojson(res)); - } - return res; - }; - - assert.commandWorked( - testColl.insert({_id: 1, in_prepared_txn: 3}, {writeConcern: {w: "majority"}})); - assert.commandWorked(testColl2.insert({_id: 1, in_prepared_txn: 3})); - - session.startTransaction(); - const clusterTimeBeforePrepare = - assert.commandWorked(sessionColl.runCommand("insert", {documents: [{_id: 2}]})) - .operationTime; - const prepareTimestamp = PrepareHelpers.prepareTransaction(session); - - const clusterTimeAfterPrepare = - assert - .commandWorked(testColl.runCommand( - "insert", - {documents: [{_id: 3, in_prepared_txn: 3}], writeConcern: {w: "majority"}})) - .operationTime; - - jsTestLog("prepareTimestamp: " + prepareTimestamp + " clusterTimeBeforePrepare: " + - clusterTimeBeforePrepare + " clusterTimeAfterPrepare: " + clusterTimeAfterPrepare); - - assert.gt(prepareTimestamp, clusterTimeBeforePrepare); - assert.gt(clusterTimeAfterPrepare, prepareTimestamp); - - jsTestLog("Test read with read concern 'majority' doesn't block on a prepared transaction."); - assert.commandWorked(read({level: 'majority'}, successTimeout, testDB, collName, 2)); - - jsTestLog("Test read with read concern 'local' doesn't block on a prepared transaction."); - assert.commandWorked(read({level: 'local'}, successTimeout, testDB, collName, 2)); - - jsTestLog("Test read with read concern 'available' doesn't block on a prepared transaction."); - assert.commandWorked(read({level: 'available'}, successTimeout, testDB, collName, 2)); - - jsTestLog("Test read with read concern 'linearizable' blocks on a prepared transaction."); - assert.commandFailedWithCode(read({level: 'linearizable'}, failureTimeout, testDB, collName), - ErrorCodes.MaxTimeMSExpired); - - // TODO SERVER-36953: uncomment this test - // jsTestLog("Test afterClusterTime read before prepareTimestamp doesn't block on a prepared " + - // "transaction."); - // assert.commandWorked(read({level: 'local', afterClusterTime: clusterTimeBeforePrepare}, - // successTimeout, - // testDB, - // collName, - // 2)); - - jsTestLog("Test afterClusterTime read after prepareTimestamp blocks on a prepared " + - "transaction."); - assert.commandFailedWithCode(read({level: 'local', afterClusterTime: clusterTimeAfterPrepare}, - failureTimeout, - testDB, - collName), - ErrorCodes.MaxTimeMSExpired); - - jsTestLog("Test read with afterClusterTime after prepareTimestamp on non-prepared documents " + - "doesn't block on a prepared transaction."); - assert.commandWorked(read({level: 'local', afterClusterTime: clusterTimeAfterPrepare}, - successTimeout, - testDB, - collName2, - 1)); - - // Create a second session and start a new transaction to test snapshot reads. - const session2 = db.getMongo().startSession({causalConsistency: false}); - const sessionDB2 = session2.getDatabase(dbName); - const sessionColl2 = sessionDB2.getCollection(collName); - // This makes future reads in the transaction use a read timestamp after the prepareTimestamp. - session2.startTransaction( - {readConcern: {level: "snapshot", atClusterTime: clusterTimeAfterPrepare}}); - - jsTestLog("Test read with read concern 'snapshot' and a read timestamp after prepareTimestamp" + - " on non-prepared documents doesn't block on a prepared transaction."); - assert.commandWorked(read({}, failureTimeout, sessionDB2, collName2, 1)); - - jsTestLog("Test read with read concern 'snapshot' and a read timestamp after prepareTimestamp" + - " blocks on a prepared transaction."); - assert.commandFailedWithCode(read({}, failureTimeout, sessionDB2, collName), - ErrorCodes.MaxTimeMSExpired); - - session2.abortTransaction(); - session2.startTransaction( - {readConcern: {level: "snapshot", atClusterTime: clusterTimeBeforePrepare}}); - - jsTestLog("Test read with read concern 'snapshot' and atClusterTime before " + - "prepareTimestamp doesn't block on a prepared transaction."); - assert.commandWorked( - testColl.runCommand("insert", {documents: [{_id: 4, in_prepared_txn: 3}]})); - assert.commandWorked(read({}, successTimeout, sessionDB2, collName, 1)); - - session.abortTransaction(); - session.endSession(); - - session2.abortTransaction(); - session2.endSession(); + // Turn off timestamp reaping so that clusterTimeBeforePrepare doesn't get too old. + assert.commandWorked(testDB.adminCommand({ + configureFailPoint: "WTPreserveSnapshotHistoryIndefinitely", + mode: "alwaysOn", + })); + + function runTest() { + testDB.runCommand({drop: collName, writeConcern: {w: "majority"}}); + assert.commandWorked(testDB.runCommand({create: collName, writeConcern: {w: "majority"}})); + + testDB.runCommand({drop: collName2, writeConcern: {w: "majority"}}); + assert.commandWorked(testDB.runCommand({create: collName2, writeConcern: {w: "majority"}})); + + const session = db.getMongo().startSession({causalConsistency: false}); + const sessionDB = session.getDatabase(dbName); + const sessionColl = sessionDB.getCollection(collName); + + const read = function(read_concern, timeout, db, coll, num_expected) { + let res = db.runCommand({ + find: coll, + filter: {in_prepared_txn: 3}, + readConcern: read_concern, + maxTimeMS: timeout, + }); + + if (num_expected) { + assert(res.cursor, tojson(res)); + assert.eq(res.cursor.firstBatch.length, num_expected, tojson(res)); + } + return res; + }; + + assert.commandWorked( + testColl.insert({_id: 1, in_prepared_txn: 3}, {writeConcern: {w: "majority"}})); + assert.commandWorked(testColl2.insert({_id: 1, in_prepared_txn: 3})); + + session.startTransaction(); + const clusterTimeBeforePrepare = + assert.commandWorked(sessionColl.runCommand("insert", {documents: [{_id: 2}]})) + .operationTime; + const prepareTimestamp = PrepareHelpers.prepareTransaction(session); + + const clusterTimeAfterPrepare = + assert + .commandWorked(testColl.runCommand( + "insert", + {documents: [{_id: 3, in_prepared_txn: 3}], writeConcern: {w: "majority"}})) + .operationTime; + + jsTestLog("prepareTimestamp: " + prepareTimestamp + " clusterTimeBeforePrepare: " + + clusterTimeBeforePrepare + " clusterTimeAfterPrepare: " + + clusterTimeAfterPrepare); + + assert.gt(prepareTimestamp, clusterTimeBeforePrepare); + assert.gt(clusterTimeAfterPrepare, prepareTimestamp); + + jsTestLog( + "Test read with read concern 'majority' doesn't block on a prepared transaction."); + assert.commandWorked(read({level: 'majority'}, successTimeout, testDB, collName, 2)); + + jsTestLog("Test read with read concern 'local' doesn't block on a prepared transaction."); + assert.commandWorked(read({level: 'local'}, successTimeout, testDB, collName, 2)); + + jsTestLog( + "Test read with read concern 'available' doesn't block on a prepared transaction."); + assert.commandWorked(read({level: 'available'}, successTimeout, testDB, collName, 2)); + + jsTestLog("Test read with read concern 'linearizable' blocks on a prepared transaction."); + assert.commandFailedWithCode( + read({level: 'linearizable'}, failureTimeout, testDB, collName), + ErrorCodes.MaxTimeMSExpired); + + // TODO SERVER-36953: uncomment this test + // jsTestLog("Test afterClusterTime read before prepareTimestamp doesn't block on a " + + // "prepared transaction."); + // assert.commandWorked(read({level: 'local', afterClusterTime: clusterTimeBeforePrepare}, + // successTimeout, + // testDB, + // collName, + // 2)); + + jsTestLog("Test afterClusterTime read after prepareTimestamp blocks on a prepared " + + "transaction."); + assert.commandFailedWithCode( + read({level: 'local', afterClusterTime: clusterTimeAfterPrepare}, + failureTimeout, + testDB, + collName), + ErrorCodes.MaxTimeMSExpired); + + jsTestLog("Test read with afterClusterTime after prepareTimestamp on non-prepared " + + "documents doesn't block on a prepared transaction."); + assert.commandWorked(read({level: 'local', afterClusterTime: clusterTimeAfterPrepare}, + successTimeout, + testDB, + collName2, + 1)); + + // Create a second session and start a new transaction to test snapshot reads. + const session2 = db.getMongo().startSession({causalConsistency: false}); + const sessionDB2 = session2.getDatabase(dbName); + const sessionColl2 = sessionDB2.getCollection(collName); + // This makes future reads in the transaction use a read timestamp after the + // prepareTimestamp. + session2.startTransaction( + {readConcern: {level: "snapshot", atClusterTime: clusterTimeAfterPrepare}}); + + jsTestLog("Test read with read concern 'snapshot' and a read timestamp after " + + "prepareTimestamp on non-prepared documents doesn't block on a prepared " + + "transaction."); + assert.commandWorked(read({}, failureTimeout, sessionDB2, collName2, 1)); + + jsTestLog("Test read with read concern 'snapshot' and a read timestamp after " + + "prepareTimestamp blocks on a prepared transaction."); + assert.commandFailedWithCode(read({}, failureTimeout, sessionDB2, collName), + ErrorCodes.MaxTimeMSExpired); + + session2.abortTransaction(); + session2.startTransaction( + {readConcern: {level: "snapshot", atClusterTime: clusterTimeBeforePrepare}}); + + jsTestLog("Test read with read concern 'snapshot' and atClusterTime before " + + "prepareTimestamp doesn't block on a prepared transaction."); + assert.commandWorked( + testColl.runCommand("insert", {documents: [{_id: 4, in_prepared_txn: 3}]})); + assert.commandWorked(read({}, successTimeout, sessionDB2, collName, 1)); + + session.abortTransaction(); + session.endSession(); + + session2.abortTransaction(); + session2.endSession(); + } + + try { + runTest(); + } finally { + // Turn this failpoint off so that it doesn't impact other tests in the suite. + assert.commandWorked(testDB.adminCommand({ + configureFailPoint: "WTPreserveSnapshotHistoryIndefinitely", + mode: "off", + })); + } + }());
\ No newline at end of file |