summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/db/SConscript2
-rw-r--r--src/mongo/db/op_observer_impl.cpp8
-rw-r--r--src/mongo/db/op_observer_impl_test.cpp6
-rw-r--r--src/mongo/db/periodic_runner_job_abort_expired_transactions.cpp3
-rw-r--r--src/mongo/db/s/transaction_coordinator_factory_mongod.cpp3
-rw-r--r--src/mongo/db/transaction_participant.cpp37
-rw-r--r--src/mongo/db/transaction_participant.h2
-rw-r--r--src/mongo/db/transaction_participant.idl63
-rw-r--r--src/mongo/db/transaction_participant_test.cpp5
-rw-r--r--src/mongo/dbtests/storage_timestamp_tests.cpp9
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() {