summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamy Lanka <samy.lanka@mongodb.com>2018-09-12 18:38:53 -0400
committerSamy Lanka <samy.lanka@mongodb.com>2018-09-13 13:27:43 -0400
commitba14a58e71334dda6babb92e89c7ce784f30120f (patch)
treeb9a9f907d211876fadd80ae3658fb8244bca75e4
parent061d13d34af2d75f1b3597b1a60478a60a97e7c7 (diff)
downloadmongo-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.js262
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