diff options
author | Kevin Pulo <kevin.pulo@mongodb.com> | 2018-08-09 04:00:41 +0000 |
---|---|---|
committer | Kevin Pulo <kevin.pulo@mongodb.com> | 2018-09-03 06:18:37 +0000 |
commit | 23794c14b03bb272daad7a2b25eca0b80c03a31c (patch) | |
tree | 2c60ec7adb337f99cefe1af28d8b7f4eee3c9239 /src | |
parent | 2704d7a89e64167fcff7356ada111b313146474e (diff) | |
download | mongo-23794c14b03bb272daad7a2b25eca0b80c03a31c.tar.gz |
SERVER-33606 fail to create logical session in shell connected to old servers
Also add --disableImplicitSessions shell cmdline arg.
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/shell/mongo.js | 26 | ||||
-rw-r--r-- | src/mongo/shell/session.js | 19 | ||||
-rw-r--r-- | src/mongo/shell/shell_options.cpp | 8 | ||||
-rw-r--r-- | src/mongo/shell/shell_options.h | 1 | ||||
-rw-r--r-- | src/mongo/shell/shell_utils.cpp | 2 |
5 files changed, 51 insertions, 5 deletions
diff --git a/src/mongo/shell/mongo.js b/src/mongo/shell/mongo.js index 635c77dbc67..416416d8b3f 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 d89be37b8e3..ce781ac0487 100644 --- a/src/mongo/shell/session.js +++ b/src/mongo/shell/session.js @@ -500,6 +500,10 @@ var { let _lastUsed = new Date(); 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) { @@ -835,7 +839,7 @@ var { }; function makeDriverSessionConstructor(implMethods, defaultOptions = {}) { - return function(client, options = defaultOptions) { + var driverSessionConstructor = function(client, options = defaultOptions) { let _options = options; let _hasEnded = false; @@ -964,6 +968,19 @@ var { return this._serverSession.abortTransaction(this); }; }; + + // 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 71cf4ceb147..a3e6d9e82d5 100644 --- a/src/mongo/shell/shell_options.cpp +++ b/src/mongo/shell/shell_options.cpp @@ -220,6 +220,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, opMsgOnly, all") @@ -387,6 +392,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 28766921807..c0a66fb35e2 100644 --- a/src/mongo/shell/shell_options.h +++ b/src/mongo/shell/shell_options.h @@ -73,6 +73,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 cac50ff9de9..cfb15de8f41 100644 --- a/src/mongo/shell/shell_utils.cpp +++ b/src/mongo/shell/shell_utils.cpp @@ -284,7 +284,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) { |