diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/db/op_observer_impl.cpp | 8 | ||||
-rw-r--r-- | src/mongo/db/op_observer_impl_test.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/periodic_runner_job_abort_expired_transactions.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/s/transaction_coordinator_factory_mongod.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/transaction_participant.cpp | 37 | ||||
-rw-r--r-- | src/mongo/db/transaction_participant.h | 2 | ||||
-rw-r--r-- | src/mongo/db/transaction_participant.idl | 63 | ||||
-rw-r--r-- | src/mongo/db/transaction_participant_test.cpp | 5 | ||||
-rw-r--r-- | src/mongo/dbtests/storage_timestamp_tests.cpp | 9 |
10 files changed, 87 insertions, 51 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript index f3f13c76532..0700e873865 100644 --- a/src/mongo/db/SConscript +++ b/src/mongo/db/SConscript @@ -733,6 +733,7 @@ env.Library( 'transaction_metrics_observer.cpp', 'transaction_participant.cpp', env.Idlc('session_txn_record.idl')[0], + env.Idlc('transaction_participant.idl')[0], env.Idlc('transactions_stats.idl')[0], ], LIBDEPS=[ @@ -758,6 +759,7 @@ env.Library( ], LIBDEPS_PRIVATE=[ '$BUILD_DIR/mongo/util/concurrency/thread_pool', + '$BUILD_DIR/mongo/idl/server_parameter', 'commands/server_status', 'update/update_driver', ] diff --git a/src/mongo/db/op_observer_impl.cpp b/src/mongo/db/op_observer_impl.cpp index 502b8968dda..568d70a504e 100644 --- a/src/mongo/db/op_observer_impl.cpp +++ b/src/mongo/db/op_observer_impl.cpp @@ -56,6 +56,7 @@ #include "mongo/db/server_options.h" #include "mongo/db/session_catalog_mongod.h" #include "mongo/db/transaction_participant.h" +#include "mongo/db/transaction_participant_gen.h" #include "mongo/db/views/durable_view_catalog.h" #include "mongo/s/client/shard_registry.h" #include "mongo/s/grid.h" @@ -66,9 +67,6 @@ namespace mongo { using repl::OplogEntry; -// This is a startup server parameter defined in transaction_participant.cpp. -extern bool useMultipleOplogEntryFormatForTransactions; - namespace { MONGO_FAIL_POINT_DEFINE(failCollectionUpdates); @@ -1239,7 +1237,7 @@ void OpObserverImpl::onUnpreparedTransactionCommit( return; repl::OpTime commitOpTime; - if (!useMultipleOplogEntryFormatForTransactions) { + if (!gUseMultipleOplogEntryFormatForTransactions) { commitOpTime = logApplyOpsForTransaction(opCtx, statements, OplogSlot()).writeOpTime; } else { // Reserve all the optimes in advance, so we only need to get the optime mutex once. We @@ -1288,7 +1286,7 @@ void OpObserverImpl::onTransactionPrepare(OperationContext* opCtx, return; } - if (!useMultipleOplogEntryFormatForTransactions) { + if (!gUseMultipleOplogEntryFormatForTransactions) { // We write the oplog entry in a side transaction so that we do not commit the now-prepared // transaction. // We write an empty 'applyOps' entry if there were no writes to choose a prepare timestamp diff --git a/src/mongo/db/op_observer_impl_test.cpp b/src/mongo/db/op_observer_impl_test.cpp index c61ea466e9b..0240d961ec4 100644 --- a/src/mongo/db/op_observer_impl_test.cpp +++ b/src/mongo/db/op_observer_impl_test.cpp @@ -47,12 +47,12 @@ #include "mongo/db/session_catalog_mongod.h" #include "mongo/db/storage/ephemeral_for_test/ephemeral_for_test_recovery_unit.h" #include "mongo/db/transaction_participant.h" +#include "mongo/db/transaction_participant_gen.h" #include "mongo/s/config_server_test_fixture.h" #include "mongo/unittest/death_test.h" #include "mongo/util/clock_source_mock.h" namespace mongo { -extern bool useMultipleOplogEntryFormatForTransactions; namespace { using repl::OplogEntry; @@ -1308,13 +1308,13 @@ TEST_F(OpObserverTransactionTest, TransactionalDeleteTest) { class OpObserverMultiEntryTransactionTest : public OpObserverTransactionTest { void setUp() override { - useMultipleOplogEntryFormatForTransactions = true; + gUseMultipleOplogEntryFormatForTransactions = true; OpObserverTransactionTest::setUp(); } void tearDown() override { OpObserverTransactionTest::tearDown(); - useMultipleOplogEntryFormatForTransactions = false; + gUseMultipleOplogEntryFormatForTransactions = false; } }; diff --git a/src/mongo/db/periodic_runner_job_abort_expired_transactions.cpp b/src/mongo/db/periodic_runner_job_abort_expired_transactions.cpp index df1278f444f..4d011c329c1 100644 --- a/src/mongo/db/periodic_runner_job_abort_expired_transactions.cpp +++ b/src/mongo/db/periodic_runner_job_abort_expired_transactions.cpp @@ -37,6 +37,7 @@ #include "mongo/db/kill_sessions_local.h" #include "mongo/db/service_context.h" #include "mongo/db/transaction_participant.h" +#include "mongo/db/transaction_participant_gen.h" #include "mongo/util/log.h" #include "mongo/util/periodic_runner.h" @@ -62,7 +63,7 @@ void startPeriodicThreadToAbortExpiredTransactions(ServiceContext* serviceContex PeriodicRunner::PeriodicJob job("startPeriodicThreadToAbortExpiredTransactions", [](Client* client) { static int seconds = 0; - int lifetime = transactionLifetimeLimitSeconds.load(); + int lifetime = gTransactionLifetimeLimitSeconds.load(); invariant(lifetime >= 1); int period = lifetime / 2; diff --git a/src/mongo/db/s/transaction_coordinator_factory_mongod.cpp b/src/mongo/db/s/transaction_coordinator_factory_mongod.cpp index a374f7b32ac..4fea64fd339 100644 --- a/src/mongo/db/s/transaction_coordinator_factory_mongod.cpp +++ b/src/mongo/db/s/transaction_coordinator_factory_mongod.cpp @@ -32,6 +32,7 @@ #include "mongo/db/s/transaction_coordinator_factory.h" #include "mongo/db/s/transaction_coordinator_service.h" #include "mongo/db/transaction_participant.h" +#include "mongo/db/transaction_participant_gen.h" namespace mongo { @@ -46,7 +47,7 @@ MONGO_REGISTER_SHIM(createTransactionCoordinator) opCtx, clientLsid, clientTxnNumber, - clockSource->now() + Seconds(transactionLifetimeLimitSeconds.load())); + clockSource->now() + Seconds(gTransactionLifetimeLimitSeconds.load())); } } // namespace mongo diff --git a/src/mongo/db/transaction_participant.cpp b/src/mongo/db/transaction_participant.cpp index 2d3127323b8..2b3bb949970 100644 --- a/src/mongo/db/transaction_participant.cpp +++ b/src/mongo/db/transaction_participant.cpp @@ -59,37 +59,12 @@ #include "mongo/db/session_catalog.h" #include "mongo/db/stats/fill_locker_info.h" #include "mongo/db/transaction_history_iterator.h" +#include "mongo/db/transaction_participant_gen.h" #include "mongo/util/fail_point_service.h" #include "mongo/util/log.h" #include "mongo/util/net/socket_utils.h" namespace mongo { - -// Server parameter that dictates the max number of milliseconds that any transaction lock request -// will wait for lock acquisition. If an operation provides a greater timeout in a lock request, -// maxTransactionLockRequestTimeoutMillis will override it. If this is set to a negative value, it -// is inactive and nothing will be overridden. -// -// 5 milliseconds will help avoid deadlocks, but will still allow fast-running metadata operations -// to run without aborting transactions. -MONGO_EXPORT_SERVER_PARAMETER(maxTransactionLockRequestTimeoutMillis, int, 5); - -// Server parameter that dictates the lifetime given to each transaction. -// Transactions must eventually expire to preempt storage cache pressure immobilizing the system. -MONGO_EXPORT_SERVER_PARAMETER(transactionLifetimeLimitSeconds, std::int32_t, 60) - ->withValidator([](const auto& potentialNewValue) { - if (potentialNewValue < 1) { - return Status(ErrorCodes::BadValue, - "transactionLifetimeLimitSeconds must be greater than or equal to 1s"); - } - - return Status::OK(); - }); - -// The useMultipleOplogEntryFormatForTransactions is for gating the new oplog format for -// transactions, to allow transactions > 16MB, while in development. -MONGO_EXPORT_STARTUP_SERVER_PARAMETER(useMultipleOplogEntryFormatForTransactions, bool, false); - namespace { // Failpoint which will pause an operation just after allocating a point-in-time storage engine @@ -431,7 +406,7 @@ void TransactionParticipant::Participant::_beginMultiDocumentTransaction(Operati auto now = opCtx->getServiceContext()->getPreciseClockSource()->now(); auto tickSource = opCtx->getServiceContext()->getTickSource(); - o(lk).transactionExpireDate = now + Seconds(transactionLifetimeLimitSeconds.load()); + o(lk).transactionExpireDate = now + Seconds(gTransactionLifetimeLimitSeconds.load()); o(lk).transactionMetricsObserver.onStart( ServerTransactionsMetrics::get(opCtx->getServiceContext()), @@ -580,7 +555,7 @@ TransactionParticipant::OplogSlotReserver::OplogSlotReserver(OperationContext* o invariant(opCtx->writesAreReplicated()); // This thread must still respect the transaction lock timeout, since it can prevent the // transaction from making progress. - auto maxTransactionLockMillis = maxTransactionLockRequestTimeoutMillis.load(); + auto maxTransactionLockMillis = gMaxTransactionLockRequestTimeoutMillis.load(); if (maxTransactionLockMillis >= 0) { opCtx->lockState()->setMaxLockTimeout(Milliseconds(maxTransactionLockMillis)); } @@ -646,7 +621,7 @@ TransactionParticipant::TxnResources::TxnResources(WithLock wl, // This thread must still respect the transaction lock timeout, since it can prevent the // transaction from making progress. - auto maxTransactionLockMillis = maxTransactionLockRequestTimeoutMillis.load(); + auto maxTransactionLockMillis = gMaxTransactionLockRequestTimeoutMillis.load(); if (stashStyle != StashStyle::kSecondary && maxTransactionLockMillis >= 0) { opCtx->lockState()->setMaxLockTimeout(Milliseconds(maxTransactionLockMillis)); } @@ -822,7 +797,7 @@ void TransactionParticipant::Participant::unstashTransactionResources(OperationC // future lock request waits longer than maxTransactionLockRequestTimeoutMillis // to acquire a lock. This is to avoid deadlocks and minimize non-transaction // operation performance degradations. - auto maxTransactionLockMillis = maxTransactionLockRequestTimeoutMillis.load(); + auto maxTransactionLockMillis = gMaxTransactionLockRequestTimeoutMillis.load(); if (opCtx->writesAreReplicated() && maxTransactionLockMillis >= 0) { opCtx->lockState()->setMaxLockTimeout(Milliseconds(maxTransactionLockMillis)); } @@ -1026,7 +1001,7 @@ void TransactionParticipant::Participant::addTransactionOperation( << BSONObjMaxInternalSize << ". Actual size is " << p().transactionOperationBytes, - useMultipleOplogEntryFormatForTransactions || + gUseMultipleOplogEntryFormatForTransactions || p().transactionOperationBytes <= BSONObjMaxInternalSize); } diff --git a/src/mongo/db/transaction_participant.h b/src/mongo/db/transaction_participant.h index 0dd426a1ecd..7791a82817d 100644 --- a/src/mongo/db/transaction_participant.h +++ b/src/mongo/db/transaction_participant.h @@ -56,8 +56,6 @@ namespace mongo { class OperationContext; -extern AtomicWord<int> transactionLifetimeLimitSeconds; - /** * Read timestamp to be used for a speculative transaction. For transactions with read * concern level specified as 'snapshot', we will use 'kAllCommitted' which ensures a snapshot diff --git a/src/mongo/db/transaction_participant.idl b/src/mongo/db/transaction_participant.idl new file mode 100644 index 00000000000..c48f49623e9 --- /dev/null +++ b/src/mongo/db/transaction_participant.idl @@ -0,0 +1,63 @@ +# Copyright (C) 2019-present MongoDB, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the Server Side Public License, version 1, +# as published by MongoDB, Inc. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# Server Side Public License for more details. +# +# You should have received a copy of the Server Side Public License +# along with this program. If not, see +# <http://www.mongodb.com/licensing/server-side-public-license>. +# +# As a special exception, the copyright holders give permission to link the +# code of portions of this program with the OpenSSL library under certain +# conditions as described in each individual source file and distribute +# linked combinations including the program with the OpenSSL library. You +# must comply with the Server Side Public License in all respects for +# all of the code used other than as permitted herein. If you modify file(s) +# with this exception, you may extend this exception to your version of the +# file(s), but you are not obligated to do so. If you do not wish to do so, +# delete this exception statement from your version. If you delete this +# exception statement from all source files in the program, then also delete +# it in the license file. +# + +global: + cpp_namespace: "mongo" + +server_parameters: + maxTransactionLockRequestTimeoutMillis: + description: >- + Max number of milliseconds that any transaction lock request + will wait for lock acquisition. If an operation provides a greater timeout in a lock request, + maxTransactionLockRequestTimeoutMillis will override it. If this is set to a negative value, it + is inactive and nothing will be overridden. + set_at: [ startup, runtime ] + cpp_vartype: AtomicWord<int> + cpp_varname: gMaxTransactionLockRequestTimeoutMillis + # 5 milliseconds will help avoid deadlocks, but will still allow fast-running metadata operations + # to run without aborting transactions. + default: 5 + + transactionLifetimeLimitSeconds: + description: >- + Lifetime given to each transaction. + Transactions must eventually expire to preempt storage cache pressure immobilizing the system. + set_at: [ startup, runtime ] + cpp_vartype: AtomicWord<std::int32_t> + cpp_varname: gTransactionLifetimeLimitSeconds + validator: + gte: 1 + default: 60 + + useMultipleOplogEntryFormatForTransactions: + description: >- + Use multi oplog format for transactions to allow transactions > 16MB. + set_at: startup + cpp_vartype: bool + cpp_varname: gUseMultipleOplogEntryFormatForTransactions + default: false diff --git a/src/mongo/db/transaction_participant_test.cpp b/src/mongo/db/transaction_participant_test.cpp index 731666fb6e4..125454f99c0 100644 --- a/src/mongo/db/transaction_participant_test.cpp +++ b/src/mongo/db/transaction_participant_test.cpp @@ -45,6 +45,7 @@ #include "mongo/db/session_catalog_mongod.h" #include "mongo/db/stats/fill_locker_info.h" #include "mongo/db/transaction_participant.h" +#include "mongo/db/transaction_participant_gen.h" #include "mongo/stdx/future.h" #include "mongo/stdx/memory.h" #include "mongo/unittest/death_test.h" @@ -2411,7 +2412,7 @@ TEST_F(TransactionsMetricsTest, ReportStashedResources) { startTime); ASSERT_EQ( dateFromISOString(transactionDocument.getField("expiryTime").valueStringData()).getValue(), - startTime + Seconds(transactionLifetimeLimitSeconds.load())); + startTime + Seconds(gTransactionLifetimeLimitSeconds.load())); ASSERT_EQ(transactionDocument.getField("timePreparedMicros").numberLong(), preparedDuration); ASSERT_EQ(stashedState.getField("client").valueStringData().toString(), ""); @@ -2492,7 +2493,7 @@ TEST_F(TransactionsMetricsTest, ReportUnstashedResources) { startTime); ASSERT_EQ( dateFromISOString(transactionDocument.getField("expiryTime").valueStringData()).getValue(), - startTime + Seconds(transactionLifetimeLimitSeconds.load())); + startTime + Seconds(gTransactionLifetimeLimitSeconds.load())); ASSERT_EQ(transactionDocument.getField("timePreparedMicros").numberLong(), prepareDuration); // For the following time metrics, we are only verifying that the transaction sub-document is diff --git a/src/mongo/dbtests/storage_timestamp_tests.cpp b/src/mongo/dbtests/storage_timestamp_tests.cpp index 95ba543c364..f13f7968afb 100644 --- a/src/mongo/dbtests/storage_timestamp_tests.cpp +++ b/src/mongo/dbtests/storage_timestamp_tests.cpp @@ -76,16 +76,13 @@ #include "mongo/db/storage/kv/kv_storage_engine.h" #include "mongo/db/storage/snapshot_manager.h" #include "mongo/db/transaction_participant.h" +#include "mongo/db/transaction_participant_gen.h" #include "mongo/dbtests/dbtests.h" #include "mongo/stdx/future.h" #include "mongo/unittest/unittest.h" #include "mongo/util/stacktrace.h" namespace mongo { - -// This is a startup server parameter defined in transaction_participant.cpp. -extern bool useMultipleOplogEntryFormatForTransactions; - namespace { /** * RAII type for operating at a timestamp. Will remove any timestamping when the object destructs. @@ -2748,7 +2745,7 @@ public: class MultiOplogEntryTransaction : public MultiDocumentTransactionTest { public: MultiOplogEntryTransaction() : MultiDocumentTransactionTest("multiOplogEntryTransaction") { - useMultipleOplogEntryFormatForTransactions = true; + gUseMultipleOplogEntryFormatForTransactions = true; const auto currentTime = _clock->getClusterTime(); firstOplogEntryTs = currentTime.addTicks(1).asTimestamp(); secondOplogEntryTs = currentTime.addTicks(2).asTimestamp(); @@ -2756,7 +2753,7 @@ public: } ~MultiOplogEntryTransaction() { - useMultipleOplogEntryFormatForTransactions = false; + gUseMultipleOplogEntryFormatForTransactions = false; } void run() { |