summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Mulrow <jack.mulrow@mongodb.com>2017-11-13 19:33:45 -0500
committerJack Mulrow <jack.mulrow@mongodb.com>2017-11-17 16:01:19 -0500
commit97af8701b538754261e566b26fa22cb4b54710f3 (patch)
tree1326cc7af7e461f5689f5c6c52e857c0a9de01ba
parent69a17fc7d0546651c4229f246292086982441346 (diff)
downloadmongo-97af8701b538754261e566b26fa22cb4b54710f3.tar.gz
SERVER-31941 Disallow retryable writes in storage engines that do not support document-level locking
-rw-r--r--etc/evergreen.yml23
-rw-r--r--jstests/multiVersion/shell_retryable_writes_downgrade.js5
-rw-r--r--jstests/noPassthrough/auto_retry_on_network_error.js5
-rw-r--r--jstests/noPassthrough/retryable_writes_mmap.js36
-rw-r--r--jstests/noPassthrough/retryable_writes_standalone_api.js5
-rw-r--r--jstests/noPassthrough/shell_can_retry_writes.js5
-rw-r--r--jstests/noPassthrough/transaction_reaper.js5
-rw-r--r--jstests/replsets/retryable_writes_direct_write_to_config_transactions.js5
-rw-r--r--jstests/replsets/retryable_writes_failover.js5
-rw-r--r--jstests/replsets/rollback_transaction_table.js5
-rw-r--r--jstests/replsets/transaction_table_oplog_replay.js5
-rw-r--r--jstests/sharding/move_chunk_find_and_modify_with_write_retryability.js5
-rw-r--r--jstests/sharding/move_chunk_insert_with_write_retryability.js6
-rw-r--r--jstests/sharding/move_chunk_remove_with_write_retryability.js6
-rw-r--r--jstests/sharding/move_chunk_update_with_write_retryability.js6
-rw-r--r--jstests/sharding/retryable_writes.js5
-rw-r--r--jstests/sharding/session_info_in_oplog.js5
-rw-r--r--jstests/sharding/write_transactions_during_migration.js5
-rw-r--r--src/mongo/db/initialize_operation_session_info.cpp9
-rw-r--r--src/mongo/db/initialize_operation_session_info.h7
-rw-r--r--src/mongo/db/logical_session_id_test.cpp25
-rw-r--r--src/mongo/db/s/SConscript1
-rw-r--r--src/mongo/db/s/session_catalog_migration_destination_test.cpp14
-rw-r--r--src/mongo/db/service_entry_point_mongod.cpp11
-rw-r--r--src/mongo/s/commands/strategy.cpp2
25 files changed, 169 insertions, 42 deletions
diff --git a/etc/evergreen.yml b/etc/evergreen.yml
index 887233c90d4..7d0dbbbcc07 100644
--- a/etc/evergreen.yml
+++ b/etc/evergreen.yml
@@ -4170,17 +4170,6 @@ tasks:
run_multiple_jobs: true
- <<: *task_template
- name: retryable_writes_jscore_passthrough
- depends_on:
- - name: jsCore
- commands:
- - func: "do setup"
- - func: "run tests"
- vars:
- resmoke_args: --suites=retryable_writes_jscore_passthrough --storageEngine=mmapv1 --excludeWithAnyTags=skip_in_retryable_writes_mmapv1_passthrough
- run_multiple_jobs: true
-
-- <<: *task_template
name: retryable_writes_jscore_passthrough_WT
depends_on:
- name: jsCore_WT
@@ -5187,7 +5176,6 @@ buildvariants:
- name: replica_sets_resync_static_jscore_passthrough_WT
- name: replica_sets_pv0
- name: replica_sets_rollback_refetch_no_uuid
- - name: retryable_writes_jscore_passthrough
- name: retryable_writes_jscore_passthrough_WT
- name: master_slave
- name: master_slave_WT
@@ -6473,9 +6461,6 @@ buildvariants:
- name: replica_sets_kill_secondaries_jscore_passthrough_WT
distros:
- windows-64-vs2015-large
- - name: retryable_writes_jscore_passthrough
- distros:
- - windows-64-vs2015-large
- name: retryable_writes_jscore_passthrough_WT
distros:
- windows-64-vs2015-large
@@ -7116,7 +7101,6 @@ buildvariants:
- name: replica_sets_jscore_passthrough
- name: replica_sets_jscore_passthrough_WT
- name: replica_sets_kill_secondaries_jscore_passthrough_WT
- - name: retryable_writes_jscore_passthrough
- name: retryable_writes_jscore_passthrough_WT
- name: rollback_fuzzer
- name: rollback_fuzzer_WT
@@ -7508,9 +7492,6 @@ buildvariants:
- name: replica_sets_kill_secondaries_jscore_passthrough_WT
distros:
- rhel62-large
- - name: retryable_writes_jscore_passthrough
- distros:
- - rhel62-large
- name: retryable_writes_jscore_passthrough_WT
distros:
- rhel62-large
@@ -7700,7 +7681,6 @@ buildvariants:
- name: replica_sets_resync_static_jscore_passthrough
- name: replica_sets_resync_static_jscore_passthrough_WT
- name: replica_sets_kill_secondaries_jscore_passthrough_WT
- - name: retryable_writes_jscore_passthrough
- name: retryable_writes_jscore_passthrough_WT
- name: sasl
- name: session_jscore_passthrough_WT
@@ -9772,7 +9752,6 @@ buildvariants:
- name: replica_sets_auth
- name: replica_sets_pv0
- name: replica_sets_jscore_passthrough
- - name: retryable_writes_jscore_passthrough
- name: retryable_writes_jscore_passthrough_WT
- name: rlp
- name: rollback_fuzzer_WT
@@ -10208,7 +10187,6 @@ buildvariants:
- name: replica_sets_resync_static_jscore_passthrough
- name: replica_sets_resync_static_jscore_passthrough_WT
- name: replica_sets_kill_secondaries_jscore_passthrough_WT
- - name: retryable_writes_jscore_passthrough
- name: retryable_writes_jscore_passthrough_WT
- name: sasl
- name: session_jscore_passthrough_WT
@@ -10421,7 +10399,6 @@ buildvariants:
- name: replica_sets_resync_static_jscore_passthrough
- name: replica_sets_resync_static_jscore_passthrough_WT
- name: replica_sets_kill_secondaries_jscore_passthrough_WT
- - name: retryable_writes_jscore_passthrough
- name: retryable_writes_jscore_passthrough_WT
- name: sasl
- name: session_jscore_passthrough_WT
diff --git a/jstests/multiVersion/shell_retryable_writes_downgrade.js b/jstests/multiVersion/shell_retryable_writes_downgrade.js
index 854b468913e..f4fac6ced7e 100644
--- a/jstests/multiVersion/shell_retryable_writes_downgrade.js
+++ b/jstests/multiVersion/shell_retryable_writes_downgrade.js
@@ -5,6 +5,11 @@
(function() {
"use strict";
+ if (jsTest.options().storageEngine === "mmapv1") {
+ jsTestLog("Retryable writes are not supported, skipping test");
+ return;
+ }
+
load("jstests/replsets/rslib.js");
const rst = new ReplSetTest({nodes: 1});
diff --git a/jstests/noPassthrough/auto_retry_on_network_error.js b/jstests/noPassthrough/auto_retry_on_network_error.js
index b92a9780b6e..0a0a8b09561 100644
--- a/jstests/noPassthrough/auto_retry_on_network_error.js
+++ b/jstests/noPassthrough/auto_retry_on_network_error.js
@@ -5,6 +5,11 @@
(function() {
"use strict";
+ if (jsTest.options().storageEngine === "mmapv1") {
+ jsTestLog("Retryable writes are not supported, skipping test");
+ return;
+ }
+
load("jstests/libs/override_methods/auto_retry_on_network_error.js");
load("jstests/replsets/rslib.js");
diff --git a/jstests/noPassthrough/retryable_writes_mmap.js b/jstests/noPassthrough/retryable_writes_mmap.js
new file mode 100644
index 00000000000..ee60fd2039d
--- /dev/null
+++ b/jstests/noPassthrough/retryable_writes_mmap.js
@@ -0,0 +1,36 @@
+/*
+ * Verify that retryable writes aren't allowed on mmapv1, because it doesn't have document-level
+ * locking.
+ */
+(function() {
+ "use strict";
+
+ if (jsTest.options().storageEngine !== "mmapv1") {
+ jsTestLog("Storage engine is not mmapv1, skipping test");
+ return;
+ }
+
+ const rst = new ReplSetTest({nodes: 1});
+ rst.startSet();
+ rst.initiate();
+
+ let testDB = rst.getPrimary().startSession({retryWrites: true}).getDatabase("test");
+
+ assert.writeErrorWithCode(
+ testDB.foo.insert({x: 1}),
+ ErrorCodes.IllegalOperation,
+ "expected command with txnNumber to fail without document-level locking");
+
+ rst.stopSet();
+
+ const st = new ShardingTest({shards: {rs0: {nodes: 1}}});
+
+ testDB = st.s.startSession({retryWrites: true}).getDatabase("test");
+
+ assert.writeErrorWithCode(
+ testDB.foo.insert({x: 1}),
+ ErrorCodes.IllegalOperation,
+ "expected command with txnNumber to fail without document-level locking");
+
+ st.stop();
+}());
diff --git a/jstests/noPassthrough/retryable_writes_standalone_api.js b/jstests/noPassthrough/retryable_writes_standalone_api.js
index 75475ca69ec..6dc6f6cd7fa 100644
--- a/jstests/noPassthrough/retryable_writes_standalone_api.js
+++ b/jstests/noPassthrough/retryable_writes_standalone_api.js
@@ -4,6 +4,11 @@
(function() {
"use strict";
+ if (jsTest.options().storageEngine === "mmapv1") {
+ jsTestLog("Retryable writes are not supported, skipping test");
+ return;
+ }
+
const standalone = MongoRunner.runMongod();
const testDB = standalone.getDB("test");
diff --git a/jstests/noPassthrough/shell_can_retry_writes.js b/jstests/noPassthrough/shell_can_retry_writes.js
index d439be51f1b..b8eaefb7e54 100644
--- a/jstests/noPassthrough/shell_can_retry_writes.js
+++ b/jstests/noPassthrough/shell_can_retry_writes.js
@@ -5,6 +5,11 @@
(function() {
"use strict";
+ if (jsTest.options().storageEngine === "mmapv1") {
+ jsTestLog("Retryable writes are not supported, skipping test");
+ return;
+ }
+
const rst = new ReplSetTest({nodes: 1});
rst.startSet();
rst.initiate();
diff --git a/jstests/noPassthrough/transaction_reaper.js b/jstests/noPassthrough/transaction_reaper.js
index b777b80d6b3..5146de52234 100644
--- a/jstests/noPassthrough/transaction_reaper.js
+++ b/jstests/noPassthrough/transaction_reaper.js
@@ -1,6 +1,11 @@
(function() {
'use strict';
+ if (jsTest.options().storageEngine === "mmapv1") {
+ jsTestLog("Retryable writes are not supported, skipping test");
+ return;
+ }
+
function Repl(lifetime) {
this.rst = new ReplSetTest({
nodes: 1,
diff --git a/jstests/replsets/retryable_writes_direct_write_to_config_transactions.js b/jstests/replsets/retryable_writes_direct_write_to_config_transactions.js
index 62d0b840711..9333344d272 100644
--- a/jstests/replsets/retryable_writes_direct_write_to_config_transactions.js
+++ b/jstests/replsets/retryable_writes_direct_write_to_config_transactions.js
@@ -2,6 +2,11 @@
(function() {
'use strict';
+ if (jsTest.options().storageEngine === "mmapv1") {
+ jsTestLog("Retryable writes are not supported, skipping test");
+ return;
+ }
+
var replTest = new ReplSetTest({nodes: 2});
replTest.startSet();
replTest.initiate();
diff --git a/jstests/replsets/retryable_writes_failover.js b/jstests/replsets/retryable_writes_failover.js
index b61c0bda382..cccd2d64f24 100644
--- a/jstests/replsets/retryable_writes_failover.js
+++ b/jstests/replsets/retryable_writes_failover.js
@@ -5,6 +5,11 @@
(function() {
"use strict";
+ if (jsTest.options().storageEngine === "mmapv1") {
+ jsTestLog("Retryable writes are not supported, skipping test");
+ return;
+ }
+
function stepDownPrimary(replTest) {
let exception = assert.throws(function() {
let res = assert.commandWorked(
diff --git a/jstests/replsets/rollback_transaction_table.js b/jstests/replsets/rollback_transaction_table.js
index 74679d363ba..d48a4820713 100644
--- a/jstests/replsets/rollback_transaction_table.js
+++ b/jstests/replsets/rollback_transaction_table.js
@@ -20,6 +20,11 @@
(function() {
"use strict";
+ if (jsTest.options().storageEngine === "mmapv1") {
+ jsTestLog("Retryable writes are not supported, skipping test");
+ return;
+ }
+
load("jstests/replsets/rslib.js");
function assertSameRecordOnBothConnections(primary, secondary, lsid) {
diff --git a/jstests/replsets/transaction_table_oplog_replay.js b/jstests/replsets/transaction_table_oplog_replay.js
index 180c1f051c5..12a93013c88 100644
--- a/jstests/replsets/transaction_table_oplog_replay.js
+++ b/jstests/replsets/transaction_table_oplog_replay.js
@@ -4,6 +4,11 @@
(function() {
"use strict";
+ if (jsTest.options().storageEngine === "mmapv1") {
+ jsTestLog("Retryable writes are not supported, skipping test");
+ return;
+ }
+
/**
* Asserts the connection has a document in its transaction collection that has the given
* sessionId, txnNumber, and lastWriteOptimeTs.
diff --git a/jstests/sharding/move_chunk_find_and_modify_with_write_retryability.js b/jstests/sharding/move_chunk_find_and_modify_with_write_retryability.js
index f5af6f88310..9541674d452 100644
--- a/jstests/sharding/move_chunk_find_and_modify_with_write_retryability.js
+++ b/jstests/sharding/move_chunk_find_and_modify_with_write_retryability.js
@@ -3,6 +3,11 @@ load("jstests/sharding/move_chunk_with_session_helper.js");
(function() {
"use strict";
+ if (jsTest.options().storageEngine === "mmapv1") {
+ jsTestLog("Retryable writes are not supported, skipping test");
+ return;
+ }
+
var checkFindAndModifyResult = function(expected, toCheck) {
assert.eq(expected.ok, toCheck.ok);
assert.eq(expected.value, toCheck.value);
diff --git a/jstests/sharding/move_chunk_insert_with_write_retryability.js b/jstests/sharding/move_chunk_insert_with_write_retryability.js
index bdbdef47000..144973169f7 100644
--- a/jstests/sharding/move_chunk_insert_with_write_retryability.js
+++ b/jstests/sharding/move_chunk_insert_with_write_retryability.js
@@ -1,9 +1,13 @@
load("jstests/sharding/move_chunk_with_session_helper.js");
(function() {
-
"use strict";
+ if (jsTest.options().storageEngine === "mmapv1") {
+ jsTestLog("Retryable writes are not supported, skipping test");
+ return;
+ }
+
var st = new ShardingTest({shards: {rs0: {nodes: 2}, rs1: {nodes: 2}}});
assert.commandWorked(st.s.adminCommand({enableSharding: 'test'}));
st.ensurePrimaryShard('test', st.shard0.shardName);
diff --git a/jstests/sharding/move_chunk_remove_with_write_retryability.js b/jstests/sharding/move_chunk_remove_with_write_retryability.js
index 64d1f5d2dee..0edd77e42ec 100644
--- a/jstests/sharding/move_chunk_remove_with_write_retryability.js
+++ b/jstests/sharding/move_chunk_remove_with_write_retryability.js
@@ -1,9 +1,13 @@
load("jstests/sharding/move_chunk_with_session_helper.js");
(function() {
-
"use strict";
+ if (jsTest.options().storageEngine === "mmapv1") {
+ jsTestLog("Retryable writes are not supported, skipping test");
+ return;
+ }
+
var st = new ShardingTest({shards: {rs0: {nodes: 2}, rs1: {nodes: 2}}});
assert.commandWorked(st.s.adminCommand({enableSharding: 'test'}));
st.ensurePrimaryShard('test', st.shard0.shardName);
diff --git a/jstests/sharding/move_chunk_update_with_write_retryability.js b/jstests/sharding/move_chunk_update_with_write_retryability.js
index 1f23db58782..ae3eab575fc 100644
--- a/jstests/sharding/move_chunk_update_with_write_retryability.js
+++ b/jstests/sharding/move_chunk_update_with_write_retryability.js
@@ -1,9 +1,13 @@
load("jstests/sharding/move_chunk_with_session_helper.js");
(function() {
-
"use strict";
+ if (jsTest.options().storageEngine === "mmapv1") {
+ jsTestLog("Retryable writes are not supported, skipping test");
+ return;
+ }
+
var st = new ShardingTest({shards: {rs0: {nodes: 2}, rs1: {nodes: 2}}});
assert.commandWorked(st.s.adminCommand({enableSharding: 'test'}));
st.ensurePrimaryShard('test', st.shard0.shardName);
diff --git a/jstests/sharding/retryable_writes.js b/jstests/sharding/retryable_writes.js
index bed3422c8ff..c8a76d3dce3 100644
--- a/jstests/sharding/retryable_writes.js
+++ b/jstests/sharding/retryable_writes.js
@@ -5,6 +5,11 @@
(function() {
"use strict";
+ if (jsTest.options().storageEngine === "mmapv1") {
+ jsTestLog("Retryable writes are not supported, skipping test");
+ return;
+ }
+
function checkFindAndModifyResult(expected, toCheck) {
assert.eq(expected.ok, toCheck.ok);
assert.eq(expected.value, toCheck.value);
diff --git a/jstests/sharding/session_info_in_oplog.js b/jstests/sharding/session_info_in_oplog.js
index 649d22f6ca6..a25bc02d598 100644
--- a/jstests/sharding/session_info_in_oplog.js
+++ b/jstests/sharding/session_info_in_oplog.js
@@ -6,6 +6,11 @@
(function() {
"use strict";
+ if (jsTest.options().storageEngine === "mmapv1") {
+ jsTestLog("Retryable writes are not supported, skipping test");
+ return;
+ }
+
var checkOplog = function(oplog, lsid, uid, txnNum, stmtId, prevTs, prevTerm) {
assert(oplog != null);
assert(oplog.lsid != null);
diff --git a/jstests/sharding/write_transactions_during_migration.js b/jstests/sharding/write_transactions_during_migration.js
index c8f8e94b71f..5e988328990 100644
--- a/jstests/sharding/write_transactions_during_migration.js
+++ b/jstests/sharding/write_transactions_during_migration.js
@@ -15,6 +15,11 @@ load('./jstests/libs/chunk_manipulation_util.js');
(function() {
"use strict";
+ if (jsTest.options().storageEngine === "mmapv1") {
+ jsTestLog("Retryable writes are not supported, skipping test");
+ return;
+ }
+
var staticMongod = MongoRunner.runMongod({}); // For startParallelOps.
var st = new ShardingTest({shards: {rs0: {nodes: 1}, rs1: {nodes: 1}}});
diff --git a/src/mongo/db/initialize_operation_session_info.cpp b/src/mongo/db/initialize_operation_session_info.cpp
index b4eb785e2c5..9db8ab8c0c8 100644
--- a/src/mongo/db/initialize_operation_session_info.cpp
+++ b/src/mongo/db/initialize_operation_session_info.cpp
@@ -42,7 +42,8 @@ namespace mongo {
void initializeOperationSessionInfo(OperationContext* opCtx,
const BSONObj& requestBody,
bool requiresAuth,
- bool canAcceptTxnNumber) {
+ bool isReplSetMemberOrMongos,
+ bool supportsDocLocking) {
if (!requiresAuth) {
return;
}
@@ -85,7 +86,11 @@ void initializeOperationSessionInfo(OperationContext* opCtx,
opCtx->getLogicalSessionId());
uassert(ErrorCodes::IllegalOperation,
"Transaction numbers are only allowed on a replica set member or mongos",
- canAcceptTxnNumber);
+ isReplSetMemberOrMongos);
+ uassert(ErrorCodes::IllegalOperation,
+ "Transaction numbers are only allowed on storage engines that support "
+ "document-level locking",
+ supportsDocLocking);
uassert(ErrorCodes::BadValue,
"Transaction number cannot be negative",
*osi.getTxnNumber() >= 0);
diff --git a/src/mongo/db/initialize_operation_session_info.h b/src/mongo/db/initialize_operation_session_info.h
index 3b1fdc0f8af..914284f5426 100644
--- a/src/mongo/db/initialize_operation_session_info.h
+++ b/src/mongo/db/initialize_operation_session_info.h
@@ -42,12 +42,13 @@ namespace mongo {
* requiresAuth specifies if the command we're initializing operationSessionInfo for requires
* authorization or not. This can be determined by invoking ->requiresAuth() on the parsed command.
*
- * canAcceptTxnNumber is true if the server is either a mongos or a member of a replica set. Throws
- * if this value is false, and the command contains a transaction number.
+ * Both isReplSetMemberOrMongos and supportsDocLocking need to be true if the command contains a
+ * transaction number, otherwise this function will throw.
*/
void initializeOperationSessionInfo(OperationContext* opCtx,
const BSONObj& requestBody,
bool requiresAuth,
- bool canAcceptTxnNumber);
+ bool isReplSetMemberOrMongos,
+ bool supportsDocLocking);
} // namespace mongo
diff --git a/src/mongo/db/logical_session_id_test.cpp b/src/mongo/db/logical_session_id_test.cpp
index 2f761f3d302..8f7e96943bb 100644
--- a/src/mongo/db/logical_session_id_test.cpp
+++ b/src/mongo/db/logical_session_id_test.cpp
@@ -244,7 +244,7 @@ TEST_F(LogicalSessionIdTest, GenWithoutAuthedUser) {
TEST_F(LogicalSessionIdTest, InitializeOperationSessionInfo_NoSessionIdNoTransactionNumber) {
addSimpleUser(UserName("simple", "test"));
- initializeOperationSessionInfo(_opCtx.get(), BSON("TestCmd" << 1), true, true);
+ initializeOperationSessionInfo(_opCtx.get(), BSON("TestCmd" << 1), true, true, true);
ASSERT(!_opCtx->getLogicalSessionId());
ASSERT(!_opCtx->getTxnNumber());
@@ -259,6 +259,7 @@ TEST_F(LogicalSessionIdTest, InitializeOperationSessionInfo_SessionIdNoTransacti
BSON("TestCmd" << 1 << "lsid" << lsid.toBSON() << "OtherField"
<< "TestField"),
true,
+ true,
true);
ASSERT(_opCtx->getLogicalSessionId());
@@ -274,6 +275,7 @@ TEST_F(LogicalSessionIdTest, InitializeOperationSessionInfo_MissingSessionIdWith
BSON("TestCmd" << 1 << "txnNumber" << 100LL << "OtherField"
<< "TestField"),
true,
+ true,
true),
AssertionException,
ErrorCodes::IllegalOperation);
@@ -289,6 +291,7 @@ TEST_F(LogicalSessionIdTest, InitializeOperationSessionInfo_SessionIdAndTransact
BSON("TestCmd" << 1 << "lsid" << lsid.toBSON() << "txnNumber" << 100LL << "OtherField"
<< "TestField"),
true,
+ true,
true);
ASSERT(_opCtx->getLogicalSessionId());
@@ -298,7 +301,24 @@ TEST_F(LogicalSessionIdTest, InitializeOperationSessionInfo_SessionIdAndTransact
ASSERT_EQ(100, *_opCtx->getTxnNumber());
}
-TEST_F(LogicalSessionIdTest, InitializeOperationSessionInfo_CanAcceptTxnNumberFalse) {
+TEST_F(LogicalSessionIdTest, InitializeOperationSessionInfo_IsReplSetMemberOrMongosFalse) {
+ addSimpleUser(UserName("simple", "test"));
+ LogicalSessionFromClient lsid;
+ lsid.setId(UUID::gen());
+
+ ASSERT_THROWS_CODE(
+ initializeOperationSessionInfo(
+ _opCtx.get(),
+ BSON("TestCmd" << 1 << "lsid" << lsid.toBSON() << "txnNumber" << 100LL << "OtherField"
+ << "TestField"),
+ true,
+ false,
+ true),
+ AssertionException,
+ ErrorCodes::IllegalOperation);
+}
+
+TEST_F(LogicalSessionIdTest, InitializeOperationSessionInfo_SupportsDocLockingFalse) {
addSimpleUser(UserName("simple", "test"));
LogicalSessionFromClient lsid;
lsid.setId(UUID::gen());
@@ -309,6 +329,7 @@ TEST_F(LogicalSessionIdTest, InitializeOperationSessionInfo_CanAcceptTxnNumberFa
BSON("TestCmd" << 1 << "lsid" << lsid.toBSON() << "txnNumber" << 100LL << "OtherField"
<< "TestField"),
true,
+ true,
false),
AssertionException,
ErrorCodes::IllegalOperation);
diff --git a/src/mongo/db/s/SConscript b/src/mongo/db/s/SConscript
index 66fce659767..cd0f836a7c7 100644
--- a/src/mongo/db/s/SConscript
+++ b/src/mongo/db/s/SConscript
@@ -348,6 +348,7 @@ env.CppUnitTest(
'session_catalog_migration_destination_test.cpp',
],
LIBDEPS=[
+ '$BUILD_DIR/mongo/db/ops/write_ops_exec',
'$BUILD_DIR/mongo/s/catalog/sharding_catalog_mock',
'$BUILD_DIR/mongo/s/shard_server_test_fixture',
'sharding',
diff --git a/src/mongo/db/s/session_catalog_migration_destination_test.cpp b/src/mongo/db/s/session_catalog_migration_destination_test.cpp
index dbd867eccda..35fe8dc6962 100644
--- a/src/mongo/db/s/session_catalog_migration_destination_test.cpp
+++ b/src/mongo/db/s/session_catalog_migration_destination_test.cpp
@@ -32,9 +32,11 @@
#include "mongo/client/remote_command_targeter_mock.h"
#include "mongo/db/concurrency/d_concurrency.h"
#include "mongo/db/dbdirectclient.h"
+#include "mongo/db/initialize_operation_session_info.h"
#include "mongo/db/logical_session_cache_noop.h"
#include "mongo/db/logical_session_id.h"
#include "mongo/db/logical_session_id_gen.h"
+#include "mongo/db/ops/write_ops_exec.h"
#include "mongo/db/ops/write_ops_gen.h"
#include "mongo/db/repl/oplog_entry.h"
#include "mongo/db/s/migration_session_id.h"
@@ -244,9 +246,15 @@ public:
Client::initThread("test insert thread");
auto innerOpCtx = Client::getCurrent()->makeOperationContext();
- DBDirectClient client(innerOpCtx.get());
- BSONObj result;
- ASSERT_TRUE(client.runCommand(ns.db().toString(), insertBuilder.obj(), result));
+
+ // The ephemeral for test storage engine doesn't support document-level locking, so
+ // requests with txnNumbers aren't allowed. To get around this, we have to manually set
+ // up the session state and perform the insert.
+ initializeOperationSessionInfo(innerOpCtx.get(), insertBuilder.obj(), true, true, true);
+ OperationContextSession sessionTxnState(innerOpCtx.get(), true);
+ const auto reply = performInserts(innerOpCtx.get(), insertRequest);
+ ASSERT(reply.results.size() == 1);
+ ASSERT(reply.results[0].isOK());
});
insertThread.join();
diff --git a/src/mongo/db/service_entry_point_mongod.cpp b/src/mongo/db/service_entry_point_mongod.cpp
index bae7d227be6..4ef0b70ec81 100644
--- a/src/mongo/db/service_entry_point_mongod.cpp
+++ b/src/mongo/db/service_entry_point_mongod.cpp
@@ -579,11 +579,12 @@ void execCommandDatabase(OperationContext* opCtx,
rpc::TrackingMetadata::get(opCtx).initWithOperName(command->getName());
auto const replCoord = repl::ReplicationCoordinator::get(opCtx);
- initializeOperationSessionInfo(opCtx,
- request.body,
- command->requiresAuth(),
- replCoord->getReplicationMode() ==
- repl::ReplicationCoordinator::modeReplSet);
+ initializeOperationSessionInfo(
+ opCtx,
+ request.body,
+ command->requiresAuth(),
+ replCoord->getReplicationMode() == repl::ReplicationCoordinator::modeReplSet,
+ opCtx->getServiceContext()->getGlobalStorageEngine()->supportsDocLocking());
const auto dbname = request.getDatabase().toString();
uassert(
diff --git a/src/mongo/s/commands/strategy.cpp b/src/mongo/s/commands/strategy.cpp
index 42bb9b9678b..148b10f61c4 100644
--- a/src/mongo/s/commands/strategy.cpp
+++ b/src/mongo/s/commands/strategy.cpp
@@ -255,7 +255,7 @@ void runCommand(OperationContext* opCtx, const OpMsgRequest& request, BSONObjBui
return;
}
- initializeOperationSessionInfo(opCtx, request.body, command->requiresAuth(), true);
+ initializeOperationSessionInfo(opCtx, request.body, command->requiresAuth(), true, true);
int loops = 5;