diff options
author | Esha Maharishi <esha.maharishi@mongodb.com> | 2018-08-27 14:13:00 -0400 |
---|---|---|
committer | Esha Maharishi <esha.maharishi@mongodb.com> | 2018-08-27 16:21:38 -0400 |
commit | e338bbd75f4697a9ec29f097436358282d75c5b3 (patch) | |
tree | ae8f31815fbd83782a36c9c09e1abac013139d6f /src/mongo/db | |
parent | 2aede7ad2fce2616e4140f2ae398e4e570c84703 (diff) | |
download | mongo-e338bbd75f4697a9ec29f097436358282d75c5b3.tar.gz |
SERVER-36755 CollectionLock acquisition in shard_filtering_metadata_refresh.cpp can cause server to terminate on stepdown (2/2)
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/s/shard_filtering_metadata_refresh.cpp | 58 | ||||
-rw-r--r-- | src/mongo/db/s/shard_filtering_metadata_refresh.h | 9 | ||||
-rw-r--r-- | src/mongo/db/service_entry_point_common.cpp | 5 |
3 files changed, 39 insertions, 33 deletions
diff --git a/src/mongo/db/s/shard_filtering_metadata_refresh.cpp b/src/mongo/db/s/shard_filtering_metadata_refresh.cpp index 0f284f1f6dd..7a757a76015 100644 --- a/src/mongo/db/s/shard_filtering_metadata_refresh.cpp +++ b/src/mongo/db/s/shard_filtering_metadata_refresh.cpp @@ -89,6 +89,29 @@ void onShardVersionMismatch(OperationContext* opCtx, forceShardFilteringMetadataRefresh(opCtx, nss, forceRefreshFromThisThread); } +void onDbVersionMismatch(OperationContext* opCtx, + const StringData dbName, + const DatabaseVersion& clientDbVersion, + const boost::optional<DatabaseVersion>& serverDbVersion) { + invariant(!opCtx->lockState()->isLocked()); + invariant(!opCtx->getClient()->isInDirectClient()); + + auto const shardingState = ShardingState::get(opCtx); + invariant(shardingState->canAcceptShardedCommands()); + + if (serverDbVersion && serverDbVersion->getUuid() == clientDbVersion.getUuid() && + serverDbVersion->getLastMod() >= clientDbVersion.getLastMod()) { + // The client was stale; do not trigger server-side refresh. + return; + } + + // TODO SERVER-33773 if the 'waitForMovePrimaryCriticalSection' flag is set on the + // OperationShardingState, wait for the movePrimary critical section to complete before + // attempting a refresh. + + forceDatabaseRefresh(opCtx, dbName); +} + } // namespace Status onShardVersionMismatchNoExcept(OperationContext* opCtx, @@ -167,37 +190,18 @@ ChunkVersion forceShardFilteringMetadataRefresh(OperationContext* opCtx, return css->getMetadata(opCtx)->getShardVersion(); } -void onDbVersionMismatch(OperationContext* opCtx, - const StringData dbName, - const DatabaseVersion& clientDbVersion, - const boost::optional<DatabaseVersion>& serverDbVersion) noexcept { - invariant(!opCtx->lockState()->isLocked()); - invariant(!opCtx->getClient()->isInDirectClient()); - - auto const shardingState = ShardingState::get(opCtx); - invariant(shardingState->canAcceptShardedCommands()); - - if (serverDbVersion && serverDbVersion->getUuid() == clientDbVersion.getUuid() && - serverDbVersion->getLastMod() >= clientDbVersion.getLastMod()) { - // The client was stale; do not trigger server-side refresh. - return; - } - - try { - // TODO SERVER-33773 if the 'waitForMovePrimaryCriticalSection' flag is set on the - // OperationShardingState, wait for the movePrimary critical section to complete before - // attempting a refresh. - } catch (const DBException& ex) { - log() << "Failed to wait for movePrimary critical section to complete " - << causedBy(redact(ex)); - return; - } - +Status onDbVersionMismatchNoExcept( + OperationContext* opCtx, + const StringData dbName, + const DatabaseVersion& clientDbVersion, + const boost::optional<DatabaseVersion>& serverDbVersion) noexcept { try { - forceDatabaseRefresh(opCtx, dbName); + onDbVersionMismatch(opCtx, dbName, clientDbVersion, serverDbVersion); + return Status::OK(); } catch (const DBException& ex) { log() << "Failed to refresh databaseVersion for database " << dbName << causedBy(redact(ex)); + return ex.toStatus(); } } diff --git a/src/mongo/db/s/shard_filtering_metadata_refresh.h b/src/mongo/db/s/shard_filtering_metadata_refresh.h index a0397726090..d4823d9d9c6 100644 --- a/src/mongo/db/s/shard_filtering_metadata_refresh.h +++ b/src/mongo/db/s/shard_filtering_metadata_refresh.h @@ -75,10 +75,11 @@ ChunkVersion forceShardFilteringMetadataRefresh(OperationContext* opCtx, * Invalidates the cached database version, schedules a refresh of the database info, waits for the * refresh to complete, and updates the cached database version. */ -void onDbVersionMismatch(OperationContext* opCtx, - const StringData dbName, - const DatabaseVersion& clientDbVersion, - const boost::optional<DatabaseVersion>& serverDbVersion) noexcept; +Status onDbVersionMismatchNoExcept( + OperationContext* opCtx, + const StringData dbName, + const DatabaseVersion& clientDbVersion, + const boost::optional<DatabaseVersion>& serverDbVersion) noexcept; void forceDatabaseRefresh(OperationContext* opCtx, const StringData dbName); diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp index 23f55f61554..7710cd8a797 100644 --- a/src/mongo/db/service_entry_point_common.cpp +++ b/src/mongo/db/service_entry_point_common.cpp @@ -893,8 +893,9 @@ void execCommandDatabase(OperationContext* opCtx, } } else if (auto sce = e.extraInfo<StaleDbRoutingVersion>()) { if (!opCtx->getClient()->isInDirectClient()) { - onDbVersionMismatch( - opCtx, sce->getDb(), sce->getVersionReceived(), sce->getVersionWanted()); + onDbVersionMismatchNoExcept( + opCtx, sce->getDb(), sce->getVersionReceived(), sce->getVersionWanted()) + .ignore(); } } else if (auto cannotImplicitCreateCollInfo = e.extraInfo<CannotImplicitlyCreateCollectionInfo>()) { |