diff options
author | Judah Schvimer <judah@mongodb.com> | 2018-05-08 14:53:49 -0400 |
---|---|---|
committer | Judah Schvimer <judah@mongodb.com> | 2018-05-15 13:59:11 -0400 |
commit | 689d52131f6ac1a446fe1b93647b11d0329c629c (patch) | |
tree | 42b715f59ee4b402ac12fad10c2e8ebc59fbe9ee /src | |
parent | 6d2de545a7cfcf4ab23dcf73426a1d50896d6d0c (diff) | |
download | mongo-689d52131f6ac1a446fe1b93647b11d0329c629c.tar.gz |
SERVER-34895 only set stable timestamp to timestamps in oplog
Diffstat (limited to 'src')
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 |