summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEsha Maharishi <esha.maharishi@mongodb.com>2019-03-20 10:13:53 -0400
committerEsha Maharishi <esha.maharishi@mongodb.com>2019-03-20 20:34:38 -0400
commit9614d52c9e83afdde0ae22e16de97f290a08c206 (patch)
tree646aef5f03ef11ec7f22148c4719e2a4766f725b
parent40f54965f90cfa986a6b6aa0e693c53464f0bc80 (diff)
downloadmongo-9614d52c9e83afdde0ae22e16de97f290a08c206.tar.gz
SERVER-38876 Ensure secondary user operations cannot abort transactions being applied from the oplog
-rw-r--r--jstests/replsets/transactions_on_secondaries_not_allowed.js25
-rw-r--r--src/mongo/db/command_can_run_here.cpp3
2 files changed, 24 insertions, 4 deletions
diff --git a/jstests/replsets/transactions_on_secondaries_not_allowed.js b/jstests/replsets/transactions_on_secondaries_not_allowed.js
index d857cef6717..c1e5c332f15 100644
--- a/jstests/replsets/transactions_on_secondaries_not_allowed.js
+++ b/jstests/replsets/transactions_on_secondaries_not_allowed.js
@@ -11,7 +11,7 @@
const collName = "transactions_on_secondaries_not_allowed";
const rst = new ReplSetTest({name: collName, nodes: 2});
- rst.startSet();
+ rst.startSet({verbose: 3});
// We want a stable topology, so make the secondary unelectable.
let config = rst.getReplSetConfig();
config.members[1].priority = 0;
@@ -26,8 +26,13 @@
assert.commandWorked(primary.getDB(dbName)[collName].insert(initialDoc));
rst.awaitLastOpCommitted();
+ // Disable the best-effort check for primary-ness in the service entry point, so that we
+ // exercise the real check for primary-ness in TransactionParticipant::beginOrContinue.
+ assert.commandWorked(secondary.adminCommand(
+ {configureFailPoint: "skipCheckingForNotMasterInCommandDispatch", mode: "alwaysOn"}));
+
// Initiate a session on the secondary.
- const sessionOptions = {causalConsistency: false};
+ const sessionOptions = {causalConsistency: false, retryWrites: true};
const session = secondaryTestDB.getMongo().startSession(sessionOptions);
const sessionDb = session.getDatabase(dbName);
@@ -60,6 +65,22 @@
jsTestLog("Make sure we are not allowed to run the abortTransaction command on the secondary.");
assert.commandFailedWithCode(session.abortTransaction_forTesting(), ErrorCodes.NotMaster);
+ /**
+ * Test starting a retryable write.
+ */
+
+ jsTestLog("Start a retryable write");
+ assert.commandFailedWithCode(sessionDb.foo.insert({_id: 0}), ErrorCodes.NotMaster);
+
+ /**
+ * Test starting a read with txnNumber, but without autocommit. This is not an officially
+ * supported combination, but should still be disallowed on a secondary.
+ */
+
+ jsTestLog("Start a read with txnNumber but without autocommit");
+ assert.commandFailedWithCode(sessionDb.runCommand({find: 'foo', txnNumber: NumberLong(10)}),
+ ErrorCodes.NotMaster);
+
session.endSession();
rst.stopSet(undefined, false, {skipValidation: true});
}());
diff --git a/src/mongo/db/command_can_run_here.cpp b/src/mongo/db/command_can_run_here.cpp
index 17dc5b7b627..37089aefa68 100644
--- a/src/mongo/db/command_can_run_here.cpp
+++ b/src/mongo/db/command_can_run_here.cpp
@@ -32,7 +32,6 @@
#include "mongo/db/command_can_run_here.h"
#include "mongo/client/read_preference.h"
-#include "mongo/db/commands/test_commands_enabled.h"
#include "mongo/db/repl/replication_coordinator.h"
#include "mongo/util/assert_util.h"
@@ -47,7 +46,7 @@ bool commandCanRunHere(OperationContext* opCtx,
return true; // primary: always ok
if (!opCtx->writesAreReplicated())
return true; // standalone: always ok
- if (inMultiDocumentTransaction && !getTestCommandsEnabled())
+ if (inMultiDocumentTransaction)
return false; // Transactions are not allowed on secondaries.
switch (command->secondaryAllowed(opCtx->getServiceContext())) {
case Command::AllowedOnSecondary::kAlways: