summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavi Vetriselvan <pvselvan@umich.edu>2018-11-06 10:34:19 -0500
committerPavi Vetriselvan <pvselvan@umich.edu>2018-11-06 13:42:56 -0500
commit2de26d2c3c7f73cc49126ba32402c0a380c8f882 (patch)
tree6ab2392b6a973f75d571663e2fc13f3f3ff12c5d
parent1f40ed56b27d9c98c23eb601d6b06116b194dfe7 (diff)
downloadmongo-2de26d2c3c7f73cc49126ba32402c0a380c8f882.tar.gz
SERVER-35811 disallow committing at the prepareTimestamp
-rw-r--r--jstests/core/txns/commit_prepared_transaction.js6
-rw-r--r--jstests/core/txns/disallow_operations_on_prepared_transaction.js2
-rw-r--r--jstests/core/txns/libs/prepare_helpers.js20
-rw-r--r--jstests/core/txns/prepare_requires_fcv42.js5
-rw-r--r--jstests/core/txns/timestamped_reads_wait_for_prepare_oplog_visibility.js2
-rw-r--r--jstests/noPassthrough/server_transaction_metrics_for_prepared_transactions.js2
-rw-r--r--jstests/replsets/commit_transaction_recovery.js4
-rw-r--r--jstests/replsets/commit_transaction_recovery_data_already_applied.js2
-rw-r--r--src/mongo/db/transaction_participant.cpp4
-rw-r--r--src/mongo/db/transaction_participant_test.cpp90
10 files changed, 100 insertions, 37 deletions
diff --git a/jstests/core/txns/commit_prepared_transaction.js b/jstests/core/txns/commit_prepared_transaction.js
index c14c9c607bf..79de318d901 100644
--- a/jstests/core/txns/commit_prepared_transaction.js
+++ b/jstests/core/txns/commit_prepared_transaction.js
@@ -33,7 +33,7 @@
assert.eq(doc1, sessionColl.findOne(doc1));
let prepareTimestamp = PrepareHelpers.prepareTransaction(session);
- assert.commandWorked(PrepareHelpers.commitTransaction(session, prepareTimestamp));
+ assert.commandWorked(PrepareHelpers.commitTransactionAfterPrepareTS(session, prepareTimestamp));
// After commit the insert persists.
assert.eq(doc1, testColl.findOne(doc1));
@@ -52,7 +52,7 @@
assert.eq(doc2, sessionColl.findOne(doc2));
prepareTimestamp = PrepareHelpers.prepareTransaction(session);
- assert.commandWorked(PrepareHelpers.commitTransaction(session, prepareTimestamp));
+ assert.commandWorked(PrepareHelpers.commitTransactionAfterPrepareTS(session, prepareTimestamp));
// After commit the update persists.
assert.eq(doc2, testColl.findOne({_id: 1}));
@@ -69,7 +69,7 @@
assert.eq(null, sessionColl.findOne(doc2));
prepareTimestamp = PrepareHelpers.prepareTransaction(session);
- assert.commandWorked(PrepareHelpers.commitTransaction(session, prepareTimestamp));
+ assert.commandWorked(PrepareHelpers.commitTransactionAfterPrepareTS(session, prepareTimestamp));
// After commit the delete persists.
assert.eq(null, testColl.findOne(doc2));
diff --git a/jstests/core/txns/disallow_operations_on_prepared_transaction.js b/jstests/core/txns/disallow_operations_on_prepared_transaction.js
index cde9ed7ce8d..4e6c879b995 100644
--- a/jstests/core/txns/disallow_operations_on_prepared_transaction.js
+++ b/jstests/core/txns/disallow_operations_on_prepared_transaction.js
@@ -34,7 +34,7 @@
session.startTransaction();
assert.commandWorked(sessionColl.insert({_id: 2}));
let prepareTimestamp = PrepareHelpers.prepareTransaction(session);
- assert.commandWorked(PrepareHelpers.commitTransaction(session, prepareTimestamp));
+ assert.commandWorked(PrepareHelpers.commitTransactionAfterPrepareTS(session, prepareTimestamp));
jsTestLog("Test that you can call abortTransaction on a prepared transaction.");
session.startTransaction();
diff --git a/jstests/core/txns/libs/prepare_helpers.js b/jstests/core/txns/libs/prepare_helpers.js
index 37217d04245..6dbfeb66936 100644
--- a/jstests/core/txns/libs/prepare_helpers.js
+++ b/jstests/core/txns/libs/prepare_helpers.js
@@ -47,8 +47,28 @@ const PrepareHelpers = (function() {
return res;
}
+ /**
+ * Commits the active transaction on the session at a commitTimestamp that is greater than
+ * the transaction's prepareTimestamp.
+ *
+ * This is a temporary function that should be used to commit prepared transactions
+ * until we allow the stable timestamp to move past the oldest active prepare timestamp.
+ *
+ * @return {object} the response to the 'commitTransaction' command.
+ */
+ function commitTransactionAfterPrepareTS(session, prepareTimestamp) {
+ assert(session);
+
+ // Add 1 to the increment so that the commitTimestamp is "after" the prepareTimestamp.
+ const commitTimestamp =
+ Timestamp(prepareTimestamp.getTime(), prepareTimestamp.getInc() + 1);
+
+ return this.commitTransaction(session, commitTimestamp);
+ }
+
return {
prepareTransaction: prepareTransaction,
commitTransaction: commitTransaction,
+ commitTransactionAfterPrepareTS: commitTransactionAfterPrepareTS,
};
})();
diff --git a/jstests/core/txns/prepare_requires_fcv42.js b/jstests/core/txns/prepare_requires_fcv42.js
index 43db290ed83..bfd87e5c79a 100644
--- a/jstests/core/txns/prepare_requires_fcv42.js
+++ b/jstests/core/txns/prepare_requires_fcv42.js
@@ -26,7 +26,8 @@
session.startTransaction();
assert.commandWorked(sessionDB[collName].insert({_id: "a"}));
let prepareTimestamp = PrepareHelpers.prepareTransaction(session);
- assert.commandWorked(PrepareHelpers.commitTransaction(session, prepareTimestamp));
+ assert.commandWorked(
+ PrepareHelpers.commitTransactionAfterPrepareTS(session, prepareTimestamp));
jsTestLog("Downgrade the featureCompatibilityVersion.");
assert.commandWorked(testDB.adminCommand({setFeatureCompatibilityVersion: lastStableFCV}));
@@ -51,7 +52,7 @@
session.startTransaction();
assert.commandWorked(sessionDB[collName].insert({_id: "c"}));
let prepareTimestamp = PrepareHelpers.prepareTransaction(session);
- assert.commandWorked(PrepareHelpers.commitTransaction(session, prepareTimestamp));
+ assert.commandWorked(PrepareHelpers.commitTransactionAfterPrepareTS(session, prepareTimestamp));
session.endSession();
}());
diff --git a/jstests/core/txns/timestamped_reads_wait_for_prepare_oplog_visibility.js b/jstests/core/txns/timestamped_reads_wait_for_prepare_oplog_visibility.js
index 2cc6b26deb0..23513e5e2a5 100644
--- a/jstests/core/txns/timestamped_reads_wait_for_prepare_oplog_visibility.js
+++ b/jstests/core/txns/timestamped_reads_wait_for_prepare_oplog_visibility.js
@@ -83,7 +83,7 @@
db.setLogLevel(0);
joinReadThread({checkExitSuccess: true});
- PrepareHelpers.commitTransaction(session, prepareTimestamp);
+ PrepareHelpers.commitTransactionAfterPrepareTS(session, prepareTimestamp);
}
const snapshotRead = function(_collName) {
diff --git a/jstests/noPassthrough/server_transaction_metrics_for_prepared_transactions.js b/jstests/noPassthrough/server_transaction_metrics_for_prepared_transactions.js
index 0e22ea56fa2..3f6af833208 100644
--- a/jstests/noPassthrough/server_transaction_metrics_for_prepared_transactions.js
+++ b/jstests/noPassthrough/server_transaction_metrics_for_prepared_transactions.js
@@ -84,7 +84,7 @@
// Verify the total prepared and committed transaction counters are updated after a commit
// and that the current prepared counter is decremented.
- PrepareHelpers.commitTransaction(session, prepareTimestampForCommit);
+ PrepareHelpers.commitTransactionAfterPrepareTS(session, prepareTimestampForCommit);
newStatus = assert.commandWorked(testDB.adminCommand({serverStatus: 1}));
verifyServerStatusFields(newStatus);
verifyServerStatusChange(
diff --git a/jstests/replsets/commit_transaction_recovery.js b/jstests/replsets/commit_transaction_recovery.js
index 00b163b8dcc..2e0ec6befe8 100644
--- a/jstests/replsets/commit_transaction_recovery.js
+++ b/jstests/replsets/commit_transaction_recovery.js
@@ -42,7 +42,7 @@
// Since the commitTimestamp is after the last snapshot, this oplog entry will be replayed
// during replication recovery during restart.
- assert.commandWorked(PrepareHelpers.commitTransaction(session, prepareTimestamp));
+ assert.commandWorked(PrepareHelpers.commitTransactionAfterPrepareTS(session, prepareTimestamp));
jsTestLog("Restarting node");
@@ -66,7 +66,7 @@
// Also, make sure that we can run another transaction after recovery without any problems.
assert.commandWorked(sessionDB[collName].update({_id: 1}, {_id: 1, a: 1}));
prepareTimestamp = PrepareHelpers.prepareTransaction(session);
- assert.commandWorked(PrepareHelpers.commitTransaction(session, prepareTimestamp));
+ assert.commandWorked(PrepareHelpers.commitTransactionAfterPrepareTS(session, prepareTimestamp));
assert.eq(testDB[collName].findOne({_id: 1}), {_id: 1, a: 1});
replTest.stopSet();
diff --git a/jstests/replsets/commit_transaction_recovery_data_already_applied.js b/jstests/replsets/commit_transaction_recovery_data_already_applied.js
index 5ca3326dd38..75ec7204383 100644
--- a/jstests/replsets/commit_transaction_recovery_data_already_applied.js
+++ b/jstests/replsets/commit_transaction_recovery_data_already_applied.js
@@ -87,7 +87,7 @@
// Also, make sure that we can run another transaction after recovery without any problems.
assert.commandWorked(sessionDB[collName].update({_id: 1}, {_id: 1, a: 1}));
prepareTimestamp = PrepareHelpers.prepareTransaction(session);
- assert.commandWorked(PrepareHelpers.commitTransaction(session, prepareTimestamp));
+ assert.commandWorked(PrepareHelpers.commitTransactionAfterPrepareTS(session, prepareTimestamp));
assert.eq(testDB[collName].findOne({_id: 1}), {_id: 1, a: 1});
replTest.stopSet();
diff --git a/src/mongo/db/transaction_participant.cpp b/src/mongo/db/transaction_participant.cpp
index b06cb225bda..49fd7b4973c 100644
--- a/src/mongo/db/transaction_participant.cpp
+++ b/src/mongo/db/transaction_participant.cpp
@@ -938,8 +938,8 @@ void TransactionParticipant::commitPreparedTransaction(OperationContext* opCtx,
uassert(
ErrorCodes::InvalidOptions, "'commitTimestamp' cannot be null", !commitTimestamp.isNull());
uassert(ErrorCodes::InvalidOptions,
- "'commitTimestamp' must be greater than or equal to 'prepareTimestamp'",
- commitTimestamp >= _prepareOpTime.getTimestamp());
+ "'commitTimestamp' must be greater than the 'prepareTimestamp'",
+ commitTimestamp > _prepareOpTime.getTimestamp());
_txnState.transitionTo(lk, TransactionState::kCommittingWithPrepare);
opCtx->recoveryUnit()->setCommitTimestamp(commitTimestamp);
diff --git a/src/mongo/db/transaction_participant_test.cpp b/src/mongo/db/transaction_participant_test.cpp
index 15aead0e7fd..69404e1593d 100644
--- a/src/mongo/db/transaction_participant_test.cpp
+++ b/src/mongo/db/transaction_participant_test.cpp
@@ -498,7 +498,8 @@ TEST_F(TxnParticipantTest, CommitTransactionSetsCommitTimestampOnPreparedTransac
// The transaction machinery cannot store an empty locker.
Lock::GlobalLock lk(opCtx(), MODE_IX, Date_t::now(), Lock::InterruptBehavior::kThrow);
- const auto userCommitTimestamp = txnParticipant->prepareTransaction(opCtx(), {});
+ const auto prepareTimestamp = txnParticipant->prepareTransaction(opCtx(), {});
+ const auto commitTS = Timestamp(prepareTimestamp.getSecs(), prepareTimestamp.getInc() + 1);
auto originalFn = _opObserver->onTransactionCommitFn;
_opObserver->onTransactionCommitFn = [&](boost::optional<OplogSlot> commitOplogEntryOpTime,
@@ -507,10 +508,10 @@ TEST_F(TxnParticipantTest, CommitTransactionSetsCommitTimestampOnPreparedTransac
ASSERT(commitOplogEntryOpTime);
ASSERT(commitTimestamp);
- ASSERT_EQ(userCommitTimestamp, commitTimestamp);
+ ASSERT_GT(commitTimestamp, prepareTimestamp);
};
- txnParticipant->commitPreparedTransaction(opCtx(), userCommitTimestamp);
+ txnParticipant->commitPreparedTransaction(opCtx(), commitTS);
// The recovery unit is reset on commit.
ASSERT(opCtx()->recoveryUnit()->getCommitTimestamp().isNull());
@@ -604,6 +605,21 @@ TEST_F(TxnParticipantTest,
ErrorCodes::InvalidOptions);
}
+TEST_F(TxnParticipantTest,
+ CommitTransactionWithCommitTimestampEqualToPrepareTimestampFailsOnPreparedTransaction) {
+ OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo());
+ 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) {
@@ -773,11 +789,12 @@ TEST_F(TxnParticipantTest, ConcurrencyOfCommitPreparedTransactionAndAbort) {
txnParticipant->unstashTransactionResources(opCtx(), "commitTransaction");
auto prepareTS = txnParticipant->prepareTransaction(opCtx(), {});
+ auto commitTS = Timestamp(prepareTS.getSecs(), prepareTS.getInc() + 1);
txnParticipant->abortArbitraryTransaction();
// A commitPreparedTransaction() after an abort should succeed since the abort should fail.
- txnParticipant->commitPreparedTransaction(opCtx(), prepareTS);
+ txnParticipant->commitPreparedTransaction(opCtx(), commitTS);
ASSERT(_opObserver->transactionCommitted);
ASSERT_FALSE(txnParticipant->transactionIsAborted());
@@ -926,7 +943,8 @@ TEST_F(TxnParticipantTest, KillSessionsDuringPreparedCommitDoesNotAbortTransacti
auto txnParticipant = TransactionParticipant::get(opCtx());
txnParticipant->unstashTransactionResources(opCtx(), "commitTransaction");
- const auto userCommitTimestamp = txnParticipant->prepareTransaction(opCtx(), {});
+ const auto prepareTimestamp = txnParticipant->prepareTransaction(opCtx(), {});
+ const auto commitTS = Timestamp(prepareTimestamp.getSecs(), prepareTimestamp.getInc() + 1);
auto originalFn = _opObserver->onTransactionCommitFn;
_opObserver->onTransactionCommitFn = [&](boost::optional<OplogSlot> commitOplogEntryOpTime,
@@ -935,14 +953,14 @@ TEST_F(TxnParticipantTest, KillSessionsDuringPreparedCommitDoesNotAbortTransacti
ASSERT(commitOplogEntryOpTime);
ASSERT(commitTimestamp);
- ASSERT_EQ(*commitTimestamp, userCommitTimestamp);
+ ASSERT_GT(*commitTimestamp, prepareTimestamp);
// The transaction may be aborted without checking out the txnParticipant.
txnParticipant->abortArbitraryTransaction();
ASSERT_FALSE(txnParticipant->transactionIsAborted());
};
- txnParticipant->commitPreparedTransaction(opCtx(), userCommitTimestamp);
+ txnParticipant->commitPreparedTransaction(opCtx(), commitTS);
// The recovery unit is reset on commit.
ASSERT(opCtx()->recoveryUnit()->getCommitTimestamp().isNull());
@@ -957,7 +975,8 @@ TEST_F(TxnParticipantTest, ArbitraryAbortDuringPreparedCommitDoesNotAbortTransac
auto txnParticipant = TransactionParticipant::get(opCtx());
txnParticipant->unstashTransactionResources(opCtx(), "commitTransaction");
- const auto userCommitTimestamp = txnParticipant->prepareTransaction(opCtx(), {});
+ const auto prepareTimestamp = txnParticipant->prepareTransaction(opCtx(), {});
+ const auto commitTS = Timestamp(prepareTimestamp.getSecs(), prepareTimestamp.getInc() + 1);
auto originalFn = _opObserver->onTransactionCommitFn;
_opObserver->onTransactionCommitFn = [&](boost::optional<OplogSlot> commitOplogEntryOpTime,
@@ -966,7 +985,7 @@ TEST_F(TxnParticipantTest, ArbitraryAbortDuringPreparedCommitDoesNotAbortTransac
ASSERT(commitOplogEntryOpTime);
ASSERT(commitTimestamp);
- ASSERT_EQ(*commitTimestamp, userCommitTimestamp);
+ ASSERT_GT(*commitTimestamp, prepareTimestamp);
// The transaction may be aborted without checking out the txnParticipant.
auto func = [&](OperationContext* opCtx) { txnParticipant->abortArbitraryTransaction(); };
@@ -974,7 +993,7 @@ TEST_F(TxnParticipantTest, ArbitraryAbortDuringPreparedCommitDoesNotAbortTransac
ASSERT_FALSE(txnParticipant->transactionIsAborted());
};
- txnParticipant->commitPreparedTransaction(opCtx(), userCommitTimestamp);
+ txnParticipant->commitPreparedTransaction(opCtx(), commitTS);
// The recovery unit is reset on commit.
ASSERT(opCtx()->recoveryUnit()->getCommitTimestamp().isNull());
@@ -993,8 +1012,9 @@ DEATH_TEST_F(TxnParticipantTest,
_opObserver->onTransactionCommitThrowsException = true;
const auto prepareTimestamp = txnParticipant->prepareTransaction(opCtx(), {});
+ const auto commitTS = Timestamp(prepareTimestamp.getSecs(), prepareTimestamp.getInc() + 1);
- txnParticipant->commitPreparedTransaction(opCtx(), prepareTimestamp);
+ txnParticipant->commitPreparedTransaction(opCtx(), commitTS);
}
TEST_F(TxnParticipantTest, ThrowDuringUnpreparedCommitLetsTheAbortAtEntryPointToCleanUp) {
@@ -1227,6 +1247,7 @@ DEATH_TEST_F(TxnParticipantTest, AbortIsIllegalDuringCommittingPreparedTransacti
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();
@@ -1247,7 +1268,7 @@ DEATH_TEST_F(TxnParticipantTest, AbortIsIllegalDuringCommittingPreparedTransacti
ASSERT_FALSE(txnParticipant->transactionIsAborted());
};
- txnParticipant->commitPreparedTransaction(opCtx(), prepareTimestamp);
+ txnParticipant->commitPreparedTransaction(opCtx(), commitTS);
// Check that we removed the prepareTimestamp from the set.
ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getOldestActiveOpTime(), boost::none);
}
@@ -1712,11 +1733,13 @@ TEST_F(TransactionsMetricsTest, IncrementTotalPreparedThenCommitted) {
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(), prepareTimestamp);
+ txnParticipant->commitPreparedTransaction(opCtx(), commitTimestamp);
ASSERT_TRUE(txnParticipant->transactionIsCommitted());
ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getTotalPreparedThenCommitted(),
@@ -1761,10 +1784,12 @@ TEST_F(TransactionsMetricsTest, IncrementCurrentPreparedWithCommit) {
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(), prepareTimestamp);
+ txnParticipant->commitPreparedTransaction(opCtx(), commitTimestamp);
ASSERT(txnParticipant->transactionIsCommitted());
ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentPrepared(), beforeCurrentPrepared);
}
@@ -1944,6 +1969,9 @@ TEST_F(TransactionsMetricsTest, TrackCurrentActiveAndInactivePreparedTransaction
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);
ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentInactive(),
@@ -1965,7 +1993,7 @@ TEST_F(TransactionsMetricsTest, TrackCurrentActiveAndInactivePreparedTransaction
beforeInactivePreparedCounter);
// Tests that committing decrements the active counter only.
- txnParticipant->commitPreparedTransaction(opCtx(), prepareTimestamp);
+ txnParticipant->commitPreparedTransaction(opCtx(), commitTimestamp);
ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentActive(),
beforeActivePreparedCounter);
ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentInactive(),
@@ -2045,10 +2073,13 @@ TEST_F(TransactionsMetricsTest, SingleTranasactionStatsPreparedDurationShouldBeS
tickSource->advance(Microseconds(10));
// Prepare the transaction and extend the duration in the prepared state.
- const auto preparedTimestamp = txnParticipant->prepareTransaction(opCtx(), {});
+ const auto prepareTimestamp = txnParticipant->prepareTransaction(opCtx(), {});
+ const auto commitTimestamp =
+ Timestamp(prepareTimestamp.getSecs(), prepareTimestamp.getInc() + 1);
+
tickSource->advance(Microseconds(100));
- txnParticipant->commitPreparedTransaction(opCtx(), preparedTimestamp);
+ txnParticipant->commitPreparedTransaction(opCtx(), commitTimestamp);
ASSERT_EQ(txnParticipant->getSingleTransactionStats().getPreparedDuration(
tickSource, tickSource->getTicks()),
Microseconds(100));
@@ -2133,6 +2164,9 @@ 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.
@@ -2143,7 +2177,7 @@ TEST_F(TransactionsMetricsTest,
tickSource->advance(Microseconds(100));
// Commit the prepared transaction and check the prepared duration.
- txnParticipant->commitPreparedTransaction(opCtx(), prepareTimestamp);
+ txnParticipant->commitPreparedTransaction(opCtx(), commitTimestamp);
ASSERT_EQ(txnParticipant->getSingleTransactionStats().getPreparedDuration(
tickSource, tickSource->getTicks()),
Microseconds(200));
@@ -2686,6 +2720,8 @@ 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));
@@ -2742,7 +2778,7 @@ TEST_F(TransactionsMetricsTest, ReportStashedResources) {
ASSERT(txnParticipant->reportStashedState().isEmpty());
// Commit the transaction. This allows us to release locks.
- txnParticipant->commitPreparedTransaction(opCtx(), prepareTimestamp);
+ txnParticipant->commitPreparedTransaction(opCtx(), commitTimestamp);
}
TEST_F(TransactionsMetricsTest, ReportUnstashedResources) {
@@ -3142,9 +3178,12 @@ 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(), prepareTimestamp);
+ txnParticipant->commitPreparedTransaction(opCtx(), commitTimestamp);
const auto lockerInfo = opCtx()->lockState()->getLockerInfo(boost::none);
ASSERT(lockerInfo);
@@ -3325,9 +3364,12 @@ TEST_F(TransactionsMetricsTest, LogPreparedTransactionInfoAfterSlowCommit) {
tickSource->advance(Microseconds(11 * 1000));
txnParticipant->unstashTransactionResources(opCtx(), "commitTransaction");
- const auto preparedTimestamp = txnParticipant->prepareTransaction(opCtx(), {});
+ const auto prepareTimestamp = txnParticipant->prepareTransaction(opCtx(), {});
+ const auto commitTimestamp =
+ Timestamp(prepareTimestamp.getSecs(), prepareTimestamp.getInc() + 1);
+
startCapturingLogMessages();
- txnParticipant->commitPreparedTransaction(opCtx(), preparedTimestamp);
+ txnParticipant->commitPreparedTransaction(opCtx(), commitTimestamp);
stopCapturingLogMessages();
const auto lockerInfo = opCtx()->lockState()->getLockerInfo(boost::none);
@@ -3493,7 +3535,7 @@ TEST_F(TxnParticipantTest, WhenOldestTSRemovedNextOldestBecomesNewOldest) {
auto newTxnParticipant = TransactionParticipant::get(newOpCtx.get());
newTxnParticipant->unstashTransactionResources(newOpCtx.get(), "prepareTransaction");
- // secondPrepareTimestamp should be greater than firstPreparedTimestamp because this
+ // secondPrepareTimestamp should be greater than firstPrepareTimestamp because this
// transaction was prepared after.
secondPrepareTimestamp = newTxnParticipant->prepareTransaction(newOpCtx.get(), {});
ASSERT_GT(secondPrepareTimestamp, firstPrepareTimestamp);
@@ -3554,7 +3596,7 @@ TEST_F(TxnParticipantTest, ReturnNullTimestampIfNoOldestActiveTimestamp) {
auto newTxnParticipant = TransactionParticipant::get(newOpCtx.get());
newTxnParticipant->unstashTransactionResources(newOpCtx.get(), "prepareTransaction");
- // secondPrepareTimestamp should be greater than firstPreparedTimestamp because this
+ // secondPrepareTimestamp should be greater than firstPrepareTimestamp because this
// transaction was prepared after.
newTxnParticipant->prepareTransaction(newOpCtx.get(), {});
// Check that we added a Timestamp to the set.