summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorPavi Vetriselvan <pvselvan@umich.edu>2019-04-01 13:42:11 -0400
committerPavi Vetriselvan <pvselvan@umich.edu>2019-04-01 14:05:19 -0400
commite433a5aee915568cf73b05e89597903855ed1952 (patch)
tree6c05ba3dab362405e8d07cc5bf65ea86003ddbbf /src/mongo
parente96547906836a12d76b7a1591a0028b1fff8cb79 (diff)
downloadmongo-e433a5aee915568cf73b05e89597903855ed1952.tar.gz
Revert "SERVER-35811 disallow committing at the prepareTimestamp and pin stable TS before oldest uncommitted TS"
This reverts commit b58420e57a2149c350ebf82815fe708850402296 and 33ac1afd4079e04d12554f9b79d1ab07426caf59.
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.cpp27
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl_test.cpp20
-rw-r--r--src/mongo/db/repl/rollback_impl_test.cpp3
-rw-r--r--src/mongo/db/server_transactions_metrics.cpp119
-rw-r--r--src/mongo/db/server_transactions_metrics.h62
-rw-r--r--src/mongo/db/transaction_metrics_observer.cpp18
-rw-r--r--src/mongo/db/transaction_metrics_observer.h8
-rw-r--r--src/mongo/db/transaction_participant.cpp35
-rw-r--r--src/mongo/db/transaction_participant.h7
-rw-r--r--src/mongo/db/transaction_participant_test.cpp206
10 files changed, 56 insertions, 449 deletions
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp
index 674e244acd8..90e8fe71c73 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl.cpp
@@ -74,7 +74,6 @@
#include "mongo/db/repl/update_position_args.h"
#include "mongo/db/repl/vote_requester.h"
#include "mongo/db/server_options.h"
-#include "mongo/db/server_transactions_metrics.h"
#include "mongo/db/transaction_participant.h"
#include "mongo/db/write_concern.h"
#include "mongo/db/write_concern_options.h"
@@ -3376,22 +3375,6 @@ boost::optional<OpTime> ReplicationCoordinatorImpl::_chooseStableOpTimeFromCandi
maximumStableOpTime = OpTime(maximumStableTimestamp, maximumStableOpTime.getTerm());
- // When calculating the stable optime, compare it to the oldest oplog entry timestamp across
- // transactions whose corresponding commit/abort oplog entries have not been majority committed.
- const auto serverTxnMetrics = ServerTransactionsMetrics::get(getGlobalServiceContext());
- const auto oldestNonMajCommittedOpTime =
- serverTxnMetrics->getOldestNonMajorityCommittedOpTime();
-
- if (oldestNonMajCommittedOpTime) {
- if (oldestNonMajCommittedOpTime->getTimestamp() < maximumStableTimestamp) {
- // If there is an oldest non-majority committed timestamp that is less than the current
- // max stable timestamp, then update the max stable timestamp/optime accordingly.
- maximumStableTimestamp = oldestNonMajCommittedOpTime->getTimestamp();
- maximumStableOpTime =
- OpTime(maximumStableTimestamp, oldestNonMajCommittedOpTime->getTerm());
- }
- }
-
// Find the greatest optime candidate that is less than or equal to 'maximumStableOpTime'. To do
// this we first find the upper bound of 'maximumStableOpTime', which points to the smallest
// element in 'candidates' that is greater than 'maximumStableOpTime'. We then step back one
@@ -3451,16 +3434,6 @@ boost::optional<OpTime> ReplicationCoordinatorImpl::_recalculateStableOpTime(Wit
invariant(snapshotOpTime <= commitPoint);
}
- // If we advanced the commit point and have prepared transactions, check if their commit or
- // abort timestamps are <= the commit point. If so, remove them from our oldest non-majority
- // committed optimes set because we know that the commit/abort oplog entries are majority
- // committed.
- // We must remove these optimes before calling _chooseStableOpTimeFromCandidates
- // because we want the stable timestamp to advance up to the commit point if all transactions
- // are committed or aborted.
- auto txnMetrics = ServerTransactionsMetrics::get(getGlobalServiceContext());
- txnMetrics->removeOpTimesLessThanOrEqToCommittedOpTime(commitPoint);
-
// When majority read concern is disabled, the stable opTime is set to the lastApplied, rather
// than the commit point.
auto maximumStableOpTime = serverGlobalParams.enableMajorityReadConcern
diff --git a/src/mongo/db/repl/replication_coordinator_impl_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_test.cpp
index ff89cc2257c..a22ffa49567 100644
--- a/src/mongo/db/repl/replication_coordinator_impl_test.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl_test.cpp
@@ -58,7 +58,6 @@
#include "mongo/db/repl/topology_coordinator.h"
#include "mongo/db/repl/update_position_args.h"
#include "mongo/db/server_options.h"
-#include "mongo/db/server_transactions_metrics.h"
#include "mongo/db/service_context.h"
#include "mongo/db/write_concern_options.h"
#include "mongo/executor/network_interface_mock.h"
@@ -3864,8 +3863,6 @@ TEST_F(StableOpTimeTest, CalculateStableOpTime) {
initReplSetMode();
auto repl = getReplCoord();
- getStorageInterface()->supportsDocLockingBool = true;
- auto txnMetrics = ServerTransactionsMetrics::get(getGlobalServiceContext());
OpTime commitPoint;
boost::optional<OpTime> expectedStableOpTime, stableOpTime;
std::set<OpTime> stableOpTimeCandidates;
@@ -3936,23 +3933,6 @@ TEST_F(StableOpTimeTest, CalculateStableOpTime) {
stableOpTime =
repl->chooseStableOpTimeFromCandidates_forTest(stableOpTimeCandidates, commitPoint);
ASSERT_EQ(expectedStableOpTime, stableOpTime);
-
- // Set the oldest oplog entry OpTime for non-majority committed aborts/commits associated
- // with a multi-document transaction to be before the current commit point. We will then
- // make expectedStableOpTime the new stable optime because it is the only candidate before
- // the oldestNonMajCommittedOpTime.
- commitPoint = OpTime({1, 5}, term);
- const auto oldestNonMajCommittedOpTime = OpTime({1, 3}, term);
- const auto finishOpTime = OpTime({1, 3}, term);
- stableOpTimeCandidates = {oldestNonMajCommittedOpTime, OpTime({1, 4}, term)};
-
- // Adds the oldestNonMajCommittedOpTime to both sets.
- txnMetrics->addActiveOpTime(oldestNonMajCommittedOpTime);
- // Update the finishOpTime.
- txnMetrics->removeActiveOpTime(oldestNonMajCommittedOpTime, finishOpTime);
- stableOpTime =
- repl->chooseStableOpTimeFromCandidates_forTest(stableOpTimeCandidates, commitPoint);
- ASSERT_EQ(oldestNonMajCommittedOpTime, stableOpTime);
}
TEST_F(StableOpTimeTest, CleanupStableOpTimeCandidates) {
diff --git a/src/mongo/db/repl/rollback_impl_test.cpp b/src/mongo/db/repl/rollback_impl_test.cpp
index 354f9f7f3dd..1fcc2bea878 100644
--- a/src/mongo/db/repl/rollback_impl_test.cpp
+++ b/src/mongo/db/repl/rollback_impl_test.cpp
@@ -1387,15 +1387,12 @@ TEST_F(RollbackImplTest, RollbackCallsClearOpTimes) {
ASSERT(txnMetrics->getOldestActiveOpTime());
ASSERT_EQ(*txnMetrics->getOldestActiveOpTime(), repl::OpTime(Timestamp(1, 2), 0));
ASSERT_EQ(txnMetrics->getTotalActiveOpTimes(), 2U);
- ASSERT(txnMetrics->getOldestNonMajorityCommittedOpTime());
- ASSERT_EQ(*txnMetrics->getOldestNonMajorityCommittedOpTime(), repl::OpTime(Timestamp(1, 2), 0));
// Call runRollback to make sure these variables get cleared.
ASSERT_OK(_rollback->runRollback(_opCtx.get()));
ASSERT_FALSE(txnMetrics->getOldestActiveOpTime());
ASSERT_EQ(txnMetrics->getTotalActiveOpTimes(), 0U);
- ASSERT_FALSE(txnMetrics->getOldestNonMajorityCommittedOpTime());
}
/**
diff --git a/src/mongo/db/server_transactions_metrics.cpp b/src/mongo/db/server_transactions_metrics.cpp
index a46a663e0b1..5696b7079be 100644
--- a/src/mongo/db/server_transactions_metrics.cpp
+++ b/src/mongo/db/server_transactions_metrics.cpp
@@ -149,8 +149,9 @@ void ServerTransactionsMetrics::decrementCurrentPrepared() {
_currentPrepared.fetchAndSubtract(1);
}
-boost::optional<repl::OpTime> ServerTransactionsMetrics::_calculateOldestActiveOpTime(
- WithLock) const {
+
+boost::optional<repl::OpTime> ServerTransactionsMetrics::getOldestActiveOpTime() const {
+ stdx::lock_guard<stdx::mutex> lm(_mutex);
if (_oldestActiveOplogEntryOpTimes.empty()) {
return boost::none;
}
@@ -162,110 +163,20 @@ void ServerTransactionsMetrics::addActiveOpTime(repl::OpTime oldestOplogEntryOpT
auto ret = _oldestActiveOplogEntryOpTimes.insert(oldestOplogEntryOpTime);
// If ret.second is false, the OpTime we tried to insert already existed.
invariant(ret.second,
- str::stream() << "This oplog entry OpTime already exists in "
- << "oldestActiveOplogEntryOpTimes."
+ str::stream() << "This oplog entry OpTime already exists."
<< "oldestOplogEntryOpTime: "
<< oldestOplogEntryOpTime.toString());
-
- // Add this OpTime to the oldestNonMajorityCommittedOpTimes set with a finishOpTime of
- // Timestamp::max() to signify that it has not been committed/aborted.
- std::pair<repl::OpTime, repl::OpTime> nonMajCommittedOpTime(oldestOplogEntryOpTime,
- repl::OpTime::max());
- auto ret2 = _oldestNonMajorityCommittedOpTimes.insert(nonMajCommittedOpTime);
- // If ret2.second is false, the OpTime we tried to insert already existed.
- invariant(ret2.second,
- str::stream() << "This oplog entry OpTime already exists in "
- << "oldestNonMajorityCommittedOpTimes."
- << "oldestOplogEntryOpTime: "
- << oldestOplogEntryOpTime.toString());
- _oldestActiveOplogEntryOpTime = _calculateOldestActiveOpTime(lm);
}
-void ServerTransactionsMetrics::removeActiveOpTime(repl::OpTime oldestOplogEntryOpTime,
- boost::optional<repl::OpTime> finishOpTime) {
+void ServerTransactionsMetrics::removeActiveOpTime(repl::OpTime oldestOplogEntryOpTime) {
stdx::lock_guard<stdx::mutex> lm(_mutex);
auto it = _oldestActiveOplogEntryOpTimes.find(oldestOplogEntryOpTime);
invariant(it != _oldestActiveOplogEntryOpTimes.end(),
- str::stream() << "This oplog entry OpTime does not exist in or has already been "
- << "removed from oldestActiveOplogEntryOpTimes."
- << "OpTime: "
- << oldestOplogEntryOpTime.toString());
- _oldestActiveOplogEntryOpTimes.erase(it);
-
- if (!finishOpTime) {
- return;
- }
-
- // The transaction's oldestOplogEntryOpTime now has a corresponding finishTime, which will
- // be its commit or abort oplog entry OpTime. Add this pair to the
- // oldestNonMajorityCommittedOpTimes.
- // Currently, the oldestOplogEntryOpTime will be a prepareOpTime so we will only have a
- // finishOpTime if we are committing a prepared transaction or aborting an active prepared
- // transaction.
- std::pair<repl::OpTime, repl::OpTime> opTimeToRemove(oldestOplogEntryOpTime,
- repl::OpTime::max());
- auto it2 = _oldestNonMajorityCommittedOpTimes.find(opTimeToRemove);
- invariant(it2 != _oldestNonMajorityCommittedOpTimes.end(),
- str::stream() << "This oplog entry OpTime does not exist in or has already been "
- << "removed from oldestNonMajorityCommittedOpTimes"
+ str::stream() << "This oplog entry OpTime does not exist "
+ << "or has already been removed."
<< "oldestOplogEntryOpTime: "
<< oldestOplogEntryOpTime.toString());
- _oldestNonMajorityCommittedOpTimes.erase(it2);
-
- std::pair<repl::OpTime, repl::OpTime> nonMajCommittedOpTime(oldestOplogEntryOpTime,
- *finishOpTime);
- auto ret = _oldestNonMajorityCommittedOpTimes.insert(nonMajCommittedOpTime);
- // If ret.second is false, the OpTime we tried to insert already existed.
- invariant(ret.second,
- str::stream() << "This oplog entry OpTime pair already exists in "
- << "oldestNonMajorityCommittedOpTimes."
- << "oldestOplogEntryOpTime: "
- << oldestOplogEntryOpTime.toString()
- << "finishOpTime: "
- << finishOpTime->toString());
- _oldestActiveOplogEntryOpTime = _calculateOldestActiveOpTime(lm);
-}
-
-boost::optional<repl::OpTime> ServerTransactionsMetrics::getOldestNonMajorityCommittedOpTime()
- const {
- stdx::lock_guard<stdx::mutex> lm(_mutex);
- if (_oldestNonMajorityCommittedOpTimes.empty()) {
- return boost::none;
- }
- const auto oldestNonMajorityCommittedOpTime = _oldestNonMajorityCommittedOpTimes.begin()->first;
- invariant(!oldestNonMajorityCommittedOpTime.isNull());
- return oldestNonMajorityCommittedOpTime;
-}
-
-void ServerTransactionsMetrics::removeOpTimesLessThanOrEqToCommittedOpTime(
- repl::OpTime committedOpTime) {
- stdx::lock_guard<stdx::mutex> lm(_mutex);
- // Iterate through oldestNonMajorityCommittedOpTimes and remove all pairs whose "finishOpTime"
- // is now less than or equal to the commit point.
- for (auto it = _oldestNonMajorityCommittedOpTimes.begin();
- it != _oldestNonMajorityCommittedOpTimes.end();) {
- if (it->second <= committedOpTime) {
- it = _oldestNonMajorityCommittedOpTimes.erase(it);
- } else {
- ++it;
- }
- }
-}
-
-boost::optional<repl::OpTime>
-ServerTransactionsMetrics::getFinishOpTimeOfOldestNonMajCommitted_forTest() const {
- stdx::lock_guard<stdx::mutex> lm(_mutex);
- if (_oldestNonMajorityCommittedOpTimes.empty()) {
- return boost::none;
- }
- const auto oldestNonMajorityCommittedOpTime =
- _oldestNonMajorityCommittedOpTimes.begin()->second;
- return oldestNonMajorityCommittedOpTime;
-}
-
-boost::optional<repl::OpTime> ServerTransactionsMetrics::getOldestActiveOpTime() const {
- stdx::lock_guard<stdx::mutex> lm(_mutex);
- return _oldestActiveOplogEntryOpTime;
+ _oldestActiveOplogEntryOpTimes.erase(it);
}
unsigned int ServerTransactionsMetrics::getTotalActiveOpTimes() const {
@@ -294,21 +205,17 @@ void ServerTransactionsMetrics::updateStats(TransactionsStats* stats, OperationC
stats->setCurrentPrepared(_currentPrepared.load());
stats->setOldestOpenUnpreparedReadTimestamp(
ServerTransactionsMetrics::_getOldestOpenUnpreparedReadTimestamp(opCtx));
- // Acquire _mutex before reading _oldestActiveOplogEntryOpTime.
- stdx::lock_guard<stdx::mutex> lm(_mutex);
- // To avoid compression loss, we use the null OpTime if no oldest active transaction optime is
- // stored.
- repl::OpTime oldestActiveOplogEntryOpTime = (_oldestActiveOplogEntryOpTime != boost::none)
- ? _oldestActiveOplogEntryOpTime.get()
- : repl::OpTime();
+ // To avoid compression loss, we use the null OpTime if no oldest active transaction
+ // optime is stored.
+ auto oldestActiveOpTime = getOldestActiveOpTime();
+ repl::OpTime oldestActiveOplogEntryOpTime =
+ (oldestActiveOpTime != boost::none) ? oldestActiveOpTime.get() : repl::OpTime();
stats->setOldestActiveOplogEntryOpTime(oldestActiveOplogEntryOpTime);
}
void ServerTransactionsMetrics::clearOpTimes() {
stdx::lock_guard<stdx::mutex> lm(_mutex);
- _oldestActiveOplogEntryOpTime = boost::none;
_oldestActiveOplogEntryOpTimes.clear();
- _oldestNonMajorityCommittedOpTimes.clear();
}
namespace {
diff --git a/src/mongo/db/server_transactions_metrics.h b/src/mongo/db/server_transactions_metrics.h
index 035e9ad6ee0..706200409da 100644
--- a/src/mongo/db/server_transactions_metrics.h
+++ b/src/mongo/db/server_transactions_metrics.h
@@ -31,6 +31,7 @@
#include <set>
+#include "mongo/bson/timestamp.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/repl/optime.h"
#include "mongo/db/service_context.h"
@@ -93,20 +94,15 @@ public:
boost::optional<repl::OpTime> getOldestActiveOpTime() const;
/**
- * Add the transaction's oplog entry OpTime to oldestActiveOplogEntryOpTimes, a set of OpTimes.
- * Also creates a pair with this OpTime and OpTime::max() as the corresponding commit/abort
- * oplog entry OpTime. Finally, adds this to oldestNonMajorityCommittedOpTimes.
+ * Add the transaction's oplog entry OpTime to a set of OpTimes.
*/
void addActiveOpTime(repl::OpTime oldestOplogEntryOpTime);
/**
* Remove the corresponding transaction oplog entry OpTime if the transaction commits or
- * aborts. Also updates the pair in oldestNonMajorityCommittedOpTimes with the
- * oldestOplogEntryOpTime to have a valid finishOpTime instead of OpTime::max(). It's stored in
- * the format: < oldestOplogEntryOpTime, finishOpTime >.
+ * aborts.
*/
- void removeActiveOpTime(repl::OpTime oldestOplogEntryOpTime,
- boost::optional<repl::OpTime> finishOpTime);
+ void removeActiveOpTime(repl::OpTime oldestOplogEntryOpTime);
/**
* Returns the number of transaction oplog entry OpTimes currently stored.
@@ -114,51 +110,19 @@ public:
unsigned int getTotalActiveOpTimes() const;
/**
- * Returns the oldest oplog entry OpTime across transactions whose corresponding commit or
- * abort oplog entry has not been majority committed.
- */
- boost::optional<repl::OpTime> getOldestNonMajorityCommittedOpTime() const;
-
- /**
- * Remove the corresponding transaction oplog entry OpTime pair from
- * oldestNonMajorityCommittedOpTimes if the transaction is majority committed or aborted.
- * We determine this by checking if there are any pairs in the set whose
- * 'finishOpTime' <= 'committedOpTime'.
- */
- void removeOpTimesLessThanOrEqToCommittedOpTime(repl::OpTime committedOpTime);
-
- /**
- * Testing function that adds an OpTime pair to oldestNonMajorityCommittedOpTimes.
- */
- void addNonMajCommittedOpTimePair_forTest(std::pair<repl::OpTime, repl::OpTime> OpTimePair);
-
- /**
- * Testing function that returns the oldest non-majority committed OpTime pair in the form:
- * < oldestOplogEntryOpTime, finishOpTime >.
- */
- boost::optional<repl::OpTime> getFinishOpTimeOfOldestNonMajCommitted_forTest() const;
-
- /**
* Appends the accumulated stats to a transactions stats object.
*/
void updateStats(TransactionsStats* stats, OperationContext* opCtx);
/**
* Invalidates the in-memory state of prepared transactions during replication rollback by
- * clearing oldestActiveOplogEntryOpTime, oldestActiveOplogEntryOpTimes, and
- * oldestNonMajorityCommittedOpTimes. These variables/data structures should be properly
- * reconstructed during replication recovery.
+ * clearing _oldestActiveOplogEntryOpTimes. This data structure should be properly reconstructed
+ * during replication recovery.
*/
void clearOpTimes();
private:
/**
- * Returns the first and oldest optime in the ordered set of active oplog entry optimes.
- * Returns boost::none if there are no transaction oplog entry optimes stored.
- */
- boost::optional<repl::OpTime> _calculateOldestActiveOpTime(WithLock) const;
-
- /**
* Returns the oldest read timestamp in use by any open unprepared transaction. This will
* return a null timestamp if there is no oldest open unprepared read timestamp to be
* returned.
@@ -203,24 +167,10 @@ private:
// The current number of transactions in the prepared state.
AtomicWord<unsigned long long> _currentPrepared{0};
- // The optime of the oldest oplog entry for any active transaction.
- boost::optional<repl::OpTime> _oldestActiveOplogEntryOpTime; // (M)
-
// Maintain the oldest oplog entry OpTime across all active transactions. Currently, we only
// write an oplog entry for an ongoing transaction if it is in the `prepare` state. By
// maintaining an ordered set of OpTimes, the OpTime at the beginning will be the oldest.
std::set<repl::OpTime> _oldestActiveOplogEntryOpTimes; // (M)
-
- // Maintain the oldest oplog entry OpTime across transactions whose corresponding abort/commit
- // oplog entries have not been majority committed. Since this is an ordered set, the first
- // pair's oldestOplogEntryOpTime represents the earliest OpTime that we should pin the stable
- // timestamp behind.
- // Each pair is structured as follows: <oldestOplogEntryOpTime, finishOpTime>
- // 'oldestOplogEntryOpTime': The first oplog entry OpTime written by a transaction.
- // 'finishOpTime': The commit/abort oplog entry OpTime.
- // Once the corresponding abort/commit entry has been majority committed, remove the pair from
- // this set.
- std::set<std::pair<repl::OpTime, repl::OpTime>> _oldestNonMajorityCommittedOpTimes; // (M)
};
} // namespace mongo
diff --git a/src/mongo/db/transaction_metrics_observer.cpp b/src/mongo/db/transaction_metrics_observer.cpp
index e1f092d60b5..fd19a6cba65 100644
--- a/src/mongo/db/transaction_metrics_observer.cpp
+++ b/src/mongo/db/transaction_metrics_observer.cpp
@@ -95,11 +95,8 @@ void TransactionMetricsObserver::onUnstash(ServerTransactionsMetrics* serverTran
void TransactionMetricsObserver::onCommit(ServerTransactionsMetrics* serverTransactionsMetrics,
TickSource* tickSource,
boost::optional<repl::OpTime> oldestOplogEntryOpTime,
- boost::optional<repl::OpTime> commitOpTime,
Top* top,
bool wasPrepared) {
- invariant((oldestOplogEntryOpTime != boost::none && commitOpTime != boost::none) ||
- (oldestOplogEntryOpTime == boost::none && commitOpTime == boost::none));
//
// Per transaction metrics.
//
@@ -129,7 +126,7 @@ void TransactionMetricsObserver::onCommit(ServerTransactionsMetrics* serverTrans
// Remove this transaction's oldest oplog entry OpTime if one was written.
if (oldestOplogEntryOpTime) {
- serverTransactionsMetrics->removeActiveOpTime(*oldestOplogEntryOpTime, commitOpTime);
+ serverTransactionsMetrics->removeActiveOpTime(*oldestOplogEntryOpTime);
}
}
@@ -137,11 +134,8 @@ void TransactionMetricsObserver::_onAbortActive(
ServerTransactionsMetrics* serverTransactionsMetrics,
TickSource* tickSource,
boost::optional<repl::OpTime> oldestOplogEntryOpTime,
- boost::optional<repl::OpTime> abortOpTime,
Top* top,
bool wasPrepared) {
- invariant((oldestOplogEntryOpTime != boost::none && abortOpTime != boost::none) ||
- (oldestOplogEntryOpTime == boost::none && abortOpTime == boost::none));
auto curTick = tickSource->getTicks();
invariant(_singleTransactionStats.isActive());
@@ -163,7 +157,7 @@ void TransactionMetricsObserver::_onAbortActive(
// Remove this transaction's oldest oplog entry OpTime if one was written.
if (oldestOplogEntryOpTime) {
- serverTransactionsMetrics->removeActiveOpTime(*oldestOplogEntryOpTime, abortOpTime);
+ serverTransactionsMetrics->removeActiveOpTime(*oldestOplogEntryOpTime);
}
}
@@ -183,25 +177,22 @@ void TransactionMetricsObserver::_onAbortInactive(
// Remove this transaction's oldest oplog entry OpTime if one was written.
if (oldestOplogEntryOpTime) {
- serverTransactionsMetrics->removeActiveOpTime(*oldestOplogEntryOpTime, boost::none);
+ serverTransactionsMetrics->removeActiveOpTime(*oldestOplogEntryOpTime);
}
}
void TransactionMetricsObserver::onAbort(ServerTransactionsMetrics* serverTransactionsMetrics,
TickSource* tickSource,
boost::optional<repl::OpTime> oldestOplogEntryOpTime,
- boost::optional<repl::OpTime> abortOpTime,
Top* top,
bool wasPrepared) {
if (_singleTransactionStats.isActive()) {
_onAbortActive(serverTransactionsMetrics,
tickSource,
oldestOplogEntryOpTime,
- abortOpTime,
top,
wasPrepared);
} else {
- invariant(abortOpTime == boost::none);
invariant(!wasPrepared);
_onAbortInactive(serverTransactionsMetrics, tickSource, oldestOplogEntryOpTime, top);
}
@@ -260,14 +251,13 @@ void TransactionMetricsObserver::_onAbort(ServerTransactionsMetrics* serverTrans
void TransactionMetricsObserver::onPrepare(ServerTransactionsMetrics* serverTransactionsMetrics,
repl::OpTime prepareOpTime,
TickSource::Tick curTick) {
-
//
// Per transaction metrics.
//
_singleTransactionStats.setPreparedStartTime(curTick);
// Since we currently only write an oplog entry for an in progress transaction when it is in
- // the prepare state, the prepareOpTime is currently the oldest OpTime written to the
+ // the prepare state, the prepareOpTime is currently the oldest optime written to the
// oplog for this transaction.
serverTransactionsMetrics->addActiveOpTime(prepareOpTime);
serverTransactionsMetrics->incrementCurrentPrepared();
diff --git a/src/mongo/db/transaction_metrics_observer.h b/src/mongo/db/transaction_metrics_observer.h
index cbb00d21fd9..2634e56728f 100644
--- a/src/mongo/db/transaction_metrics_observer.h
+++ b/src/mongo/db/transaction_metrics_observer.h
@@ -70,12 +70,10 @@ public:
/**
* Updates relevant metrics when a transaction commits. Also removes this transaction's oldest
* oplog entry OpTime from the oldestActiveOplogEntryOpTimes set if it is not boost::none.
- * Finally, updates an entry in oldestNonMajorityCommittedOpTimes to include its commit OpTime.
*/
void onCommit(ServerTransactionsMetrics* serverTransactionsMetrics,
TickSource* tickSource,
boost::optional<repl::OpTime> oldestOplogEntryOpTime,
- boost::optional<repl::OpTime> commitOpTime,
Top* top,
bool wasPrepared);
@@ -86,13 +84,12 @@ public:
void onAbort(ServerTransactionsMetrics* serverTransactionsMetrics,
TickSource* tickSource,
boost::optional<repl::OpTime> oldestOplogEntryOpTime,
- boost::optional<repl::OpTime> abortOpTime,
Top* top,
bool wasPrepared);
/**
- * Adds the prepareOpTime, which is currently the Timestamp of the first oplog entry written by
- * an active transaction, to the oldestActiveOplogEntryTS set.
+ * Adds the prepareOpTime, which is currently the OpTime of the first oplog entry written
+ * by an active transaction, to the oldestActiveOplogEntryOpTimes set.
*/
void onPrepare(ServerTransactionsMetrics* serverTransactionsMetrics,
repl::OpTime prepareOpTime,
@@ -138,7 +135,6 @@ private:
void _onAbortActive(ServerTransactionsMetrics* serverTransactionsMetrics,
TickSource* tickSource,
boost::optional<repl::OpTime> oldestOplogEntryOpTime,
- boost::optional<repl::OpTime> abortOpTime,
Top* top,
bool wasPrepared);
diff --git a/src/mongo/db/transaction_participant.cpp b/src/mongo/db/transaction_participant.cpp
index 8ed304c50d7..59ec112a210 100644
--- a/src/mongo/db/transaction_participant.cpp
+++ b/src/mongo/db/transaction_participant.cpp
@@ -1030,14 +1030,11 @@ Timestamp TransactionParticipant::Participant::prepareTransaction(
abortGuard.dismiss();
- // For prepared transactions, we must update ServerTransactionMetrics with the prepare optime
- // before the prepare oplog entry is written so that we don't incorrectly advance the stable
- // timestamp.
invariant(!p().oldestOplogEntryOpTime,
- str::stream() << "This transaction's oldest oplog entry Timestamp has already "
+ str::stream() << "This transaction's oldest oplog entry OpTime has already "
<< "been set to: "
<< p().oldestOplogEntryOpTime->toString());
- // Keep track of the Timestamp from the first oplog entry written by this transaction.
+ // Keep track of the OpTime from the first oplog entry written by this transaction.
p().oldestOplogEntryOpTime = prepareOplogSlot.opTime;
// Maintain the OpTime of the oldest active oplog entry for this transaction. We currently
@@ -1126,7 +1123,7 @@ void TransactionParticipant::Participant::commitUnpreparedTransaction(OperationC
// TODO SERVER-37129: Remove this invariant once we allow transactions larger than 16MB.
invariant(!p().oldestOplogEntryOpTime,
- str::stream() << "The oldest oplog entry Timestamp should not have been set because "
+ str::stream() << "The oldest oplog entry OpTime should not have been set because "
<< "this transaction is not prepared. But, it is currently "
<< p().oldestOplogEntryOpTime->toString());
@@ -1191,8 +1188,8 @@ void TransactionParticipant::Participant::commitPreparedTransaction(
uassert(
ErrorCodes::InvalidOptions, "'commitTimestamp' cannot be null", !commitTimestamp.isNull());
uassert(ErrorCodes::InvalidOptions,
- "'commitTimestamp' must be greater than the 'prepareTimestamp'",
- commitTimestamp > o().prepareOpTime.getTimestamp());
+ "'commitTimestamp' must be greater than or equal to 'prepareTimestamp'",
+ commitTimestamp >= o().prepareOpTime.getTimestamp());
{
stdx::lock_guard<Client> lk(*opCtx->getClient());
@@ -1245,9 +1242,8 @@ void TransactionParticipant::Participant::commitPreparedTransaction(
clearOperationsInMemory(opCtx);
// If we are committing a prepared transaction, then we must have already recorded this
- // transaction's oldest oplog entry optime.
+ // transaction's oldest oplog entry OpTime.
invariant(p().oldestOplogEntryOpTime);
- p().finishOpTime = commitOplogSlotOpTime;
_finishCommitTransaction(opCtx);
} catch (...) {
@@ -1300,7 +1296,6 @@ void TransactionParticipant::Participant::_finishCommitTransaction(OperationCont
o(lk).transactionMetricsObserver.onCommit(ServerTransactionsMetrics::get(opCtx),
tickSource,
p().oldestOplogEntryOpTime,
- p().finishOpTime,
&Top::get(getGlobalServiceContext()),
isCommittingWithPrepare);
o(lk).transactionMetricsObserver.onTransactionOperation(
@@ -1364,7 +1359,7 @@ void TransactionParticipant::Participant::abortActiveUnpreparedOrStashPreparedTr
// TODO SERVER-37129: Remove this invariant once we allow transactions larger than 16MB.
invariant(!p().oldestOplogEntryOpTime,
- str::stream() << "The oldest oplog entry Timestamp should not have been set because "
+ str::stream() << "The oldest oplog entry OpTime should not have been set because "
<< "this transaction is not prepared. But, it is currently "
<< p().oldestOplogEntryOpTime->toString());
@@ -1409,12 +1404,6 @@ void TransactionParticipant::Participant::_abortActiveTransaction(
invariant(opObserver);
opObserver->onTransactionAbort(opCtx, abortOplogSlot);
- // Set the finishOpTime of this transaction if we have recorded this transaction's oldest oplog
- // entry optime.
- if (p().oldestOplogEntryOpTime) {
- p().finishOpTime = repl::ReplClientInfo::forClient(opCtx->getClient()).getLastOp();
- }
-
// Only abort the transaction in session if it's in expected states.
// When the state of active transaction on session is not expected, it means another
// thread has already aborted the transaction on session.
@@ -1454,7 +1443,6 @@ void TransactionParticipant::Participant::_abortTransactionOnSession(OperationCo
ServerTransactionsMetrics::get(opCtx->getServiceContext()),
tickSource,
p().oldestOplogEntryOpTime,
- p().finishOpTime,
&Top::get(opCtx->getServiceContext()),
o().txnState.isPrepared());
}
@@ -1772,10 +1760,6 @@ std::string TransactionParticipant::Participant::_transactionInfoForLog(
s << " oldestOplogEntryOpTime:" << p().oldestOplogEntryOpTime->toString();
}
- if (p().finishOpTime) {
- s << " finishOpTime:" << p().finishOpTime->toString();
- }
-
// Total duration of the transaction.
s << ", "
<< duration_cast<Milliseconds>(singleTransactionStats.getDuration(tickSource, curTick));
@@ -1949,7 +1933,6 @@ void TransactionParticipant::Participant::_resetTransactionState(
p().transactionOperations.clear();
o(wl).prepareOpTime = repl::OpTime();
p().oldestOplogEntryOpTime = boost::none;
- p().finishOpTime = boost::none;
p().speculativeTransactionReadOpTime = repl::OpTime();
p().multikeyPathInfo.clear();
p().autoCommit = boost::none;
@@ -1989,8 +1972,8 @@ void TransactionParticipant::Participant::abortPreparedTransactionForRollback(
// we only modify these variables when adding an operation to a transaction. Since this
// transaction is already prepared, we cannot add more operations to it. We will have this
// in the prepare oplog entry.
- // Both _finishOpTime and _oldestOplogEntryOpTime will be reset to boost::none. With a
- // prepared transaction, the latter is the same as the prepareOpTime.
+ // The oldestOplogEntryOpTime will be reset to boost::none. With a prepared transaction, this
+ // is the same as the prepareOpTime.
_resetTransactionState(lg, TransactionState::kNone);
}
diff --git a/src/mongo/db/transaction_participant.h b/src/mongo/db/transaction_participant.h
index e68c3205afd..6d5b1718513 100644
--- a/src/mongo/db/transaction_participant.h
+++ b/src/mongo/db/transaction_participant.h
@@ -633,10 +633,6 @@ public:
return p().oldestOplogEntryOpTime;
}
- boost::optional<repl::OpTime> getFinishOpTimeForTest() const {
- return p().finishOpTime;
- }
-
const Locker* getTxnResourceStashLockerForTest() const {
invariant(o().txnResourceStash);
return o().txnResourceStash->locker();
@@ -916,9 +912,6 @@ private:
// Tracks the OpTime of the first oplog entry written by this TransactionParticipant.
boost::optional<repl::OpTime> oldestOplogEntryOpTime;
- // Tracks the OpTime of the abort/commit oplog entry associated with this transaction.
- boost::optional<repl::OpTime> finishOpTime;
-
//
// Retryable writes state
//
diff --git a/src/mongo/db/transaction_participant_test.cpp b/src/mongo/db/transaction_participant_test.cpp
index 5e4051da203..31d09c22656 100644
--- a/src/mongo/db/transaction_participant_test.cpp
+++ b/src/mongo/db/transaction_participant_test.cpp
@@ -41,7 +41,6 @@
#include "mongo/db/repl/oplog.h"
#include "mongo/db/repl/oplog_entry.h"
#include "mongo/db/repl/optime.h"
-#include "mongo/db/repl/repl_client_info.h"
#include "mongo/db/server_transactions_metrics.h"
#include "mongo/db/service_context.h"
#include "mongo/db/session_catalog_mongod.h"
@@ -632,21 +631,6 @@ TEST_F(TxnParticipantTest,
ErrorCodes::InvalidOptions);
}
-TEST_F(TxnParticipantTest,
- CommitTransactionWithCommitTimestampEqualToPrepareTimestampFailsOnPreparedTransaction) {
- auto sessionCheckout = checkOutSession();
- auto txnParticipant = TransactionParticipant::get(opCtx());
-
- txnParticipant.unstashTransactionResources(opCtx(), "commitTransaction");
-
- // The transaction machinery cannot store an empty locker.
- Lock::GlobalLock lk(opCtx(), MODE_IX, Date_t::now(), Lock::InterruptBehavior::kThrow);
- auto prepareTimestamp = txnParticipant.prepareTransaction(opCtx(), {});
- ASSERT_THROWS_CODE(txnParticipant.commitPreparedTransaction(opCtx(), prepareTimestamp, {}),
- AssertionException,
- ErrorCodes::InvalidOptions);
-}
-
// This test makes sure the abort machinery works even when no operations are done on the
// transaction.
TEST_F(TxnParticipantTest, EmptyTransactionAbort) {
@@ -745,7 +729,6 @@ TEST_F(TxnParticipantTest, StepDownAfterPrepareDoesNotBlockThenCommit) {
txnParticipant.unstashTransactionResources(opCtx(), "prepareTransaction");
const auto prepareTimestamp = txnParticipant.prepareTransaction(opCtx(), {});
- const auto commitTS = Timestamp(prepareTimestamp.getSecs(), prepareTimestamp.getInc() + 1);
// Test that we can acquire the RSTL in mode X, and then immediately release it so the test can
// complete successfully.
@@ -755,7 +738,7 @@ TEST_F(TxnParticipantTest, StepDownAfterPrepareDoesNotBlockThenCommit) {
};
runFunctionFromDifferentOpCtx(func);
- txnParticipant.commitPreparedTransaction(opCtx(), commitTS, {});
+ txnParticipant.commitPreparedTransaction(opCtx(), prepareTimestamp, {});
ASSERT(_opObserver->preparedTransactionCommitted);
ASSERT(txnParticipant.transactionIsCommitted());
}
@@ -1024,9 +1007,9 @@ DEATH_TEST_F(TxnParticipantTest,
txnParticipant.unstashTransactionResources(opCtx(), "insert");
auto operation = repl::OplogEntry::makeInsertOperation(kNss, kUUID, BSON("TestValue" << 0));
+
txnParticipant.addTransactionOperation(opCtx(), operation);
auto prepareTimestamp = txnParticipant.prepareTransaction(opCtx(), {});
- auto commitTS = Timestamp(prepareTimestamp.getSecs(), prepareTimestamp.getInc() + 1);
// Check that the oldest prepareTimestamp is the one we just set.
auto prepareOpTime = ServerTransactionsMetrics::get(opCtx())->getOldestActiveOpTime();
@@ -1041,9 +1024,10 @@ DEATH_TEST_F(TxnParticipantTest,
ASSERT_FALSE(txnParticipant.transactionIsAborted());
};
- txnParticipant.commitPreparedTransaction(opCtx(), commitTS, {});
+ txnParticipant.commitPreparedTransaction(opCtx(), prepareTimestamp, {});
// Check that we removed the prepareTimestamp from the set.
- ASSERT_FALSE(ServerTransactionsMetrics::get(opCtx())->getOldestActiveOpTime());
+ auto oldestActiveTS = ServerTransactionsMetrics::get(opCtx())->getOldestActiveOpTime();
+ ASSERT_FALSE(oldestActiveTS);
}
TEST_F(TxnParticipantTest, CannotContinueNonExistentTransaction) {
@@ -1462,15 +1446,14 @@ TEST_F(TransactionsMetricsTest, IncrementTotalCommittedOnCommit) {
TEST_F(TransactionsMetricsTest, IncrementTotalPreparedThenCommitted) {
auto sessionCheckout = checkOutSession();
auto txnParticipant = TransactionParticipant::get(opCtx());
+
txnParticipant.unstashTransactionResources(opCtx(), "commitTransaction");
const auto prepareTimestamp = txnParticipant.prepareTransaction(opCtx(), {});
- const auto commitTimestamp =
- Timestamp(prepareTimestamp.getSecs(), prepareTimestamp.getInc() + 1);
unsigned long long beforePreparedThenCommittedCount =
ServerTransactionsMetrics::get(opCtx())->getTotalPreparedThenCommitted();
- txnParticipant.commitPreparedTransaction(opCtx(), commitTimestamp, {});
+ txnParticipant.commitPreparedTransaction(opCtx(), prepareTimestamp, {});
ASSERT_TRUE(txnParticipant.transactionIsCommitted());
ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getTotalPreparedThenCommitted(),
@@ -1513,14 +1496,13 @@ TEST_F(TransactionsMetricsTest, IncrementCurrentPreparedWithCommit) {
auto sessionCheckout = checkOutSession();
auto txnParticipant = TransactionParticipant::get(opCtx());
+
txnParticipant.unstashTransactionResources(opCtx(), "commitTransaction");
const auto prepareTimestamp = txnParticipant.prepareTransaction(opCtx(), {});
- const auto commitTimestamp =
- Timestamp(prepareTimestamp.getSecs(), prepareTimestamp.getInc() + 1);
ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentPrepared(),
beforeCurrentPrepared + 1U);
- txnParticipant.commitPreparedTransaction(opCtx(), commitTimestamp, {});
+ txnParticipant.commitPreparedTransaction(opCtx(), prepareTimestamp, {});
ASSERT(txnParticipant.transactionIsCommitted());
ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentPrepared(), beforeCurrentPrepared);
}
@@ -1698,10 +1680,9 @@ TEST_F(TransactionsMetricsTest, TrackCurrentActiveAndInactivePreparedTransaction
// Tests that unstashing a transaction puts it into an active state.
auto txnParticipant = TransactionParticipant::get(opCtx());
+
txnParticipant.unstashTransactionResources(opCtx(), "prepareTransaction");
const auto prepareTimestamp = txnParticipant.prepareTransaction(opCtx(), {});
- const auto commitTimestamp =
- Timestamp(prepareTimestamp.getSecs(), prepareTimestamp.getInc() + 1);
ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentActive(),
beforeActivePreparedCounter + 1U);
@@ -1724,7 +1705,8 @@ TEST_F(TransactionsMetricsTest, TrackCurrentActiveAndInactivePreparedTransaction
beforeInactivePreparedCounter);
// Tests that committing decrements the active counter only.
- txnParticipant.commitPreparedTransaction(opCtx(), commitTimestamp, {});
+ txnParticipant.commitPreparedTransaction(opCtx(), prepareTimestamp, {});
+
ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentActive(),
beforeActivePreparedCounter);
ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentInactive(),
@@ -1841,12 +1823,10 @@ TEST_F(TransactionsMetricsTest, SingleTransactionStatsPreparedDurationShouldBeSe
// Prepare the transaction and extend the duration in the prepared state.
const auto prepareTimestamp = txnParticipant.prepareTransaction(opCtx(), {});
- const auto commitTimestamp =
- Timestamp(prepareTimestamp.getSecs(), prepareTimestamp.getInc() + 1);
tickSource->advance(Microseconds(100));
- txnParticipant.commitPreparedTransaction(opCtx(), commitTimestamp, {});
+ txnParticipant.commitPreparedTransaction(opCtx(), prepareTimestamp, {});
ASSERT_EQ(txnParticipant.getSingleTransactionStatsForTest().getPreparedDuration(
tickSource, tickSource->getTicks()),
Microseconds(100));
@@ -1931,9 +1911,6 @@ TEST_F(TransactionsMetricsTest,
// Prepare the transaction and extend the duration in the prepared state.
const auto prepareTimestamp = txnParticipant.prepareTransaction(opCtx(), {});
- const auto commitTimestamp =
- Timestamp(prepareTimestamp.getSecs(), prepareTimestamp.getInc() + 1);
-
tickSource->advance(Microseconds(100));
// The prepared transaction's duration should have increased.
@@ -1944,7 +1921,7 @@ TEST_F(TransactionsMetricsTest,
tickSource->advance(Microseconds(100));
// Commit the prepared transaction and check the prepared duration.
- txnParticipant.commitPreparedTransaction(opCtx(), commitTimestamp, {});
+ txnParticipant.commitPreparedTransaction(opCtx(), prepareTimestamp, {});
ASSERT_EQ(txnParticipant.getSingleTransactionStatsForTest().getPreparedDuration(
tickSource, tickSource->getTicks()),
Microseconds(200));
@@ -2457,9 +2434,6 @@ TEST_F(TransactionsMetricsTest, ReportStashedResources) {
// Prepare the transaction and extend the duration in the prepared state.
const auto prepareTimestamp = txnParticipant.prepareTransaction(opCtx(), {});
- const auto commitTimestamp =
- Timestamp(prepareTimestamp.getSecs(), prepareTimestamp.getInc() + 1);
-
const long preparedDuration = 10;
tickSource->advance(Microseconds(preparedDuration));
@@ -2516,7 +2490,7 @@ TEST_F(TransactionsMetricsTest, ReportStashedResources) {
ASSERT(txnParticipant.reportStashedState(opCtx()).isEmpty());
// Commit the transaction. This allows us to release locks.
- txnParticipant.commitPreparedTransaction(opCtx(), commitTimestamp, {});
+ txnParticipant.commitPreparedTransaction(opCtx(), prepareTimestamp, {});
}
TEST_F(TransactionsMetricsTest, ReportUnstashedResources) {
@@ -2851,7 +2825,7 @@ std::string buildTransactionInfoString(
// timeInactiveMicros:2 numYields:0 locks:{ Global: { acquireCount: { r: 6, w: 4 } }, Database:
// { acquireCount: { r: 1, w: 1, W: 2 } }, Collection: { acquireCount: { R: 1 } }, oplog: {
// acquireCount: { W: 1 } } } wasPrepared:1 totalPreparedDurationMicros:10
- // prepareOpTime:<OpTime> oldestOplogEntryOpTime:<OpTime> finishOpTime:<OpTime> 0ms
+ // prepareOpTime:<OpTime> oldestOplogEntryOpTime:<OpTime> 0ms
StringBuilder expectedTransactionInfo;
expectedTransactionInfo << parametersInfo.str() << readTimestampInfo.str()
<< singleTransactionStatsInfo.str()
@@ -2877,10 +2851,6 @@ std::string buildTransactionInfoString(
ASSERT(!txnParticipant.getOldestOplogEntryOpTimeForTest());
expectedTransactionInfo << " oldestOplogEntryOpTime:" << oldestOplogEntryOpTime->toString();
}
- if (txnParticipant.getFinishOpTimeForTest()) {
- expectedTransactionInfo << " finishOpTime:"
- << txnParticipant.getFinishOpTimeForTest()->toString();
- }
expectedTransactionInfo << ", "
<< duration_cast<Milliseconds>(
txnParticipant.getSingleTransactionStatsForTest().getDuration(
@@ -2948,12 +2918,10 @@ TEST_F(TransactionsMetricsTest, TestPreparedTransactionInfoForLogAfterCommit) {
auto txnParticipant = TransactionParticipant::get(opCtx());
txnParticipant.unstashTransactionResources(opCtx(), "commitTransaction");
const auto prepareTimestamp = txnParticipant.prepareTransaction(opCtx(), {});
- const auto commitTimestamp =
- Timestamp(prepareTimestamp.getSecs(), prepareTimestamp.getInc() + 1);
tickSource->advance(Microseconds(10));
- txnParticipant.commitPreparedTransaction(opCtx(), commitTimestamp, {});
+ txnParticipant.commitPreparedTransaction(opCtx(), prepareTimestamp, {});
const auto lockerInfo = opCtx()->lockState()->getLockerInfo(boost::none);
ASSERT(lockerInfo);
@@ -3139,11 +3107,9 @@ TEST_F(TransactionsMetricsTest, LogPreparedTransactionInfoAfterSlowCommit) {
txnParticipant.unstashTransactionResources(opCtx(), "commitTransaction");
const auto prepareTimestamp = txnParticipant.prepareTransaction(opCtx(), {});
- const auto commitTimestamp =
- Timestamp(prepareTimestamp.getSecs(), prepareTimestamp.getInc() + 1);
startCapturingLogMessages();
- txnParticipant.commitPreparedTransaction(opCtx(), commitTimestamp, {});
+ txnParticipant.commitPreparedTransaction(opCtx(), prepareTimestamp, {});
stopCapturingLogMessages();
const auto lockerInfo = opCtx()->lockState()->getLockerInfo(boost::none);
@@ -3460,128 +3426,6 @@ TEST_F(TxnParticipantTest, ReturnNullTimestampIfNoOldestActiveTimestamp) {
ASSERT_FALSE(ServerTransactionsMetrics::get(opCtx())->getOldestActiveOpTime());
}
-TEST_F(TxnParticipantTest, ProperlyMaintainOldestNonMajorityCommittedOpTimeSet) {
- auto sessionCheckout = checkOutSession();
- auto txnParticipant = TransactionParticipant::get(opCtx());
-
- // Check that there are no Timestamps in the set.
- ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getTotalActiveOpTimes(), 0U);
-
- txnParticipant.unstashTransactionResources(opCtx(), "prepareTransaction");
- auto prepareTimestamp = txnParticipant.prepareTransaction(opCtx(), {});
- // Check that we added a Timestamp to the set.
- ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getTotalActiveOpTimes(), 1U);
-
- // Check that the oldest prepareTimestamp is equal to first prepareTimestamp because there is
- // only one prepared transaction on this Service.
- auto prepareOpTime = ServerTransactionsMetrics::get(opCtx())->getOldestActiveOpTime();
- ASSERT_EQ(prepareOpTime->getTimestamp(), prepareTimestamp);
-
- // Check that oldestNonMajorityCommittedOpTimes also has this prepareTimestamp and that the
- // pair's finishOpTime is Timestamp::max() because this transaction has not been
- // committed/aborted.
- auto nonMajorityCommittedOpTime =
- ServerTransactionsMetrics::get(opCtx())->getOldestNonMajorityCommittedOpTime();
- ASSERT_EQ(nonMajorityCommittedOpTime->getTimestamp(), prepareTimestamp);
- auto nonMajorityCommittedOpTimeFinishOpTime =
- ServerTransactionsMetrics::get(opCtx())->getFinishOpTimeOfOldestNonMajCommitted_forTest();
- ASSERT_EQ(nonMajorityCommittedOpTimeFinishOpTime->getTimestamp(), Timestamp::max());
-
- ASSERT_FALSE(txnParticipant.transactionIsAborted());
- // Since this test uses a mock opObserver, we have to manually set the finishTimestamp on the
- // txnParticipant.
- auto finishOpTime = repl::OpTime({10, 10}, 0);
- repl::ReplClientInfo::forClient(opCtx()->getClient()).setLastOp(finishOpTime);
-
- txnParticipant.abortActiveTransaction(opCtx());
- ASSERT(txnParticipant.transactionIsAborted());
-
- // Make sure that we moved the OpTime from the oldestActiveOplogEntryOpTimes to
- // oldestNonMajorityCommittedOpTimes along with the abort/commit oplog entry OpTime
- // associated with the transaction.
- ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getTotalActiveOpTimes(), 0U);
- ASSERT_FALSE(ServerTransactionsMetrics::get(opCtx())->getOldestActiveOpTime());
-
- nonMajorityCommittedOpTime =
- ServerTransactionsMetrics::get(opCtx())->getOldestNonMajorityCommittedOpTime();
- nonMajorityCommittedOpTimeFinishOpTime =
- ServerTransactionsMetrics::get(opCtx())->getFinishOpTimeOfOldestNonMajCommitted_forTest();
- ASSERT_FALSE(nonMajorityCommittedOpTime == boost::none);
- ASSERT_FALSE(nonMajorityCommittedOpTimeFinishOpTime == boost::none);
- ASSERT_EQ(nonMajorityCommittedOpTime->getTimestamp(), prepareTimestamp);
- ASSERT(nonMajorityCommittedOpTimeFinishOpTime);
- ASSERT_EQ(*nonMajorityCommittedOpTimeFinishOpTime, finishOpTime);
-
- // If we pass in a mock commit point that is greater than the finish timestamp of the
- // oldestNonMajorityCommittedOpTime, it should be removed from the set. This would mean that
- // the abort/commit oplog entry is majority committed.
- ServerTransactionsMetrics::get(opCtx())->removeOpTimesLessThanOrEqToCommittedOpTime(
- repl::OpTime::max());
- nonMajorityCommittedOpTime =
- ServerTransactionsMetrics::get(opCtx())->getOldestNonMajorityCommittedOpTime();
- ASSERT_FALSE(nonMajorityCommittedOpTime);
-}
-
-TEST_F(TxnParticipantTest, GetOldestNonMajorityCommittedOpTimeReturnsOldestEntry) {
- const auto earlierOpTime = repl::OpTime({1, 1}, 0);
- const auto earlierFinishOpTime = repl::OpTime({3, 2}, 0);
-
- const auto middleOpTime = repl::OpTime({1, 2}, 0);
- const auto middleFinishOpTime = repl::OpTime({3, 3}, 0);
-
- const auto laterOpTime = repl::OpTime({1, 3}, 0);
- const auto laterFinishOpTime = repl::OpTime({3, 4}, 0);
-
- ServerTransactionsMetrics::get(opCtx())->addActiveOpTime(earlierOpTime);
- ServerTransactionsMetrics::get(opCtx())->removeActiveOpTime(earlierOpTime, earlierFinishOpTime);
-
- ServerTransactionsMetrics::get(opCtx())->addActiveOpTime(middleOpTime);
- ServerTransactionsMetrics::get(opCtx())->removeActiveOpTime(middleOpTime, middleFinishOpTime);
-
- ServerTransactionsMetrics::get(opCtx())->addActiveOpTime(laterOpTime);
- ServerTransactionsMetrics::get(opCtx())->removeActiveOpTime(laterOpTime, laterFinishOpTime);
-
- auto nonMajorityCommittedOpTime =
- ServerTransactionsMetrics::get(opCtx())->getOldestNonMajorityCommittedOpTime();
-
- ASSERT_EQ(*nonMajorityCommittedOpTime, repl::OpTime({1, 1}, 0));
-
- // If we pass in a mock commit point that is greater than the finish timestamp of the
- // oldestNonMajorityCommittedOpTime, it should be removed from the set. This would mean that
- // the abort/commit oplog entry is majority committed.
- ServerTransactionsMetrics::get(opCtx())->removeOpTimesLessThanOrEqToCommittedOpTime(
- repl::OpTime::max());
- nonMajorityCommittedOpTime =
- ServerTransactionsMetrics::get(opCtx())->getOldestNonMajorityCommittedOpTime();
- ASSERT_FALSE(nonMajorityCommittedOpTime);
-
- // Test that we can remove only a part of the set by passing in a commit point that is only
- // greater than or equal to two of the optimes.
- ServerTransactionsMetrics::get(opCtx())->addActiveOpTime(earlierOpTime);
- ServerTransactionsMetrics::get(opCtx())->removeActiveOpTime(earlierOpTime, earlierFinishOpTime);
-
- ServerTransactionsMetrics::get(opCtx())->addActiveOpTime(middleOpTime);
- ServerTransactionsMetrics::get(opCtx())->removeActiveOpTime(middleOpTime, middleFinishOpTime);
-
- ServerTransactionsMetrics::get(opCtx())->addActiveOpTime(laterOpTime);
- ServerTransactionsMetrics::get(opCtx())->removeActiveOpTime(laterOpTime, laterFinishOpTime);
-
- nonMajorityCommittedOpTime =
- ServerTransactionsMetrics::get(opCtx())->getOldestNonMajorityCommittedOpTime();
-
- ASSERT_EQ(*nonMajorityCommittedOpTime, earlierOpTime);
-
- ServerTransactionsMetrics::get(opCtx())->removeOpTimesLessThanOrEqToCommittedOpTime(
- repl::OpTime({3, 3}, 0));
- nonMajorityCommittedOpTime =
- ServerTransactionsMetrics::get(opCtx())->getOldestNonMajorityCommittedOpTime();
-
- // earlierOpTime and middleOpTime must have been removed because their finishOpTime are less
- // than or equal to the mock commit point.
- ASSERT(nonMajorityCommittedOpTime);
- ASSERT_EQ(*nonMajorityCommittedOpTime, laterOpTime);
-}
-
TEST_F(TxnParticipantTest, RollbackResetsInMemoryStateOfPreparedTransaction) {
auto sessionCheckout = checkOutSession();
@@ -3598,7 +3442,6 @@ TEST_F(TxnParticipantTest, RollbackResetsInMemoryStateOfPreparedTransaction) {
// Check that our metrics are initialized to their default values.
ASSERT_FALSE(ServerTransactionsMetrics::get(opCtx())->getOldestActiveOpTime());
ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getTotalActiveOpTimes(), 0U);
- ASSERT_FALSE(ServerTransactionsMetrics::get(opCtx())->getOldestNonMajorityCommittedOpTime());
// Perform an insert as a part of a transaction so that we have a transaction operation.
txnParticipant.unstashTransactionResources(opCtx(), "insert");
@@ -3612,13 +3455,10 @@ TEST_F(TxnParticipantTest, RollbackResetsInMemoryStateOfPreparedTransaction) {
// Check that we added a Timestamp to oldestActiveOplogEntryOpTimes.
ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getTotalActiveOpTimes(), 1U);
- // Check that the oldest active timestamp and the oldest non majority committed timestamp are
- // equal to the prepareTimestamp because there is only one prepared transaction.
- auto oldestActiveOpTime = ServerTransactionsMetrics::get(opCtx())->getOldestActiveOpTime();
- auto oldestNonMajorityCommittedOpTime =
- ServerTransactionsMetrics::get(opCtx())->getOldestNonMajorityCommittedOpTime();
- ASSERT_EQ(oldestActiveOpTime->getTimestamp(), prepareTimestamp);
- ASSERT_EQ(oldestNonMajorityCommittedOpTime->getTimestamp(), prepareTimestamp);
+ // Check that the oldest active timestamp is equal to the prepareTimestamp because there is
+ // only one prepared transaction.
+ auto prepareOpTime = ServerTransactionsMetrics::get(opCtx())->getOldestActiveOpTime();
+ ASSERT_EQ(prepareOpTime->getTimestamp(), prepareTimestamp);
ASSERT_FALSE(txnParticipant.transactionIsAborted());
// Make sure the state of txnParticipant is populated correctly after a prepared transaction.
@@ -3639,7 +3479,6 @@ TEST_F(TxnParticipantTest, RollbackResetsInMemoryStateOfPreparedTransaction) {
// After calling clearOpTimes, we should no longer have an oldestActiveOpTime.
ASSERT_FALSE(ServerTransactionsMetrics::get(opCtx())->getOldestActiveOpTime());
- ASSERT_FALSE(ServerTransactionsMetrics::get(opCtx())->getOldestNonMajorityCommittedOpTime());
ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getTotalActiveOpTimes(), 0U);
}
@@ -3683,7 +3522,6 @@ TEST_F(TxnParticipantTest, CommitPreparedTransactionAsSecondarySetsTheFinishOpTi
Timestamp(prepareTimestamp.getSecs(), prepareTimestamp.getInc() + 1);
const auto commitOplogEntryOpTime = repl::OpTime({10, 10}, 0);
txnParticipant.commitPreparedTransaction(opCtx(), commitTimestamp, commitOplogEntryOpTime);
- ASSERT_EQ(txnParticipant.getFinishOpTimeForTest().get(), commitOplogEntryOpTime);
ASSERT_TRUE(txnParticipant.transactionIsCommitted());
}