diff options
author | William Schultz <william.schultz@mongodb.com> | 2018-07-23 12:20:11 -0400 |
---|---|---|
committer | William Schultz <william.schultz@mongodb.com> | 2018-07-23 12:20:11 -0400 |
commit | 826d21952137b50e6376cea627995d24a9eb54a9 (patch) | |
tree | b3decb90d9cfa30078293b7021c83c9122749785 | |
parent | a73722cc85bd1027898be8af651e1312d68a680b (diff) | |
download | mongo-826d21952137b50e6376cea627995d24a9eb54a9.tar.gz |
SERVER-35695 Add server parameter to enable transactions on inMemory
storage engine
-rw-r--r-- | jstests/noPassthrough/transactions_enabled_in_memory_parameter.js | 53 | ||||
-rw-r--r-- | src/mongo/db/initialize_operation_session_info.cpp | 17 |
2 files changed, 69 insertions, 1 deletions
diff --git a/jstests/noPassthrough/transactions_enabled_in_memory_parameter.js b/jstests/noPassthrough/transactions_enabled_in_memory_parameter.js new file mode 100644 index 00000000000..870bc4a3748 --- /dev/null +++ b/jstests/noPassthrough/transactions_enabled_in_memory_parameter.js @@ -0,0 +1,53 @@ +/** + * Verify that transactions can be run on the in-memory storage engine with the + * 'enableInMemoryTransactions' parameter. + */ +(function() { + "use strict"; + + if (jsTest.options().storageEngine !== "inMemory") { + jsTestLog("Skipping test because storageEngine is not inMemory"); + return; + } + + const dbName = "test"; + const collName = "transactions_enabled_in_memory_parameter"; + + const replTest = new ReplSetTest({name: collName, nodes: 1}); + replTest.startSet({storageEngine: "inMemory"}); + replTest.initiate(); + + const primary = replTest.getPrimary(); + + // Initiate a session. + const sessionOptions = {causalConsistency: false}; + const session = primary.getDB(dbName).getMongo().startSession(sessionOptions); + const sessionDb = session.getDatabase(dbName); + + // Create collection. + assert.commandWorked(sessionDb[collName].insert({x: 0})); + + // Check the default parameter value. + let res = primary.adminCommand({"getParameter": 1, "enableInMemoryTransactions": 1}); + assert.eq(res.enableInMemoryTransactions, false); + + // Try to start a transaction that should fail. + session.startTransaction(); + assert.commandFailedWithCode(sessionDb[collName].insert({x: 1}), ErrorCodes.IllegalOperation); + // The abort command will fail on the server, but should reset the local transaction state + // appropriately. + assert.commandFailedWithCode(session.abortTransaction_forTesting(), + ErrorCodes.IllegalOperation); + + // Enable in-memory transactions. + assert.commandWorked( + primary.adminCommand({"setParameter": 1, "enableInMemoryTransactions": true})); + + // Start a transaction that should succeed. + session.startTransaction(); + assert.commandWorked(sessionDb[collName].insert({x: 2})); + session.commitTransaction(); + + session.endSession(); + replTest.stopSet(); +}()); diff --git a/src/mongo/db/initialize_operation_session_info.cpp b/src/mongo/db/initialize_operation_session_info.cpp index 965dc0f1e53..446170d63f2 100644 --- a/src/mongo/db/initialize_operation_session_info.cpp +++ b/src/mongo/db/initialize_operation_session_info.cpp @@ -34,9 +34,16 @@ #include "mongo/db/logical_session_cache.h" #include "mongo/db/logical_session_id_helpers.h" #include "mongo/db/operation_context.h" +#include "mongo/db/server_parameters.h" namespace mongo { +// Allows multi-document transactions to run with the 'inMemory' storage engine. This flag should +// ONLY be used for testing purposes. Production systems should not run transactions on the +// 'inMemory' storage engines until "rollback to a timestamp" is supported on the 'inMemory' storage +// engine (see SERVER-34165). +MONGO_EXPORT_SERVER_PARAMETER(enableInMemoryTransactions, bool, false); + boost::optional<OperationSessionInfoFromClient> initializeOperationSessionInfo( OperationContext* opCtx, const BSONObj& requestBody, @@ -107,10 +114,18 @@ boost::optional<OperationSessionInfoFromClient> initializeOperationSessionInfo( uassert(ErrorCodes::InvalidOptions, "Specifying autocommit=true is not allowed.", !osi.getAutocommit().value()); + + // We allow transactions to run on in-memory storage engines for testing purposes. + bool allowInMemoryTransactions = false; + auto storageEngine = opCtx->getServiceContext()->getStorageEngine(); + if (storageEngine) { + allowInMemoryTransactions = + storageEngine->isEphemeral() && enableInMemoryTransactions.load(); + } uassert(ErrorCodes::IllegalOperation, "Multi-document transactions are only allowed on storage engines that support " "recover to stable timestamp.", - supportsRecoverToStableTimestamp); + supportsRecoverToStableTimestamp || allowInMemoryTransactions); } else { uassert(ErrorCodes::InvalidOptions, "'startTransaction' field requires 'autocommit' field to also be specified", |