summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJudah Schvimer <judah@mongodb.com>2018-08-08 15:21:45 -0400
committerJudah Schvimer <judah@mongodb.com>2018-08-09 16:49:28 -0400
commitb69f0e10fc921d179fb91b8854a2bb5a3f95ec27 (patch)
tree424859806ede4e65e67bd1fc36f7af130f470a84
parent6981d17bddeef6092a89f5d70621b991abe2b317 (diff)
downloadmongo-b69f0e10fc921d179fb91b8854a2bb5a3f95ec27.tar.gz
SERVER-35881 Gate prepareTransaction on featureCompatibilityVersion 4.2
-rw-r--r--buildscripts/resmokeconfig/suites/replica_sets_initsync_jscore_passthrough.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/replica_sets_initsync_static_jscore_passthrough.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/replica_sets_jscore_passthrough.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/replica_sets_kill_secondaries_jscore_passthrough.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/sharded_core_txns.yml1
-rw-r--r--jstests/core/txns/prepare_requires_fcv42.js56
-rw-r--r--src/mongo/db/s/txn_two_phase_commit_cmds.cpp5
7 files changed, 66 insertions, 0 deletions
diff --git a/buildscripts/resmokeconfig/suites/replica_sets_initsync_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/replica_sets_initsync_jscore_passthrough.yml
index dba7fd9b567..5a4d1186c5a 100644
--- a/buildscripts/resmokeconfig/suites/replica_sets_initsync_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/replica_sets_initsync_jscore_passthrough.yml
@@ -78,6 +78,7 @@ selector:
# entries.
- jstests/core/txns/commit_prepared_transaction.js
- jstests/core/txns/timestamped_reads_wait_for_prepare_oplog_visibility.js
+ - jstests/core/txns/prepare_requires_fcv42.js
run_hook_interval: &run_hook_interval 20
executor:
diff --git a/buildscripts/resmokeconfig/suites/replica_sets_initsync_static_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/replica_sets_initsync_static_jscore_passthrough.yml
index 4ececd471fd..556578ef569 100644
--- a/buildscripts/resmokeconfig/suites/replica_sets_initsync_static_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/replica_sets_initsync_static_jscore_passthrough.yml
@@ -15,6 +15,7 @@ selector:
# entries.
- jstests/core/txns/commit_prepared_transaction.js
- jstests/core/txns/timestamped_reads_wait_for_prepare_oplog_visibility.js
+ - jstests/core/txns/prepare_requires_fcv42.js
run_hook_interval: &run_hook_interval 20
executor:
diff --git a/buildscripts/resmokeconfig/suites/replica_sets_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/replica_sets_jscore_passthrough.yml
index 40a40434b62..70d68273f79 100644
--- a/buildscripts/resmokeconfig/suites/replica_sets_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/replica_sets_jscore_passthrough.yml
@@ -27,6 +27,7 @@ selector:
# entries.
- jstests/core/txns/commit_prepared_transaction.js
- jstests/core/txns/timestamped_reads_wait_for_prepare_oplog_visibility.js
+ - jstests/core/txns/prepare_requires_fcv42.js
executor:
archive:
diff --git a/buildscripts/resmokeconfig/suites/replica_sets_kill_secondaries_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/replica_sets_kill_secondaries_jscore_passthrough.yml
index 3e26a655d41..a7a72179829 100644
--- a/buildscripts/resmokeconfig/suites/replica_sets_kill_secondaries_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/replica_sets_kill_secondaries_jscore_passthrough.yml
@@ -18,6 +18,7 @@ selector:
# entries.
- jstests/core/txns/commit_prepared_transaction.js
- jstests/core/txns/timestamped_reads_wait_for_prepare_oplog_visibility.js
+ - jstests/core/txns/prepare_requires_fcv42.js
executor:
archive:
diff --git a/buildscripts/resmokeconfig/suites/sharded_core_txns.yml b/buildscripts/resmokeconfig/suites/sharded_core_txns.yml
index 7f37c9c1c28..c2188ce6cff 100644
--- a/buildscripts/resmokeconfig/suites/sharded_core_txns.yml
+++ b/buildscripts/resmokeconfig/suites/sharded_core_txns.yml
@@ -23,6 +23,7 @@ selector:
- jstests/core/txns/prepare_committed_transaction.js
- jstests/core/txns/prepare_conflict.js
- jstests/core/txns/timestamped_reads_wait_for_prepare_oplog_visibility.js
+ - jstests/core/txns/prepare_requires_fcv42.js
# Mongos doesn't upconvert from local or majority level readConcern to snapshot.
- jstests/core/txns/upconvert_read_concern.js
diff --git a/jstests/core/txns/prepare_requires_fcv42.js b/jstests/core/txns/prepare_requires_fcv42.js
new file mode 100644
index 00000000000..35905e5116e
--- /dev/null
+++ b/jstests/core/txns/prepare_requires_fcv42.js
@@ -0,0 +1,56 @@
+/**
+ * Tests that 'prepareTransaction' only succeeds in FCV 4.2.
+ *
+ * @tags: [uses_transactions]
+ */
+(function() {
+ "use strict";
+ load("jstests/libs/feature_compatibility_version.js");
+ load("jstests/core/txns/libs/prepare_helpers.js");
+
+ const dbName = "test";
+ const collName = "prepare_requires_fcv42";
+ const testDB = db.getSiblingDB(dbName);
+ const adminDB = db.getSiblingDB('admin');
+
+ testDB[collName].drop({writeConcern: {w: "majority"}});
+ assert.commandWorked(testDB.runCommand({create: collName, writeConcern: {w: "majority"}}));
+
+ const sessionOptions = {causalConsistency: false};
+ const session = testDB.getMongo().startSession(sessionOptions);
+ const sessionDB = session.getDatabase(dbName);
+
+ try {
+ jsTestLog("Transaction succeeds in latest FCV.");
+ checkFCV(adminDB, latestFCV);
+ session.startTransaction();
+ assert.commandWorked(sessionDB[collName].insert({_id: "a"}));
+ let prepareTimestamp = PrepareHelpers.prepareTransaction(session);
+ assert.commandWorked(PrepareHelpers.commitTransaction(session, prepareTimestamp));
+
+ jsTestLog("Downgrade the featureCompatibilityVersion.");
+ assert.commandWorked(testDB.adminCommand({setFeatureCompatibilityVersion: lastStableFCV}));
+ checkFCV(adminDB, lastStableFCV);
+
+ jsTestLog("Transaction fails to prepare in last stable FCV.");
+ session.startTransaction();
+ assert.commandWorked(sessionDB[collName].insert({_id: "b"}));
+ assert.commandFailedWithCode(sessionDB.adminCommand({prepareTransaction: 1}),
+ ErrorCodes.CommandNotSupported);
+ // Abort the transaction in the shell.
+ session.abortTransaction();
+
+ } finally {
+ jsTestLog("Restore the original featureCompatibilityVersion.");
+ assert.commandWorked(testDB.adminCommand({setFeatureCompatibilityVersion: latestFCV}));
+ checkFCV(adminDB, latestFCV);
+ }
+
+ jsTestLog("Transaction succeeds in latest FCV after upgrade.");
+ session.startTransaction();
+ assert.commandWorked(sessionDB[collName].insert({_id: "c"}));
+ let prepareTimestamp = PrepareHelpers.prepareTransaction(session);
+ assert.commandWorked(PrepareHelpers.commitTransaction(session, prepareTimestamp));
+
+ session.endSession();
+}());
diff --git a/src/mongo/db/s/txn_two_phase_commit_cmds.cpp b/src/mongo/db/s/txn_two_phase_commit_cmds.cpp
index cd5c0a1c099..99ed8e1ae5a 100644
--- a/src/mongo/db/s/txn_two_phase_commit_cmds.cpp
+++ b/src/mongo/db/s/txn_two_phase_commit_cmds.cpp
@@ -73,6 +73,11 @@ public:
"prepareTransaction must be run within a transaction",
txnParticipant);
+ uassert(ErrorCodes::CommandNotSupported,
+ "'prepareTransaction' is only supported in feature compatibility version 4.2",
+ (serverGlobalParams.featureCompatibility.getVersion() ==
+ ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo42));
+
uassert(ErrorCodes::NoSuchTransaction,
"Transaction isn't in progress",
txnParticipant->inMultiDocumentTransaction());