summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Pulo <kevin.pulo@mongodb.com>2018-08-09 04:00:41 +0000
committerJack Mulrow <jack.mulrow@mongodb.com>2018-10-11 16:11:43 -0400
commit8e48340301c668742a5a5bb2a8f1bb68553faaf2 (patch)
tree062e73229b08eaa4d8954598ec4b5d17c538edea
parentf04a3bd23e66c75952eec2dd599d85dc1361f509 (diff)
downloadmongo-8e48340301c668742a5a5bb2a8f1bb68553faaf2.tar.gz
SERVER-33606 fail to create logical session in shell connected to old servers
Also add --disableImplicitSessions shell cmdline arg. (cherry picked from commit 23794c14b03bb272daad7a2b25eca0b80c03a31c)
-rw-r--r--src/mongo/shell/mongo.js26
-rw-r--r--src/mongo/shell/session.js32
-rw-r--r--src/mongo/shell/shell_options.cpp8
-rw-r--r--src/mongo/shell/shell_options.h1
-rw-r--r--src/mongo/shell/shell_utils.cpp2
5 files changed, 60 insertions, 9 deletions
diff --git a/src/mongo/shell/mongo.js b/src/mongo/shell/mongo.js
index faf2b624b66..e574f0b99d7 100644
--- a/src/mongo/shell/mongo.js
+++ b/src/mongo/shell/mongo.js
@@ -263,6 +263,10 @@ connect = function(url, user, pass) {
}
}
+ if (_shouldUseImplicitSessions()) {
+ chatty("Implicit session: " + db.getSession());
+ }
+
// Implicit sessions should not be used when opening a connection. In particular, the buildInfo
// command is erroneously marked as requiring auth in MongoDB 3.6 and therefore fails if a
// logical session id is included in the request.
@@ -445,14 +449,30 @@ Mongo.prototype._getDefaultSession = function getDefaultSession() {
// a logical session id. These implicit sessions are intentionally not causally consistent. If
// implicit sessions have been globally disabled, a dummy session is used instead of a real one.
if (!this.hasOwnProperty("_defaultSession")) {
- this._defaultSession = _shouldUseImplicitSessions()
- ? this.startSession({causalConsistency: false})
- : new _DummyDriverSession(this);
+ if (_shouldUseImplicitSessions()) {
+ try {
+ this._defaultSession = this.startSession({causalConsistency: false});
+ } catch (e) {
+ if (e instanceof DriverSession.UnsupportedError) {
+ chatty("WARNING: No implicit session: " + e.message);
+ this._setDummyDefaultSession();
+ } else {
+ print("ERROR: Implicit session failed: " + e.message);
+ throw(e);
+ }
+ }
+ } else {
+ this._setDummyDefaultSession();
+ }
this._defaultSession._isExplicit = false;
}
return this._defaultSession;
};
+Mongo.prototype._setDummyDefaultSession = function setDummyDefaultSession() {
+ this._defaultSession = new _DummyDriverSession(this);
+};
+
Mongo.prototype.isCausalConsistency = function isCausalConsistency() {
if (!this.hasOwnProperty("_causalConsistency")) {
this._causalConsistency = false;
diff --git a/src/mongo/shell/session.js b/src/mongo/shell/session.js
index ecd80b288cb..905e3682b7a 100644
--- a/src/mongo/shell/session.js
+++ b/src/mongo/shell/session.js
@@ -80,11 +80,11 @@ var {
};
}
- function SessionAwareClient(client) {
- const kWireVersionSupportingCausalConsistency = 6;
- const kWireVersionSupportingLogicalSession = 6;
- const kWireVersionSupportingRetryableWrites = 6;
+ const kWireVersionSupportingCausalConsistency = 6;
+ const kWireVersionSupportingLogicalSession = 6;
+ const kWireVersionSupportingRetryableWrites = 6;
+ function SessionAwareClient(client) {
this.getReadPreference = function getReadPreference(driverSession) {
const sessionOptions = driverSession.getOptions();
if (sessionOptions.getReadPreference() !== undefined) {
@@ -444,8 +444,17 @@ var {
let _nextTxnNum = 0;
this.client = new SessionAwareClient(client);
+ if (!serverSupports(kWireVersionSupportingLogicalSession)) {
+ throw new DriverSession.UnsupportedError(
+ "Logical Sessions are only supported on server versions 3.6 and greater.");
+ }
this.handle = client._startSession();
+ function serverSupports(wireVersion) {
+ return client.getMinWireVersion() <= wireVersion &&
+ wireVersion <= client.getMaxWireVersion();
+ }
+
this.getLastUsed = function getLastUsed() {
return _lastUsed;
};
@@ -585,7 +594,7 @@ var {
}
function makeDriverSessionConstructor(implMethods, defaultOptions = {}) {
- return function(client, options = defaultOptions) {
+ var driverSessionConstructor = function(client, options = defaultOptions) {
let _options = options;
let _hasEnded = false;
@@ -685,6 +694,19 @@ var {
return "session " + tojson(sessionId);
};
};
+
+ // Having a specific Error for when logical sessions aren't supported by the server, allows
+ // the correct fallback behavior in this case (while propagating other errors).
+ driverSessionConstructor.UnsupportedError = function(message) {
+ this.name = "DriverSession.UnsupportedError";
+ this.message = message;
+ this.stack = this.toString() + "\n" + (new Error()).stack;
+ };
+ driverSessionConstructor.UnsupportedError.prototype = Object.create(Error.prototype);
+ driverSessionConstructor.UnsupportedError.prototype.constructor =
+ driverSessionConstructor.UnsupportedError;
+
+ return driverSessionConstructor;
}
const DriverSession = makeDriverSessionConstructor({
diff --git a/src/mongo/shell/shell_options.cpp b/src/mongo/shell/shell_options.cpp
index 0f1e667a36d..6ac0a498956 100644
--- a/src/mongo/shell/shell_options.cpp
+++ b/src/mongo/shell/shell_options.cpp
@@ -214,6 +214,11 @@ Status addMongoShellOptions(moe::OptionSection* options) {
moe::Switch,
"automatically retry write operations upon transient network errors");
+ options->addOptionChaining("disableImplicitSessions",
+ "disableImplicitSessions",
+ moe::Switch,
+ "do not automatically create and use implicit sessions");
+
options
->addOptionChaining(
"rpcProtocols", "rpcProtocols", moe::String, " none, opQueryOnly, opCommandOnly, all")
@@ -372,6 +377,9 @@ Status storeMongoShellOptions(const moe::Environment& params,
if (params.count("retryWrites")) {
shellGlobalParams.shouldRetryWrites = true;
}
+ if (params.count("disableImplicitSessions")) {
+ shellGlobalParams.shouldUseImplicitSessions = false;
+ }
if (params.count("rpcProtocols")) {
std::string protos = params["rpcProtocols"].as<string>();
auto parsedRPCProtos = rpc::parseProtocolSet(protos);
diff --git a/src/mongo/shell/shell_options.h b/src/mongo/shell/shell_options.h
index 6b1852b114a..bee473d2ea9 100644
--- a/src/mongo/shell/shell_options.h
+++ b/src/mongo/shell/shell_options.h
@@ -72,6 +72,7 @@ struct ShellGlobalParams {
std::string writeMode = "commands";
std::string readMode = "compatibility";
bool shouldRetryWrites = false;
+ bool shouldUseImplicitSessions = true;
boost::optional<rpc::ProtocolSet> rpcProtocols = boost::none;
diff --git a/src/mongo/shell/shell_utils.cpp b/src/mongo/shell/shell_utils.cpp
index 196e4060523..e672fedf739 100644
--- a/src/mongo/shell/shell_utils.cpp
+++ b/src/mongo/shell/shell_utils.cpp
@@ -218,7 +218,7 @@ BSONObj shouldRetryWrites(const BSONObj&, void* data) {
}
BSONObj shouldUseImplicitSessions(const BSONObj&, void* data) {
- return BSON("" << true);
+ return BSON("" << shellGlobalParams.shouldUseImplicitSessions);
}
BSONObj interpreterVersion(const BSONObj& a, void* data) {