summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJudah Schvimer <judah@mongodb.com>2018-05-08 14:53:49 -0400
committerJudah Schvimer <judah@mongodb.com>2018-05-15 13:59:11 -0400
commit689d52131f6ac1a446fe1b93647b11d0329c629c (patch)
tree42b715f59ee4b402ac12fad10c2e8ebc59fbe9ee /src
parent6d2de545a7cfcf4ab23dcf73426a1d50896d6d0c (diff)
downloadmongo-689d52131f6ac1a446fe1b93647b11d0329c629c.tar.gz
SERVER-34895 only set stable timestamp to timestamps in oplog
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/repl/oplog.cpp18
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.cpp32
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.h8
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl_elect_v1_test.cpp30
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl_reconfig_test.cpp52
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl_test.cpp245
-rw-r--r--src/mongo/db/repl/replication_coordinator_test_fixture.cpp4
-rw-r--r--src/mongo/db/repl/storage_interface.h13
-rw-r--r--src/mongo/db/repl/storage_interface_impl.cpp8
-rw-r--r--src/mongo/db/repl/storage_interface_impl.h4
-rw-r--r--src/mongo/db/repl/storage_interface_mock.cpp8
-rw-r--r--src/mongo/db/repl/storage_interface_mock.h7
-rw-r--r--src/mongo/db/storage/devnull/devnull_kv_engine.h2
-rw-r--r--src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.h2
-rw-r--r--src/mongo/db/storage/kv/kv_engine.h2
-rw-r--r--src/mongo/db/storage/kv/kv_storage_engine.cpp4
-rw-r--r--src/mongo/db/storage/kv/kv_storage_engine.h2
-rw-r--r--src/mongo/db/storage/mmap_v1/mmap_v1_engine.h2
-rw-r--r--src/mongo/db/storage/mobile/mobile_kv_engine.h2
-rw-r--r--src/mongo/db/storage/storage_engine.h2
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp4
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h2
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.cpp8
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.h4
24 files changed, 284 insertions, 181 deletions
diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp
index 7e01e6226e5..6ce206869a7 100644
--- a/src/mongo/db/repl/oplog.cpp
+++ b/src/mongo/db/repl/oplog.cpp
@@ -402,25 +402,9 @@ void _logOpsInner(OperationContext* opCtx,
<< commitTime->toString());
}
- auto lastAppliedTimestamp = finalOpTime.getTimestamp();
- const auto storageEngine = opCtx->getServiceContext()->getStorageEngine();
- if (storageEngine->supportsDocLocking()) {
- // If the storage engine supports document level locking, then it is possible for
- // oplog writes to commit out of order. In that case, we only want to set our last
- // applied optime to the all committed timestamp to ensure that all operations
- // earlier than the last applied optime have been storage-committed. We are
- // guaranteed that whatever operation occurred at the all committed timestamp
- // occurred during the same term as 'finalOpTime'. When a primary enters a new term,
- // it first commits a 'new primary' oplog entry in the new term before accepting any
- // new writes. This will ensure that the all committed timestamp is in the new term
- // before any client writes are committed.
- lastAppliedTimestamp = storageEngine->getAllCommittedTimestamp(opCtx);
- }
-
// Optimes on the primary should always represent consistent database states.
replCoord->setMyLastAppliedOpTimeForward(
- OpTime(lastAppliedTimestamp, finalOpTime.getTerm()),
- ReplicationCoordinator::DataConsistency::Consistent);
+ finalOpTime, ReplicationCoordinator::DataConsistency::Consistent);
// We set the last op on the client to 'finalOpTime', because that contains the
// timestamp of the operation that the client actually performed.
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp
index 210c65c13af..cea5dc3dd97 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl.cpp
@@ -1133,6 +1133,8 @@ void ReplicationCoordinatorImpl::_setMyLastAppliedOpTime_inlock(const OpTime& op
// RECOVERING after a rollback using the 'rollbackViaRefetch' algorithm, we will be inconsistent
// until we reach the 'minValid' optime.
if (consistency == DataConsistency::Consistent) {
+ invariant(opTime.getTimestamp().getInc() > 0,
+ str::stream() << "Impossible optime received: " << opTime.toString());
_stableOpTimeCandidates.insert(opTime);
// If we are lagged behind the commit optime, set a new stable timestamp here.
if (opTime <= _topCoord->getLastCommittedOpTime()) {
@@ -3029,7 +3031,7 @@ void ReplicationCoordinatorImpl::_updateLastCommittedOpTime_inlock() {
_wakeReadyWaiters_inlock();
}
-boost::optional<OpTime> ReplicationCoordinatorImpl::_calculateStableOpTime(
+boost::optional<OpTime> ReplicationCoordinatorImpl::_calculateStableOpTime_inlock(
const std::set<OpTime>& candidates, const OpTime& commitPoint) {
// No optime candidates.
@@ -3037,12 +3039,33 @@ boost::optional<OpTime> ReplicationCoordinatorImpl::_calculateStableOpTime(
return boost::none;
}
+ auto maximumStableTimestamp = commitPoint.getTimestamp();
+ if (_canAcceptNonLocalWrites && _storage->supportsDocLocking(_service)) {
+ // If the storage engine supports document level locking, then it is possible for oplog
+ // writes to commit out of order. In that case, we don't want to set the stable timestamp
+ // ahead of the all committed timestamp. This is not a problem for oplog application
+ // because we only set lastApplied between batches when the all committed timestamp cannot
+ // be behind. During oplog application the all committed timestamp can jump around since
+ // we first write oplog entries to the oplog and then go back and apply them.
+ //
+ // If the all committed timestamp is less than the commit point, then we are guaranteed that
+ // there are no stable timestamp candidates with a greater timestamp than the all committed
+ // timestamp and a lower term than the commit point. Thus we can consider the all committed
+ // timestamp to have the same term as the commit point. When a primary enters a new term, it
+ // first storage-commits a 'new primary' oplog entry in the new term before accepting any
+ // new writes. This will ensure that the all committed timestamp is in the new term before
+ // any writes in the new term are replication committed.
+ maximumStableTimestamp =
+ std::min(_storage->getAllCommittedTimestamp(_service), commitPoint.getTimestamp());
+ }
+ const auto maximumStableOpTime = OpTime(maximumStableTimestamp, commitPoint.getTerm());
+
// Find the greatest optime candidate that is less than or equal to the commit point.
// To do this we first find the upper bound of 'commitPoint', which points to the smallest
// element in 'candidates' that is greater than 'commitPoint'. We then step back one element,
// which should give us the largest element in 'candidates' that is less than or equal to the
// 'commitPoint'.
- auto upperBoundIter = candidates.upper_bound(commitPoint);
+ auto upperBoundIter = candidates.upper_bound(maximumStableOpTime);
// All optime candidates are greater than the commit point.
if (upperBoundIter == candidates.begin()) {
@@ -3068,7 +3091,8 @@ void ReplicationCoordinatorImpl::_cleanupStableOpTimeCandidates(std::set<OpTime>
boost::optional<OpTime> ReplicationCoordinatorImpl::calculateStableOpTime_forTest(
const std::set<OpTime>& candidates, const OpTime& commitPoint) {
- return _calculateStableOpTime(candidates, commitPoint);
+ stdx::lock_guard<stdx::mutex> lk(_mutex);
+ return _calculateStableOpTime_inlock(candidates, commitPoint);
}
void ReplicationCoordinatorImpl::cleanupStableOpTimeCandidates_forTest(std::set<OpTime>* candidates,
OpTime stableOpTime) {
@@ -3093,7 +3117,7 @@ boost::optional<OpTime> ReplicationCoordinatorImpl::_getStableOpTime_inlock() {
}
// Compute the current stable optime.
- auto stableOpTime = _calculateStableOpTime(_stableOpTimeCandidates, commitPoint);
+ auto stableOpTime = _calculateStableOpTime_inlock(_stableOpTimeCandidates, commitPoint);
if (stableOpTime) {
// By definition, the stable optime should never be greater than the commit point.
invariant(stableOpTime->getTimestamp() <= commitPoint.getTimestamp());
diff --git a/src/mongo/db/repl/replication_coordinator_impl.h b/src/mongo/db/repl/replication_coordinator_impl.h
index 9db6442ca68..32e53c9cf52 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.h
+++ b/src/mongo/db/repl/replication_coordinator_impl.h
@@ -975,8 +975,8 @@ private:
* current commit point. The stable optime is the greatest optime in 'candidates' that is
* also less than or equal to 'commitPoint'.
*/
- boost::optional<OpTime> _calculateStableOpTime(const std::set<OpTime>& candidates,
- const OpTime& commitPoint);
+ boost::optional<OpTime> _calculateStableOpTime_inlock(const std::set<OpTime>& candidates,
+ const OpTime& commitPoint);
/**
* Removes any optimes from the optime set 'candidates' that are less than
@@ -1121,8 +1121,8 @@ private:
// (PS) Pointer is read-only in concurrent operation, item pointed to is self-synchronizing;
// Access in any context.
// (M) Reads and writes guarded by _mutex
- // (GM) Readable under any global intent lock. Must hold both the global lock in exclusive
- // mode (MODE_X) and hold _mutex to write.
+ // (GM) Readable under any global intent lock or _mutex. Must hold both the global lock in
+ // exclusive mode (MODE_X) and hold _mutex to write.
// (I) Independently synchronized, see member variable comment.
// Protects member data of this ReplicationCoordinator.
diff --git a/src/mongo/db/repl/replication_coordinator_impl_elect_v1_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_elect_v1_test.cpp
index df475771ed0..388c465e69d 100644
--- a/src/mongo/db/repl/replication_coordinator_impl_elect_v1_test.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl_elect_v1_test.cpp
@@ -134,8 +134,8 @@ TEST_F(ReplCoordTest, ElectionSucceedsWhenNodeIsTheOnlyElectableNode) {
ASSERT(getReplCoord()->getMemberState().secondary())
<< getReplCoord()->getMemberState().toString();
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(10, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(10, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(10, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(10, 1), 0));
auto electionTimeoutWhen = getReplCoord()->getElectionTimeout_forTest();
ASSERT_NOT_EQUALS(Date_t(), electionTimeoutWhen);
@@ -198,8 +198,8 @@ TEST_F(ReplCoordTest, StartElectionDoesNotStartAnElectionWhenNodeIsRecovering) {
ASSERT(getReplCoord()->getMemberState().recovering())
<< getReplCoord()->getMemberState().toString();
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(10, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(10, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(10, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(10, 1), 0));
simulateEnoughHeartbeatsForAllNodesUp();
auto electionTimeoutWhen = getReplCoord()->getElectionTimeout_forTest();
@@ -219,8 +219,8 @@ TEST_F(ReplCoordTest, ElectionSucceedsWhenNodeIsTheOnlyNode) {
<< 1),
HostAndPort("node1", 12345));
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(10, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(10, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(10, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(10, 1), 0));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
getReplCoord()->waitForElectionFinish_forTest();
ASSERT(getReplCoord()->getMemberState().primary())
@@ -464,8 +464,8 @@ TEST_F(ReplCoordTest, NodeWillNotStandForElectionDuringHeartbeatReconfig) {
<< 1),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 1), 0));
getGlobalFailPointRegistry()
->getFailPoint("blockHeartbeatReconfigFinish")
@@ -1927,9 +1927,9 @@ TEST_F(TakeoverTest, DontCallForPriorityTakeoverWhenLaggedDifferentSecond) {
auto now = getNet()->now();
OperationContextNoop opCtx;
- OpTime currentOpTime(Timestamp(100, 0), 0);
- OpTime behindOpTime(Timestamp(97, 0), 0);
- OpTime closeEnoughOpTime(Timestamp(98, 0), 0);
+ OpTime currentOpTime(Timestamp(100, 1), 0);
+ OpTime behindOpTime(Timestamp(97, 1), 0);
+ OpTime closeEnoughOpTime(Timestamp(98, 1), 0);
replCoord->setMyLastAppliedOpTime(behindOpTime);
replCoord->setMyLastDurableOpTime(behindOpTime);
@@ -1999,8 +1999,8 @@ TEST_F(ReplCoordTest, NodeCancelsElectionUponReceivingANewConfigDuringDryRun) {
<< BSON("heartbeatIntervalMillis" << 100)),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 1), 0));
simulateEnoughHeartbeatsForAllNodesUp();
// Advance to dry run vote request phase.
@@ -2064,8 +2064,8 @@ TEST_F(ReplCoordTest, NodeCancelsElectionUponReceivingANewConfigDuringVotePhase)
<< BSON("heartbeatIntervalMillis" << 100)),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 1), 0));
simulateEnoughHeartbeatsForAllNodesUp();
simulateSuccessfulDryRun();
ASSERT(TopologyCoordinator::Role::kCandidate == getTopoCoord().getRole());
diff --git a/src/mongo/db/repl/replication_coordinator_impl_reconfig_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_reconfig_test.cpp
index 728616d3b5a..5aefac8a7b2 100644
--- a/src/mongo/db/repl/replication_coordinator_impl_reconfig_test.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl_reconfig_test.cpp
@@ -82,8 +82,8 @@ TEST_F(ReplCoordTest, NodeReturnsNotMasterWhenReconfigReceivedWhileSecondary) {
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 1), 0));
BSONObjBuilder result;
ReplSetReconfigArgs args;
@@ -107,8 +107,8 @@ TEST_F(ReplCoordTest, NodeReturnsInvalidReplicaSetConfigWhenReconfigReceivedWith
<< "node2:12345"))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 1), 0));
simulateSuccessfulV1Election();
BSONObjBuilder result;
@@ -151,8 +151,8 @@ TEST_F(ReplCoordTest, NodeReturnsInvalidReplicaSetConfigWhenReconfigReceivedWith
<< "node2:12345"))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 1), 0));
simulateSuccessfulV1Election();
BSONObjBuilder result;
@@ -191,8 +191,8 @@ TEST_F(ReplCoordTest, NodeReturnsInvalidReplicaSetConfigWhenReconfigReceivedWith
<< BSON("replicaSetId" << OID::gen())),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 1), 0));
simulateSuccessfulV1Election();
BSONObjBuilder result;
@@ -232,8 +232,8 @@ TEST_F(ReplCoordTest,
<< "node2:12345"))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 1), 0));
simulateSuccessfulV1Election();
BSONObjBuilder result;
@@ -313,8 +313,8 @@ TEST_F(ReplCoordTest,
<< "node2:12345"))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 1), 0));
simulateSuccessfulV1Election();
Status status(ErrorCodes::InternalError, "Not Set");
@@ -354,8 +354,8 @@ TEST_F(ReplCoordTest, NodeReturnsOutOfDiskSpaceWhenSavingANewConfigFailsDuringRe
<< "node2:12345"))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 1), 0));
simulateSuccessfulV1Election();
Status status(ErrorCodes::InternalError, "Not Set");
@@ -383,8 +383,8 @@ TEST_F(ReplCoordTest,
<< "node2:12345"))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 1), 0));
simulateSuccessfulV1Election();
Status status(ErrorCodes::InternalError, "Not Set");
@@ -423,8 +423,8 @@ TEST_F(ReplCoordTest, NodeReturnsConfigurationInProgressWhenReceivingAReconfigWh
init();
start(HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 1), 0));
// initiate
Status status(ErrorCodes::InternalError, "Not Set");
@@ -472,8 +472,8 @@ TEST_F(ReplCoordTest, PrimaryNodeAcceptsNewConfigWhenReceivingAReconfigWithAComp
<< BSON("replicaSetId" << OID::gen())),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 1), 0));
simulateSuccessfulV1Election();
Status status(ErrorCodes::InternalError, "Not Set");
@@ -516,8 +516,8 @@ TEST_F(
<< "node2:12345"))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 1), 0));
simulateSuccessfulV1Election();
ASSERT_TRUE(getReplCoord()->getMemberState().primary());
@@ -583,8 +583,8 @@ TEST_F(ReplCoordTest, NodeDoesNotAcceptHeartbeatReconfigWhileInTheMidstOfReconfi
<< "node2:12345"))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 1), 0));
simulateSuccessfulV1Election();
ASSERT_TRUE(getReplCoord()->getMemberState().primary());
@@ -652,8 +652,8 @@ TEST_F(ReplCoordTest, NodeAcceptsConfigFromAReconfigWithForceTrueWhileNotPrimary
<< "node2:12345"))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 1), 0));
// fail before forced
BSONObjBuilder result;
diff --git a/src/mongo/db/repl/replication_coordinator_impl_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_test.cpp
index 41b572c0ef0..01cff031b59 100644
--- a/src/mongo/db/repl/replication_coordinator_impl_test.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl_test.cpp
@@ -657,8 +657,8 @@ TEST_F(ReplCoordTest, NodeReturnsOkWhenRunningAwaitReplicationAgainstPrimaryWith
// Become primary.
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 1));
simulateSuccessfulV1Election();
ASSERT(getReplCoord()->getMemberState().primary());
@@ -694,12 +694,12 @@ TEST_F(ReplCoordTest,
<< 3))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 1));
simulateSuccessfulV1Election();
- OpTimeWithTermOne time1(100, 1);
- OpTimeWithTermOne time2(100, 2);
+ OpTimeWithTermOne time1(100, 2);
+ OpTimeWithTermOne time2(100, 3);
WriteConcernOptions writeConcern;
writeConcern.wTimeout = WriteConcernOptions::kNoWaiting;
@@ -774,12 +774,12 @@ TEST_F(ReplCoordTest, NodeReturnsWriteConcernFailedUntilASufficientNumberOfNodes
<< 3))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 1));
simulateSuccessfulV1Election();
- OpTimeWithTermOne time1(100, 1);
- OpTimeWithTermOne time2(100, 2);
+ OpTimeWithTermOne time1(100, 2);
+ OpTimeWithTermOne time2(100, 3);
WriteConcernOptions writeConcern;
writeConcern.wTimeout = WriteConcernOptions::kNoWaiting;
@@ -849,8 +849,8 @@ TEST_F(ReplCoordTest,
<< "node4"))),
HostAndPort("node0"));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 1), 0));
simulateSuccessfulV1Election();
OpTime time1(Timestamp(100, 1), 1);
@@ -919,8 +919,8 @@ TEST_F(
<< BSON("dc" << 2 << "rack" << 3)))),
HostAndPort("node0"));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 1), 0));
simulateSuccessfulV1Election();
OpTime time1(Timestamp(100, 1), 1);
@@ -1075,8 +1075,8 @@ TEST_F(ReplCoordTest, NodeReturnsOkWhenAWriteConcernWithNoTimeoutHasBeenSatisfie
<< 2))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 1));
simulateSuccessfulV1Election();
ReplicationAwaiter awaiter(getReplCoord(), getServiceContext());
@@ -1139,8 +1139,8 @@ TEST_F(ReplCoordTest, NodeReturnsWriteConcernFailedWhenAWriteConcernTimesOutBefo
<< 2))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 1));
simulateSuccessfulV1Election();
ReplicationAwaiter awaiter(getReplCoord(), getServiceContext());
@@ -1190,8 +1190,8 @@ TEST_F(ReplCoordTest,
<< 2))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 1));
simulateSuccessfulV1Election();
ReplicationAwaiter awaiter(getReplCoord(), getServiceContext());
@@ -1240,8 +1240,8 @@ TEST_F(ReplCoordTest, NodeReturnsNotMasterWhenSteppingDownBeforeSatisfyingAWrite
<< 2))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 1));
simulateSuccessfulV1Election();
const auto opCtx = makeOperationContext();
@@ -1282,8 +1282,8 @@ TEST_F(ReplCoordTest,
<< "node3"))),
HostAndPort("node1"));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 1));
simulateSuccessfulV1Election();
ReplicationAwaiter awaiter(getReplCoord(), getServiceContext());
@@ -2342,8 +2342,8 @@ TEST_F(ReplCoordTest,
<< "test3:1234"))),
HostAndPort("test2", 1234));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 1));
// Can't unset maintenance mode if it was never set to begin with.
Status status = getReplCoord()->setMaintenanceMode(false);
@@ -2369,8 +2369,8 @@ TEST_F(ReplCoordTest,
<< "test3:1234"))),
HostAndPort("test2", 1234));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 1));
// valid set
ASSERT_OK(getReplCoord()->setMaintenanceMode(true));
ASSERT_TRUE(getReplCoord()->getMemberState().recovering());
@@ -2401,8 +2401,8 @@ TEST_F(ReplCoordTest, AllowAsManyUnsetMaintenanceModesAsThereHaveBeenSetMaintena
<< "test3:1234"))),
HostAndPort("test2", 1234));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 1));
// Can set multiple times
ASSERT_OK(getReplCoord()->setMaintenanceMode(true));
ASSERT_OK(getReplCoord()->setMaintenanceMode(true));
@@ -2435,8 +2435,8 @@ TEST_F(ReplCoordTest, SettingAndUnsettingMaintenanceModeShouldNotAffectRollbackS
<< "test3:1234"))),
HostAndPort("test2", 1234));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 1));
// From rollback, entering and exiting maintenance mode doesn't change perceived
// state.
@@ -2477,8 +2477,8 @@ TEST_F(ReplCoordTest, DoNotAllowMaintenanceModeWhilePrimary) {
<< "test3:1234"))),
HostAndPort("test2", 1234));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 1));
// Can't modify maintenance mode when PRIMARY
simulateSuccessfulV1Election();
@@ -2516,8 +2516,8 @@ TEST_F(ReplCoordTest, DoNotAllowSettingMaintenanceModeWhileConductingAnElection)
<< "test3:1234"))),
HostAndPort("test2", 1234));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 1));
// TODO this election shouldn't have to happen.
simulateSuccessfulV1Election();
@@ -2828,8 +2828,8 @@ TEST_F(ReplCoordTest, DoNotProcessSelfWhenUpdatePositionContainsInfoAboutSelf) {
<< 2))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 1));
simulateSuccessfulV1Election();
OpTime time1({100, 1}, 1);
@@ -2886,8 +2886,8 @@ TEST_F(ReplCoordTest, DoNotProcessUpdatePositionWhenItsConfigVersionIsIncorrect)
<< 2))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 1));
simulateSuccessfulV1Election();
OpTime time1({100, 1}, 1);
@@ -2943,8 +2943,8 @@ TEST_F(ReplCoordTest, DoNotProcessUpdatePositionOfMembersWhoseIdsAreNotInTheConf
<< 2))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 1));
simulateSuccessfulV1Election();
OpTime time1({100, 1}, 1);
@@ -2999,8 +2999,8 @@ TEST_F(ReplCoordTest,
<< 2))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 1));
simulateSuccessfulV1Election();
OpTimeWithTermOne time1(100, 1);
@@ -3349,7 +3349,7 @@ TEST_F(ReplCoordTest,
<< true))),
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
- OpTime time(Timestamp(100, 0), 1);
+ OpTime time(Timestamp(100, 1), 1);
getReplCoord()->setMyLastAppliedOpTime(time);
getReplCoord()->setMyLastDurableOpTime(time);
simulateSuccessfulV1Election();
@@ -3418,7 +3418,7 @@ TEST_F(ReplCoordTest,
HostAndPort("node1", 12345));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
OpTime zero(Timestamp(0, 0), 0);
- OpTime time(Timestamp(100, 0), 1);
+ OpTime time(Timestamp(100, 1), 1);
getReplCoord()->setMyLastAppliedOpTime(time);
getReplCoord()->setMyLastDurableOpTime(time);
simulateSuccessfulV1Election();
@@ -3617,29 +3617,60 @@ TEST_F(StableOpTimeTest, SetMyLastAppliedSetsStableOpTimeForStorage) {
* and that timestamp cleanup occurs. This test is not meant to fully exercise the stable
* optime calculation logic.
*/
+ init("mySet/test1:1234,test2:1234,test3:1234");
+ assertStartSuccess(BSON("_id"
+ << "mySet"
+ << "protocolVersion"
+ << 1
+ << "version"
+ << 1
+ << "members"
+ << BSON_ARRAY(BSON("_id" << 0 << "host"
+ << "test1:1234")
+ << BSON("_id" << 1 << "host"
+ << "test2:1234")
+ << BSON("_id" << 2 << "host"
+ << "test3:1234"))),
+ HostAndPort("test2", 1234));
- initReplSetMode();
auto repl = getReplCoord();
Timestamp stableTimestamp;
- long long term = 0;
+ long long term = 2;
+
+ getStorageInterface()->supportsDocLockingBool = true;
- // There should be no stable optime candidates until setMyLastAppliedOpTime is called.
- repl->advanceCommitPoint(OpTime({1, 2}, 0));
+ repl->advanceCommitPoint(OpTime({1, 1}, term));
ASSERT_EQUALS(Timestamp::min(), getStorageInterface()->getStableTimestamp());
+ ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
+
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(1, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(1, 1));
+ simulateSuccessfulV1Election();
+
+ repl->advanceCommitPoint(OpTime({2, 2}, term));
+ ASSERT_EQUALS(Timestamp(1, 1), getStorageInterface()->getStableTimestamp());
+
+ // Check that the stable timestamp is not updated if the all-committed timestamp is behind.
+ getStorageInterface()->allCommittedTimestamp = Timestamp(1, 1);
+ repl->setMyLastAppliedOpTime(OpTime({1, 2}, term));
+ stableTimestamp = getStorageInterface()->getStableTimestamp();
+ ASSERT_EQUALS(Timestamp(1, 1), getStorageInterface()->getStableTimestamp());
+
+ getStorageInterface()->allCommittedTimestamp = Timestamp(3, 1);
// Check that the stable timestamp is updated for the storage engine when we set the applied
// optime.
- repl->setMyLastAppliedOpTime(OpTime({1, 1}, 0));
+ repl->setMyLastAppliedOpTime(OpTime({2, 1}, term));
stableTimestamp = getStorageInterface()->getStableTimestamp();
- ASSERT_EQUALS(Timestamp(1, 1), stableTimestamp);
+ ASSERT_EQUALS(Timestamp(2, 1), stableTimestamp);
// Check that timestamp cleanup occurs.
- repl->setMyLastAppliedOpTime(OpTime({1, 2}, 0));
+ repl->setMyLastAppliedOpTime(OpTime({2, 2}, term));
stableTimestamp = getStorageInterface()->getStableTimestamp();
- ASSERT_EQUALS(Timestamp(1, 2), stableTimestamp);
+ ASSERT_EQUALS(Timestamp(2, 2), stableTimestamp);
auto opTimeCandidates = repl->getStableOpTimeCandidates_forTest();
- std::set<OpTime> expectedOpTimeCandidates = {OpTime({1, 2}, term)};
+ std::set<OpTime> expectedOpTimeCandidates = {OpTime({2, 2}, term)};
ASSERT_OPTIME_SET_EQ(expectedOpTimeCandidates, opTimeCandidates);
}
@@ -3651,28 +3682,58 @@ TEST_F(StableOpTimeTest, AdvanceCommitPointSetsStableOpTimeForStorage) {
* calculation logic.
*/
- initReplSetMode();
+ init("mySet/test1:1234,test2:1234,test3:1234");
+ assertStartSuccess(BSON("_id"
+ << "mySet"
+ << "protocolVersion"
+ << 1
+ << "version"
+ << 1
+ << "members"
+ << BSON_ARRAY(BSON("_id" << 0 << "host"
+ << "test1:1234")
+ << BSON("_id" << 1 << "host"
+ << "test2:1234")
+ << BSON("_id" << 2 << "host"
+ << "test3:1234"))),
+ HostAndPort("test2", 1234));
+ ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(1, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(1, 1));
+ simulateSuccessfulV1Election();
+
auto repl = getReplCoord();
Timestamp stableTimestamp;
- long long term = 0;
+ long long term = 2;
- // Add two stable optime candidates.
- repl->setMyLastAppliedOpTime(OpTime({1, 1}, term));
- repl->setMyLastAppliedOpTime(OpTime({1, 2}, term));
+ getStorageInterface()->supportsDocLockingBool = true;
+ getStorageInterface()->allCommittedTimestamp = Timestamp(2, 1);
+
+ // Add three stable optime candidates.
+ repl->setMyLastAppliedOpTime(OpTime({2, 1}, term));
+ repl->setMyLastAppliedOpTime(OpTime({2, 2}, term));
+ repl->setMyLastAppliedOpTime(OpTime({3, 2}, term));
// Set a commit point and check the stable optime.
- repl->advanceCommitPoint(OpTime({1, 1}, term));
+ repl->advanceCommitPoint(OpTime({2, 1}, term));
+ stableTimestamp = getStorageInterface()->getStableTimestamp();
+ ASSERT_EQUALS(Timestamp(2, 1), stableTimestamp);
+
+ // Check that the stable timestamp is not updated if the all-committed timestamp is behind.
+ repl->advanceCommitPoint(OpTime({2, 2}, term));
stableTimestamp = getStorageInterface()->getStableTimestamp();
- ASSERT_EQUALS(Timestamp(1, 1), stableTimestamp);
+ ASSERT_EQUALS(Timestamp(2, 1), stableTimestamp);
+
+ getStorageInterface()->allCommittedTimestamp = Timestamp(4, 4);
// Check that the stable timestamp is updated when we advance the commit point.
- repl->advanceCommitPoint(OpTime({1, 2}, term));
+ repl->advanceCommitPoint(OpTime({3, 2}, term));
stableTimestamp = getStorageInterface()->getStableTimestamp();
- ASSERT_EQUALS(Timestamp(1, 2), stableTimestamp);
+ ASSERT_EQUALS(Timestamp(3, 2), stableTimestamp);
// Check that timestamp candidate cleanup occurs.
auto opTimeCandidates = getReplCoord()->getStableOpTimeCandidates_forTest();
- std::set<OpTime> expectedOpTimeCandidates = {OpTime({1, 2}, term)};
+ std::set<OpTime> expectedOpTimeCandidates = {OpTime({3, 2}, term)};
ASSERT_OPTIME_SET_EQ(expectedOpTimeCandidates, opTimeCandidates);
}
@@ -3777,8 +3838,8 @@ TEST_F(ReplCoordTest, NodeReturnsShutdownInProgressWhenWaitingUntilAnOpTimeDurin
<< 0))),
HostAndPort("node1", 12345));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(10, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(10, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(10, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(10, 1));
auto opCtx = makeOperationContext();
@@ -3802,8 +3863,8 @@ TEST_F(ReplCoordTest, NodeReturnsInterruptedWhenWaitingUntilAnOpTimeIsInterrupte
<< 0))),
HostAndPort("node1", 12345));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(10, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(10, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(10, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(10, 1));
const auto opCtx = makeOperationContext();
killOperation(opCtx.get());
@@ -3843,8 +3904,8 @@ TEST_F(ReplCoordTest, NodeReturnsOkImmediatelyWhenWaitingUntilOpTimePassesAnOpTi
<< 0))),
HostAndPort("node1", 12345));
- getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 0));
- getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTimeWithTermOne(100, 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTimeWithTermOne(100, 1));
auto opCtx = makeOperationContext();
@@ -3866,7 +3927,7 @@ TEST_F(ReplCoordTest, NodeReturnsOkImmediatelyWhenWaitingUntilOpTimePassesAnOpTi
HostAndPort("node1", 12345));
- OpTimeWithTermOne time(100, 0);
+ OpTimeWithTermOne time(100, 1);
getReplCoord()->setMyLastAppliedOpTime(time);
getReplCoord()->setMyLastDurableOpTime(time);
@@ -3915,8 +3976,8 @@ TEST_F(ReplCoordTest, ReadAfterCommittedWhileShutdown) {
auto opCtx = makeOperationContext();
runSingleNodeElection(opCtx.get());
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(10, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(10, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(10, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(10, 1), 0));
shutdown(opCtx.get());
@@ -3940,8 +4001,8 @@ TEST_F(ReplCoordTest, ReadAfterCommittedInterrupted) {
const auto opCtx = makeOperationContext();
runSingleNodeElection(opCtx.get());
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(10, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(10, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(10, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(10, 1), 0));
killOperation(opCtx.get());
auto status = getReplCoord()->waitUntilOpTimeForRead(
opCtx.get(),
@@ -3963,8 +4024,8 @@ TEST_F(ReplCoordTest, ReadAfterCommittedGreaterOpTime) {
auto opCtx = makeOperationContext();
runSingleNodeElection(opCtx.get());
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 0), 1));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 0), 1));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(100, 1), 1));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(100, 1), 1));
ASSERT_OK(getReplCoord()->waitUntilOpTimeForRead(
opCtx.get(),
@@ -3985,7 +4046,7 @@ TEST_F(ReplCoordTest, ReadAfterCommittedEqualOpTime) {
auto opCtx = makeOperationContext();
runSingleNodeElection(opCtx.get());
- OpTime time(Timestamp(100, 0), 1);
+ OpTime time(Timestamp(100, 1), 1);
getReplCoord()->setMyLastAppliedOpTime(time);
getReplCoord()->setMyLastDurableOpTime(time);
@@ -4009,7 +4070,7 @@ TEST_F(ReplCoordTest, ReadAfterCommittedDeferredGreaterOpTime) {
runSingleNodeElection(opCtx.get());
getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(0, 0), 1));
getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(0, 0), 1));
- OpTime committedOpTime(Timestamp(200, 0), 1);
+ OpTime committedOpTime(Timestamp(200, 1), 1);
auto pseudoLogOp = stdx::async(stdx::launch::async, [this, &committedOpTime]() {
// Not guaranteed to be scheduled after waitUntil blocks...
getReplCoord()->setMyLastAppliedOpTime(committedOpTime);
@@ -4037,7 +4098,7 @@ TEST_F(ReplCoordTest, ReadAfterCommittedDeferredEqualOpTime) {
getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(0, 0), 1));
getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(0, 0), 1));
- OpTime opTimeToWait(Timestamp(100, 0), 1);
+ OpTime opTimeToWait(Timestamp(100, 1), 1);
auto pseudoLogOp = stdx::async(stdx::launch::async, [this, &opTimeToWait]() {
// Not guaranteed to be scheduled after waitUntil blocks...
@@ -4134,8 +4195,8 @@ TEST_F(ReplCoordTest, UpdateLastCommittedOpTimeWhenTheLastCommittedOpTimeIsNewer
getReplCoord()->updateTerm(opCtx.get(), 1).transitional_ignore();
ASSERT_EQUALS(1, getReplCoord()->getTerm());
- OpTime time(Timestamp(10, 0), 1);
- OpTime oldTime(Timestamp(9, 0), 1);
+ OpTime time(Timestamp(10, 1), 1);
+ OpTime oldTime(Timestamp(9, 1), 1);
getReplCoord()->setMyLastAppliedOpTime(time);
// higher OpTime, should change
@@ -4387,8 +4448,8 @@ TEST_F(ReplCoordTest, TermAndLastCommittedOpTimeUpdatedFromHeartbeatWhenArbiter)
// commit point via heartbeats.
StatusWith<rpc::ReplSetMetadata> metadata = rpc::ReplSetMetadata::readFromMetadata(BSON(
rpc::kReplSetMetadataFieldName
- << BSON("lastOpCommitted" << BSON("ts" << Timestamp(10, 0) << "t" << 3) << "lastOpVisible"
- << BSON("ts" << Timestamp(10, 0) << "t" << 3)
+ << BSON("lastOpCommitted" << BSON("ts" << Timestamp(10, 1) << "t" << 3) << "lastOpVisible"
+ << BSON("ts" << Timestamp(10, 1) << "t" << 3)
<< "configVersion"
<< config.getConfigVersion()
<< "primaryIndex"
@@ -4418,7 +4479,7 @@ TEST_F(ReplCoordTest, TermAndLastCommittedOpTimeUpdatedFromHeartbeatWhenArbiter)
net->runReadyNetworkOperations();
net->exitNetwork();
- ASSERT_EQUALS(OpTime(Timestamp(10, 0), 3), getReplCoord()->getLastCommittedOpTime());
+ ASSERT_EQUALS(OpTime(Timestamp(10, 1), 3), getReplCoord()->getLastCommittedOpTime());
ASSERT_EQUALS(3, getReplCoord()->getTerm());
ASSERT_EQUALS(-1, getTopoCoord().getCurrentPrimaryIndex());
}
@@ -5180,8 +5241,8 @@ TEST_F(ReplCoordTest, WaitForMemberState) {
HostAndPort("test1", 1234));
auto replCoord = getReplCoord();
auto initialTerm = replCoord->getTerm();
- replCoord->setMyLastAppliedOpTime(OpTime(Timestamp(1, 0), 0));
- replCoord->setMyLastDurableOpTime(OpTime(Timestamp(1, 0), 0));
+ replCoord->setMyLastAppliedOpTime(OpTime(Timestamp(1, 1), 0));
+ replCoord->setMyLastDurableOpTime(OpTime(Timestamp(1, 1), 0));
ASSERT_OK(replCoord->setFollowerMode(MemberState::RS_SECONDARY));
// Single node cluster - this node should start election on setFollowerMode() completion.
@@ -5217,8 +5278,8 @@ TEST_F(ReplCoordTest, WaitForDrainFinish) {
HostAndPort("test1", 1234));
auto replCoord = getReplCoord();
auto initialTerm = replCoord->getTerm();
- replCoord->setMyLastAppliedOpTime(OpTime(Timestamp(1, 0), 0));
- replCoord->setMyLastDurableOpTime(OpTime(Timestamp(1, 0), 0));
+ replCoord->setMyLastAppliedOpTime(OpTime(Timestamp(1, 1), 0));
+ replCoord->setMyLastDurableOpTime(OpTime(Timestamp(1, 1), 0));
ASSERT_OK(replCoord->setFollowerMode(MemberState::RS_SECONDARY));
// Single node cluster - this node should start election on setFollowerMode() completion.
@@ -5361,7 +5422,7 @@ TEST_F(ReplCoordTest, NodeStoresElectionVotes) {
<< "_id"
<< 2))),
HostAndPort("node1", 12345));
- auto time = OpTimeWithTermOne(100, 0);
+ auto time = OpTimeWithTermOne(100, 1);
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
getReplCoord()->setMyLastAppliedOpTime(time);
getReplCoord()->setMyLastDurableOpTime(time);
@@ -5415,7 +5476,7 @@ TEST_F(ReplCoordTest, NodeDoesNotStoreDryRunVotes) {
<< "_id"
<< 2))),
HostAndPort("node1", 12345));
- auto time = OpTimeWithTermOne(100, 0);
+ auto time = OpTimeWithTermOne(100, 1);
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
getReplCoord()->setMyLastAppliedOpTime(time);
getReplCoord()->setMyLastDurableOpTime(time);
diff --git a/src/mongo/db/repl/replication_coordinator_test_fixture.cpp b/src/mongo/db/repl/replication_coordinator_test_fixture.cpp
index a7ce2561f57..db81b8e46d8 100644
--- a/src/mongo/db/repl/replication_coordinator_test_fixture.cpp
+++ b/src/mongo/db/repl/replication_coordinator_test_fixture.cpp
@@ -394,8 +394,8 @@ void ReplCoordTest::signalDrainComplete(OperationContext* opCtx) {
}
void ReplCoordTest::runSingleNodeElection(OperationContext* opCtx) {
- getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(1, 0), 0));
- getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(1, 0), 0));
+ getReplCoord()->setMyLastAppliedOpTime(OpTime(Timestamp(1, 1), 0));
+ getReplCoord()->setMyLastDurableOpTime(OpTime(Timestamp(1, 1), 0));
ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_SECONDARY));
getReplCoord()->waitForElectionFinish_forTest();
diff --git a/src/mongo/db/repl/storage_interface.h b/src/mongo/db/repl/storage_interface.h
index 234a45871d4..db97cc8c698 100644
--- a/src/mongo/db/repl/storage_interface.h
+++ b/src/mongo/db/repl/storage_interface.h
@@ -381,6 +381,19 @@ public:
virtual void waitForAllEarlierOplogWritesToBeVisible(OperationContext* opCtx) = 0;
/**
+ * Returns the all committed timestamp. All transactions with timestamps earlier than the
+ * all committed timestamp are committed. Only storage engines that support document level
+ * locking must provide an implementation. Other storage engines may provide a no-op
+ * implementation.
+ */
+ virtual Timestamp getAllCommittedTimestamp(ServiceContext* serviceCtx) const = 0;
+
+ /**
+ * Returns true if the storage engine supports document level locking.
+ */
+ virtual bool supportsDocLocking(ServiceContext* serviceCtx) const = 0;
+
+ /**
* Registers a timestamp with the storage engine so that it can enforce oplog visiblity rules.
* orderedCommit - specifies whether the timestamp provided is ordered w.r.t. commits; that is,
* all commits with older timestamps have already occurred, and any commits with newer
diff --git a/src/mongo/db/repl/storage_interface_impl.cpp b/src/mongo/db/repl/storage_interface_impl.cpp
index 70e44dd80b5..fad6858f2e3 100644
--- a/src/mongo/db/repl/storage_interface_impl.cpp
+++ b/src/mongo/db/repl/storage_interface_impl.cpp
@@ -1149,5 +1149,13 @@ boost::optional<Timestamp> StorageInterfaceImpl::getLastStableCheckpointTimestam
return ret;
}
+bool StorageInterfaceImpl::supportsDocLocking(ServiceContext* serviceCtx) const {
+ return serviceCtx->getStorageEngine()->supportsDocLocking();
+}
+
+Timestamp StorageInterfaceImpl::getAllCommittedTimestamp(ServiceContext* serviceCtx) const {
+ return serviceCtx->getStorageEngine()->getAllCommittedTimestamp();
+}
+
} // namespace repl
} // namespace mongo
diff --git a/src/mongo/db/repl/storage_interface_impl.h b/src/mongo/db/repl/storage_interface_impl.h
index b86d36b17ac..8f8fdb8c621 100644
--- a/src/mongo/db/repl/storage_interface_impl.h
+++ b/src/mongo/db/repl/storage_interface_impl.h
@@ -166,6 +166,10 @@ public:
boost::optional<Timestamp> getRecoveryTimestamp(ServiceContext* serviceCtx) const override;
+ bool supportsDocLocking(ServiceContext* serviceCtx) const override;
+
+ Timestamp getAllCommittedTimestamp(ServiceContext* serviceCtx) const override;
+
/**
* Checks that the "admin" database contains a supported version of the auth data schema.
*/
diff --git a/src/mongo/db/repl/storage_interface_mock.cpp b/src/mongo/db/repl/storage_interface_mock.cpp
index 2282c7ca9ac..17aa602a63d 100644
--- a/src/mongo/db/repl/storage_interface_mock.cpp
+++ b/src/mongo/db/repl/storage_interface_mock.cpp
@@ -89,6 +89,14 @@ Timestamp StorageInterfaceMock::getInitialDataTimestamp() const {
return _initialDataTimestamp;
}
+Timestamp StorageInterfaceMock::getAllCommittedTimestamp(ServiceContext* serviceCtx) const {
+ return allCommittedTimestamp;
+}
+
+bool StorageInterfaceMock::supportsDocLocking(ServiceContext* serviceCtx) const {
+ return supportsDocLockingBool;
+}
+
Status CollectionBulkLoaderMock::init(const std::vector<BSONObj>& secondaryIndexSpecs) {
LOG(1) << "CollectionBulkLoaderMock::init called";
stats->initCalled = true;
diff --git a/src/mongo/db/repl/storage_interface_mock.h b/src/mongo/db/repl/storage_interface_mock.h
index 3bb46b2fe0b..f242c0b6a93 100644
--- a/src/mongo/db/repl/storage_interface_mock.h
+++ b/src/mongo/db/repl/storage_interface_mock.h
@@ -303,6 +303,10 @@ public:
return boost::none;
}
+ Timestamp getAllCommittedTimestamp(ServiceContext* serviceCtx) const override;
+
+ bool supportsDocLocking(ServiceContext* serviceCtx) const override;
+
Status isAdminDbValid(OperationContext* opCtx) override {
return isAdminDbValidFn(opCtx);
};
@@ -384,6 +388,9 @@ public:
return Status{ErrorCodes::IllegalOperation, "GetCollectionUUIDFn not implemented."};
};
+ bool supportsDocLockingBool = false;
+ Timestamp allCommittedTimestamp = Timestamp::min();
+
private:
mutable stdx::mutex _mutex;
int _rbid;
diff --git a/src/mongo/db/storage/devnull/devnull_kv_engine.h b/src/mongo/db/storage/devnull/devnull_kv_engine.h
index 2f6d1ca75f2..5e8af42c74d 100644
--- a/src/mongo/db/storage/devnull/devnull_kv_engine.h
+++ b/src/mongo/db/storage/devnull/devnull_kv_engine.h
@@ -112,7 +112,7 @@ public:
void setJournalListener(JournalListener* jl) final {}
- virtual Timestamp getAllCommittedTimestamp(OperationContext* opCtx) const override {
+ virtual Timestamp getAllCommittedTimestamp() const override {
return Timestamp();
}
diff --git a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.h b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.h
index 6574ff10beb..38c9ea37cef 100644
--- a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.h
+++ b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.h
@@ -110,7 +110,7 @@ public:
_journalListener = jl;
}
- virtual Timestamp getAllCommittedTimestamp(OperationContext* opCtx) const override {
+ virtual Timestamp getAllCommittedTimestamp() const override {
MONGO_UNREACHABLE;
}
diff --git a/src/mongo/db/storage/kv/kv_engine.h b/src/mongo/db/storage/kv/kv_engine.h
index 2c0a45d862f..750f3a1d249 100644
--- a/src/mongo/db/storage/kv/kv_engine.h
+++ b/src/mongo/db/storage/kv/kv_engine.h
@@ -292,7 +292,7 @@ public:
/**
* See `StorageEngine::getAllCommittedTimestamp`
*/
- virtual Timestamp getAllCommittedTimestamp(OperationContext* opCtx) const = 0;
+ virtual Timestamp getAllCommittedTimestamp() const = 0;
/**
* See `StorageEngine::supportsReadConcernSnapshot`
diff --git a/src/mongo/db/storage/kv/kv_storage_engine.cpp b/src/mongo/db/storage/kv/kv_storage_engine.cpp
index 7c6fb248668..d76642cc8c4 100644
--- a/src/mongo/db/storage/kv/kv_storage_engine.cpp
+++ b/src/mongo/db/storage/kv/kv_storage_engine.cpp
@@ -632,8 +632,8 @@ void KVStorageEngine::replicationBatchIsComplete() const {
return _engine->replicationBatchIsComplete();
}
-Timestamp KVStorageEngine::getAllCommittedTimestamp(OperationContext* opCtx) const {
- return _engine->getAllCommittedTimestamp(opCtx);
+Timestamp KVStorageEngine::getAllCommittedTimestamp() const {
+ return _engine->getAllCommittedTimestamp();
}
void KVStorageEngine::_dumpCatalog(OperationContext* opCtx) {
diff --git a/src/mongo/db/storage/kv/kv_storage_engine.h b/src/mongo/db/storage/kv/kv_storage_engine.h
index c3f58c91ab9..79ae83adf52 100644
--- a/src/mongo/db/storage/kv/kv_storage_engine.h
+++ b/src/mongo/db/storage/kv/kv_storage_engine.h
@@ -127,7 +127,7 @@ public:
virtual boost::optional<Timestamp> getLastStableCheckpointTimestamp() const override;
- virtual Timestamp getAllCommittedTimestamp(OperationContext* opCtx) const override;
+ virtual Timestamp getAllCommittedTimestamp() const override;
bool supportsReadConcernSnapshot() const final;
diff --git a/src/mongo/db/storage/mmap_v1/mmap_v1_engine.h b/src/mongo/db/storage/mmap_v1/mmap_v1_engine.h
index afc3472cbcf..92ab5bfc6f5 100644
--- a/src/mongo/db/storage/mmap_v1/mmap_v1_engine.h
+++ b/src/mongo/db/storage/mmap_v1/mmap_v1_engine.h
@@ -104,7 +104,7 @@ public:
void setJournalListener(JournalListener* jl) final;
- Timestamp getAllCommittedTimestamp(OperationContext* opCtx) const override {
+ Timestamp getAllCommittedTimestamp() const override {
MONGO_UNREACHABLE;
}
diff --git a/src/mongo/db/storage/mobile/mobile_kv_engine.h b/src/mongo/db/storage/mobile/mobile_kv_engine.h
index c6c577d5c08..a87da11ad31 100644
--- a/src/mongo/db/storage/mobile/mobile_kv_engine.h
+++ b/src/mongo/db/storage/mobile/mobile_kv_engine.h
@@ -116,7 +116,7 @@ public:
_journalListener = jl;
}
- virtual Timestamp getAllCommittedTimestamp(OperationContext* opCtx) const override {
+ virtual Timestamp getAllCommittedTimestamp() const override {
MONGO_UNREACHABLE;
}
diff --git a/src/mongo/db/storage/storage_engine.h b/src/mongo/db/storage/storage_engine.h
index e7c47bae900..64f19f5dadf 100644
--- a/src/mongo/db/storage/storage_engine.h
+++ b/src/mongo/db/storage/storage_engine.h
@@ -403,7 +403,7 @@ public:
* locking must provide an implementation. Other storage engines may provide a no-op
* implementation.
*/
- virtual Timestamp getAllCommittedTimestamp(OperationContext* opCtx) const = 0;
+ virtual Timestamp getAllCommittedTimestamp() const = 0;
};
} // namespace mongo
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
index d9709c2a2dc..d90ad9d2e23 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
@@ -1243,8 +1243,8 @@ StatusWith<Timestamp> WiredTigerKVEngine::recoverToStableTimestamp(OperationCont
return {stableTimestamp};
}
-Timestamp WiredTigerKVEngine::getAllCommittedTimestamp(OperationContext* opCtx) const {
- return Timestamp(_oplogManager->fetchAllCommittedValue(opCtx));
+Timestamp WiredTigerKVEngine::getAllCommittedTimestamp() const {
+ return Timestamp(_oplogManager->fetchAllCommittedValue(_conn));
}
boost::optional<Timestamp> WiredTigerKVEngine::getRecoveryTimestamp() const {
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
index 408efcea8f1..6cf7e3c14af 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
@@ -187,7 +187,7 @@ public:
*/
virtual boost::optional<Timestamp> getLastStableCheckpointTimestamp() const override;
- virtual Timestamp getAllCommittedTimestamp(OperationContext* opCtx) const override;
+ virtual Timestamp getAllCommittedTimestamp() const override;
bool supportsReadConcernSnapshot() const final;
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.cpp
index 19b37e4274a..6aee81d30e6 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.cpp
@@ -207,7 +207,7 @@ void WiredTigerOplogManager::_oplogJournalThreadLoop(
_opsWaitingForJournal = false;
lk.unlock();
- const uint64_t newTimestamp = _fetchAllCommittedValue(sessionCache->conn());
+ const uint64_t newTimestamp = fetchAllCommittedValue(sessionCache->conn());
// The newTimestamp may actually go backward during secondary batch application,
// where we commit data file changes separately from oplog changes, so ignore
@@ -249,11 +249,7 @@ void WiredTigerOplogManager::_setOplogReadTimestamp(WithLock, uint64_t newTimest
LOG(2) << "setting new oplogReadTimestamp: " << newTimestamp;
}
-uint64_t WiredTigerOplogManager::fetchAllCommittedValue(OperationContext* opCtx) {
- return _fetchAllCommittedValue(WiredTigerRecoveryUnit::get(opCtx)->getSessionCache()->conn());
-}
-
-uint64_t WiredTigerOplogManager::_fetchAllCommittedValue(WT_CONNECTION* conn) {
+uint64_t WiredTigerOplogManager::fetchAllCommittedValue(WT_CONNECTION* conn) {
// Fetch the latest all_committed value from the storage engine. This value will be a
// timestamp that has no holes (uncommitted transactions with lower timestamps) behind it.
char buf[(2 * 8 /*bytes in hex*/) + 1 /*nul terminator*/];
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.h b/src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.h
index cfa444d0b37..435b6b31f20 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.h
@@ -80,7 +80,7 @@ public:
// Returns the all committed timestamp. All transactions with timestamps earlier than the
// all committed timestamp are committed.
- uint64_t fetchAllCommittedValue(OperationContext* opCtx);
+ uint64_t fetchAllCommittedValue(WT_CONNECTION* conn);
private:
void _oplogJournalThreadLoop(WiredTigerSessionCache* sessionCache,
@@ -88,8 +88,6 @@ private:
void _setOplogReadTimestamp(WithLock, uint64_t newTimestamp);
- uint64_t _fetchAllCommittedValue(WT_CONNECTION* conn);
-
stdx::thread _oplogJournalThread;
mutable stdx::mutex _oplogVisibilityStateMutex;
mutable stdx::condition_variable