Skip to content

Commit

Permalink
SERVER-31777 deactivate logical sessions for fcv34
Browse files Browse the repository at this point in the history
For anything less than fully upgraded to 3.6:
* suppress logicalSessionTimeoutMinutes in isMaster
* fail any commands that passes lsid
  • Loading branch information
hanumantmk committed Nov 9, 2017
1 parent c3c736d commit bf53cbe
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 21 deletions.
2 changes: 2 additions & 0 deletions jstests/concurrency/fsm_all_sharded_causal_consistency.js
Expand Up @@ -85,6 +85,8 @@ var blacklist = [
'rename_collection_dbname_droptarget.js',
'rename_collection_droptarget.js',

'toggle_feature_compatibility.js', // Sets FCV to 3.4, which will cause session use to fail

'update_simple_eval.js', // eval doesn't work with sharded collections
'update_simple_eval_nolock.js', // eval doesn't work with sharded collections
'update_upsert_multi.js', // our update queries lack shard keys
Expand Down
Expand Up @@ -91,6 +91,8 @@ var blacklist = [
'rename_collection_dbname_droptarget.js',
'rename_collection_droptarget.js',

'toggle_feature_compatibility.js', // Sets FCV to 3.4, which will cause session use to fail

'update_simple_eval.js', // eval doesn't work with sharded collections
'update_simple_eval_nolock.js', // eval doesn't work with sharded collections
'update_upsert_multi.js', // our update queries lack shard keys
Expand Down
8 changes: 8 additions & 0 deletions jstests/libs/override_methods/enable_sessions.js
Expand Up @@ -43,6 +43,10 @@
// Override the runCommand to check for any command obj that does not contain a logical session
// and throw an error.
function runCommandWithLsidCheck(conn, dbName, cmdObj, func, funcArgs) {
if (jsTest.options().disableEnableSessions) {
return func.apply(conn, funcArgs);
}

const cmdName = Object.keys(cmdObj)[0];

// If the command is in a wrapped form, then we look for the actual command object
Expand Down Expand Up @@ -77,6 +81,10 @@
// to cache the session for each connection instance so we can retrieve the same session on
// subsequent calls to getDB.
Mongo.prototype.getDB = function(dbName) {
if (jsTest.options().disableEnableSessions) {
return getDBOriginal.apply(this, arguments);
}

if (!sessionMap.has(this)) {
const session = startSession(this);
sessionMap.set(this, session);
Expand Down
13 changes: 4 additions & 9 deletions jstests/multiVersion/shell_retryable_writes_downgrade.js
Expand Up @@ -78,12 +78,9 @@

assert.commandWorked(db.adminCommand({setFeatureCompatibilityVersion: "3.4"}));

// The server continues to accept lsid and txnNumber while in featureCompatibilityVersion=3.4.
//
// TODO SERVER-31777: The server should return an error if an lsid or txnNumber is specified
// while in featureCompatibilityVersion=3.4.
// The server errors on lsid and txnNumber while in featureCompatibilityVersion=3.4.
testCommandCanBeRetried(function() {
assert.writeOK(coll.insert({_id: "while fCV=3.4"}));
assert.writeError(coll.insert({_id: "while fCV=3.4"}));
});

rst.restart(primary, {binVersion: "3.4"});
Expand All @@ -110,11 +107,9 @@

// When upgrading to MongoDB 3.6 but running as a stand-alone server, the mongo shell should
// still assign a transaction number to its write requests (per the Driver's specification).
//
// TODO SERVER-31777: The server should return an error if an lsid or txnNumber is specified
// while in featureCompatibilityVersion=3.4.
testCommandCanBeRetried(function() {
assert.writeOK(coll.insert({_id: "while binVersion=3.6 as stand-alone and reconnected"}));
assert.writeError(
coll.insert({_id: "while binVersion=3.6 as stand-alone and reconnected"}));
});

db.getSession().endSession();
Expand Down
21 changes: 16 additions & 5 deletions jstests/noPassthrough/logical_session_feature_compatibility.js
Expand Up @@ -51,6 +51,14 @@
" under featureCompatibilityVersion 3.4");
}
}

const isMasterResult = admin.runCommand({isMaster: 1});
assert.commandWorked(isMasterResult);
assert.eq(!errorCode,
isMasterResult.hasOwnProperty("logicalSessionTimeoutMinutes"),
"failed test that we " + (errorCode ? "don't " : "") +
"have logicalSessionTimeoutMinutes under featureCompatibilityVersion " +
compatibilityVersion);
};

// First verify the commands without auth, in feature compatibility version 3.6.
Expand Down Expand Up @@ -90,18 +98,21 @@
assert.commandWorked(admin.adminCommand({setFeatureCompatibilityVersion: "3.6"}));

for (var i = 0; i < 11; i++) {
admin.runCommand({"insert": "test", "documents": [{a: 1}], "lsid": {"id": UUID()}});
assert.commandWorked(
admin.runCommand({"insert": "test", "documents": [{a: 1}], "lsid": {"id": UUID()}}));
}

admin.adminCommand({setFeatureCompatibilityVersion: "3.4"});
assert.commandWorked(admin.adminCommand({setFeatureCompatibilityVersion: "3.4"}));

for (var i = 0; i < 13; i++) {
admin.runCommand({"insert": "test", "documents": [{a: 2}], "lsid": {"id": UUID()}});
assert.commandFailedWithCode(
admin.runCommand({"insert": "test", "documents": [{a: 2}], "lsid": {"id": UUID()}}),
ErrorCodes.InvalidOptions);
}

admin.adminCommand({setFeatureCompatibilityVersion: "3.6"});
assert.commandWorked(admin.adminCommand({setFeatureCompatibilityVersion: "3.6"}));

admin.runCommand({refreshLogicalSessionCacheNow: 1});
assert.commandWorked(admin.runCommand({refreshLogicalSessionCacheNow: 1}));

assert.eq(config.system.sessions.find().count(), 11);

Expand Down
14 changes: 9 additions & 5 deletions src/mongo/db/initialize_operation_session_info.cpp
Expand Up @@ -31,6 +31,7 @@
#include "mongo/db/initialize_operation_session_info.h"

#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands/feature_compatibility_version.h"
#include "mongo/db/logical_session_cache.h"
#include "mongo/db/logical_session_id_helpers.h"
#include "mongo/db/operation_context.h"
Expand All @@ -46,11 +47,6 @@ void initializeOperationSessionInfo(OperationContext* opCtx,
return;
}

if (serverGlobalParams.featureCompatibility.getVersion() !=
ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo36) {
return;
}

{
// If we're using the localhost bypass, logical sessions are disabled
AuthorizationSession* authSession = AuthorizationSession::get(opCtx->getClient());
Expand All @@ -62,6 +58,14 @@ void initializeOperationSessionInfo(OperationContext* opCtx,
auto osi = OperationSessionInfoFromClient::parse("OperationSessionInfo"_sd, requestBody);

if (osi.getSessionId()) {
uassert(ErrorCodes::InvalidOptions,
str::stream() << "cannot pass logical session id unless fully upgraded to "
"featureCompatibilityVersion 3.4. See "
<< feature_compatibility_version::kDochubLink
<< " .",
serverGlobalParams.featureCompatibility.getVersion() ==
ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo36);

stdx::lock_guard<Client> lk(*opCtx->getClient());

opCtx->setLogicalSessionId(makeLogicalSessionId(osi.getSessionId().get(), opCtx));
Expand Down
5 changes: 4 additions & 1 deletion src/mongo/db/repl/replication_info.cpp
Expand Up @@ -362,7 +362,10 @@ class CmdIsMaster : public BasicCommand {
result.appendNumber("maxMessageSizeBytes", MaxMessageSizeBytes);
result.appendNumber("maxWriteBatchSize", write_ops::kMaxWriteBatchSize);
result.appendDate("localTime", jsTime());
result.append("logicalSessionTimeoutMinutes", localLogicalSessionTimeoutMinutes);
if (serverGlobalParams.featureCompatibility.getVersion() ==
ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo36) {
result.append("logicalSessionTimeoutMinutes", localLogicalSessionTimeoutMinutes);
}

if (internalClientElement) {
result.append("minWireVersion",
Expand Down
5 changes: 4 additions & 1 deletion src/mongo/s/commands/cluster_is_master_cmd.cpp
Expand Up @@ -112,7 +112,10 @@ class CmdIsMaster : public BasicCommand {
result.appendNumber("maxMessageSizeBytes", MaxMessageSizeBytes);
result.appendNumber("maxWriteBatchSize", write_ops::kMaxWriteBatchSize);
result.appendDate("localTime", jsTime());
result.append("logicalSessionTimeoutMinutes", localLogicalSessionTimeoutMinutes);
if (serverGlobalParams.featureCompatibility.getVersion() ==
ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo36) {
result.append("logicalSessionTimeoutMinutes", localLogicalSessionTimeoutMinutes);
}

// Mongos tries to keep exactly the same version range of the server for which
// it is compiled.
Expand Down
1 change: 1 addition & 0 deletions src/mongo/shell/utils.js
Expand Up @@ -260,6 +260,7 @@ jsTestOptions = function() {
excludedDBsFromDBHash: TestData.excludedDBsFromDBHash,
alwaysInjectTransactionNumber: TestData.alwaysInjectTransactionNumber,
skipGossipingClusterTime: TestData.skipGossipingClusterTime || false,
disableEnableSessions: TestData.disableEnableSessions,
});
}
return _jsTestOptions;
Expand Down

0 comments on commit bf53cbe

Please sign in to comment.