diff options
-rw-r--r-- | src/mongo/db/keys_collection_manager.cpp | 27 | ||||
-rw-r--r-- | src/mongo/db/keys_collection_manager.h | 3 | ||||
-rw-r--r-- | src/mongo/db/logical_time_validator_test.cpp | 18 | ||||
-rw-r--r-- | src/mongo/db/repl/rs_rollback.cpp | 5 |
4 files changed, 44 insertions, 9 deletions
diff --git a/src/mongo/db/keys_collection_manager.cpp b/src/mongo/db/keys_collection_manager.cpp index 889b822477c..c3c66b2b2c0 100644 --- a/src/mongo/db/keys_collection_manager.cpp +++ b/src/mongo/db/keys_collection_manager.cpp @@ -172,6 +172,9 @@ void KeysCollectionManager::enableKeyGenerator(OperationContext* opCtx, bool doE return StatusWith<KeysCollectionDocument>(keyGenerationStatus); } + // Set a small deadline so the refresh will not wait forever to satisfy readConcern. + opCtx->setDeadlineAfterNowBy(Milliseconds(500)); + // An error encountered by the keyGenerator should not prevent refreshing the cache auto cacheRefreshStatus = _keysCache.refresh(opCtx); @@ -182,8 +185,11 @@ void KeysCollectionManager::enableKeyGenerator(OperationContext* opCtx, bool doE return cacheRefreshStatus; }); } else { - _refresher.switchFunc( - opCtx, [this](OperationContext* opCtx) { return _keysCache.refresh(opCtx); }); + _refresher.switchFunc(opCtx, [this](OperationContext* opCtx) { + // Set a small deadline so the refresh will not wait forever to satisfy readConcern. + opCtx->setDeadlineAfterNowBy(Milliseconds(500)); + return _keysCache.refresh(opCtx); + }); } } @@ -195,7 +201,7 @@ void KeysCollectionManager::PeriodicRunner::refreshNow(OperationContext* opCtx) auto refreshRequest = [this]() { stdx::lock_guard<stdx::mutex> lk(_mutex); - if (_inShutdown) { + if (_isStopping) { uasserted(ErrorCodes::ShutdownInProgress, "aborting keys cache refresh because node is shutting down"); } @@ -229,7 +235,7 @@ void KeysCollectionManager::PeriodicRunner::_doPeriodicRefresh(ServiceContext* s { stdx::lock_guard<stdx::mutex> lock(_mutex); - if (_inShutdown) { + if (_isStopping) { break; } @@ -242,7 +248,6 @@ void KeysCollectionManager::PeriodicRunner::_doPeriodicRefresh(ServiceContext* s { auto opCtx = cc().makeOperationContext(); - auto latestKeyStatusWith = (*doRefresh)(opCtx.get()); if (latestKeyStatusWith.getStatus().isOK()) { errorCount = 0; @@ -285,7 +290,7 @@ void KeysCollectionManager::PeriodicRunner::_doPeriodicRefresh(ServiceContext* s _refreshRequest.reset(); } - if (_inShutdown) { + if (_isStopping) { break; } @@ -324,7 +329,7 @@ void KeysCollectionManager::PeriodicRunner::start(ServiceContext* service, Milliseconds refreshInterval) { stdx::lock_guard<stdx::mutex> lock(_mutex); invariant(!_backgroundThread.joinable()); - invariant(!_inShutdown); + invariant(!_isStopping); _backgroundThread = stdx::thread([this, service, threadName, refreshInterval] { _doPeriodicRefresh(service, threadName, refreshInterval); @@ -338,11 +343,17 @@ void KeysCollectionManager::PeriodicRunner::stop() { return; } - _inShutdown = true; + _isStopping = true; _refreshNeededCV.notify_all(); } _backgroundThread.join(); + + { + stdx::lock_guard<stdx::mutex> lock(_mutex); + invariant(!_backgroundThread.joinable()); + _isStopping = false; + } } bool KeysCollectionManager::PeriodicRunner::hasSeenKeys() { diff --git a/src/mongo/db/keys_collection_manager.h b/src/mongo/db/keys_collection_manager.h index 5826e2228ee..e0138cf2e32 100644 --- a/src/mongo/db/keys_collection_manager.h +++ b/src/mongo/db/keys_collection_manager.h @@ -173,7 +173,8 @@ private: std::shared_ptr<RefreshFunc> _doRefresh; bool _hasSeenKeys = false; - bool _inShutdown = false; + // In the process of stopping this runner. + bool _isStopping = false; }; /** diff --git a/src/mongo/db/logical_time_validator_test.cpp b/src/mongo/db/logical_time_validator_test.cpp index 461689a61e6..70cfe1a76f7 100644 --- a/src/mongo/db/logical_time_validator_test.cpp +++ b/src/mongo/db/logical_time_validator_test.cpp @@ -181,5 +181,23 @@ TEST_F(LogicalTimeValidatorTest, ShouldGossipLogicalTimeIsFalseUntilKeysAreFound ASSERT_OK(validator()->validate(operationContext(), newTime)); } +TEST_F(LogicalTimeValidatorTest, CanSignTimesAfterReset) { + validator()->enableKeyGenerator(operationContext(), true); + + LogicalTime t1(Timestamp(10, 0)); + auto newTime = validator()->trySignLogicalTime(t1); + + ASSERT_EQ(t1.asTimestamp(), newTime.getTime().asTimestamp()); + ASSERT_TRUE(newTime.getProof()); + + validator()->resetKeyManagerCache(operationContext()->getServiceContext()); + + LogicalTime t2(Timestamp(20, 0)); + auto newTime2 = validator()->trySignLogicalTime(t2); + + ASSERT_EQ(t2.asTimestamp(), newTime2.getTime().asTimestamp()); + ASSERT_TRUE(newTime2.getProof()); +} + } // unnamed namespace } // namespace mongo diff --git a/src/mongo/db/repl/rs_rollback.cpp b/src/mongo/db/repl/rs_rollback.cpp index 5b76eb1c42f..bf993918cec 100644 --- a/src/mongo/db/repl/rs_rollback.cpp +++ b/src/mongo/db/repl/rs_rollback.cpp @@ -53,6 +53,7 @@ #include "mongo/db/dbhelpers.h" #include "mongo/db/exec/working_set_common.h" #include "mongo/db/logical_session_id.h" +#include "mongo/db/logical_time_validator.h" #include "mongo/db/ops/delete.h" #include "mongo/db/ops/update.h" #include "mongo/db/ops/update_lifecycle_impl.h" @@ -1421,6 +1422,10 @@ void rollback_internal::syncFixUp(OperationContext* opCtx, SessionCatalog::get(opCtx)->invalidateSessions(opCtx, boost::none); } + if (auto validator = LogicalTimeValidator::get(opCtx)) { + validator->resetKeyManagerCache(opCtx->getClient()->getServiceContext()); + } + // Reload the lastAppliedOpTime and lastDurableOpTime value in the replcoord and the // lastAppliedHash value in bgsync to reflect our new last op. The rollback common point does // not necessarily represent a consistent database state. For example, on a secondary, we may |