diff options
author | Sergi Mateo Bellido <sergi.mateo-bellido@mongodb.com> | 2022-05-26 13:12:35 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2023-03-27 16:47:29 +0000 |
commit | a7d14387f1c04e37b6b8b3838be5f212ba2b54a0 (patch) | |
tree | c492b4c583f373a7279a561cd3a17c7ad086d53f | |
parent | 2e2da0ba453e68c5723e5f34efa146621d0639fe (diff) | |
download | mongo-a7d14387f1c04e37b6b8b3838be5f212ba2b54a0.tar.gz |
SERVER-66542 Unifying paths on the CatalogCache lookup function
Before this change there was an early-exit path that wasn't updating the
stats neither logging a line.
(cherry picked from commit 46a8e36aade47b36837d89cccfa41e28ddad272c)
-rw-r--r-- | src/mongo/s/catalog_cache.cpp | 183 |
1 files changed, 94 insertions, 89 deletions
diff --git a/src/mongo/s/catalog_cache.cpp b/src/mongo/s/catalog_cache.cpp index 53987d307cc..32d61b5de85 100644 --- a/src/mongo/s/catalog_cache.cpp +++ b/src/mongo/s/catalog_cache.cpp @@ -74,6 +74,93 @@ const OperationContext::Decoration<bool> operationShouldBlockBehindCatalogCacheR const OperationContext::Decoration<bool> operationBlockedBehindCatalogCacheRefresh = OperationContext::declareDecoration<bool>(); +std::shared_ptr<RoutingTableHistory> createUpdatedRoutingTableHistory( + OperationContext* opCtx, + const NamespaceString& nss, + bool isIncremental, + const RoutingTableHistoryValueHandle& existingHistory, + const CatalogCacheLoader::CollectionAndChangedChunks& collectionAndChunks) { + // If a refresh doesn't find new information -> re-use the existing RoutingTableHistory. + // Do not re-use the existing routing table if there was a metadata format change. + if (isIncremental && collectionAndChunks.changedChunks.size() == 1 && + collectionAndChunks.changedChunks[0].getVersion() == existingHistory->optRt->getVersion() && + collectionAndChunks.changedChunks[0].getVersion().getTimestamp().is_initialized() == + existingHistory->optRt->getVersion().getTimestamp().is_initialized()) { + + const auto& newVersion = collectionAndChunks.changedChunks[0].getVersion(); + tassert(7032310, + fmt::format("allowMigrations field of collection '{}' changed without changing the " + "collection version {}. Old value: {}, new value: {}", + nss.toString(), + newVersion.toString(), + existingHistory->optRt->allowMigrations(), + collectionAndChunks.allowMigrations), + collectionAndChunks.allowMigrations == existingHistory->optRt->allowMigrations()); + + const auto& oldReshardingFields = existingHistory->optRt->getReshardingFields(); + const auto& newReshardingFields = collectionAndChunks.reshardingFields; + tassert(7032311, + fmt::format("reshardingFields field of collection '{}' changed without changing " + "the collection version {}. Old value: {}, new value: {}", + nss.toString(), + newVersion.toString(), + oldReshardingFields->toBSON().toString(), + newReshardingFields->toBSON().toString()), + [&] { + if (oldReshardingFields && newReshardingFields) + return oldReshardingFields->toBSON().woCompare( + newReshardingFields->toBSON()) == 0; + else + return !oldReshardingFields && !newReshardingFields; + }()); + + return existingHistory->optRt; + } + + auto newRoutingHistory = [&] { + // If we have routing info already and it's for the same collection epoch, we're + // updating. Otherwise, we're making a whole new routing table. + if (isIncremental && + existingHistory->optRt->getVersion().epoch() == collectionAndChunks.epoch) { + if (existingHistory->optRt->getVersion().getTimestamp().is_initialized() != + collectionAndChunks.creationTime.is_initialized()) { + return existingHistory->optRt + ->makeUpdatedReplacingTimestamp(collectionAndChunks.creationTime) + .makeUpdated(collectionAndChunks.reshardingFields, + collectionAndChunks.allowMigrations, + collectionAndChunks.changedChunks); + } else { + return existingHistory->optRt->makeUpdated(collectionAndChunks.reshardingFields, + collectionAndChunks.allowMigrations, + collectionAndChunks.changedChunks); + } + } + + auto defaultCollator = [&]() -> std::unique_ptr<CollatorInterface> { + if (!collectionAndChunks.defaultCollation.isEmpty()) { + // The collation should have been validated upon collection creation + return uassertStatusOK(CollatorFactoryInterface::get(opCtx->getServiceContext()) + ->makeFromBSON(collectionAndChunks.defaultCollation)); + } + return nullptr; + }(); + + return RoutingTableHistory::makeNew(nss, + collectionAndChunks.uuid, + KeyPattern(collectionAndChunks.shardKeyPattern), + std::move(defaultCollator), + collectionAndChunks.shardKeyIsUnique, + collectionAndChunks.epoch, + collectionAndChunks.creationTime, + collectionAndChunks.timeseriesFields, + std::move(collectionAndChunks.reshardingFields), + collectionAndChunks.allowMigrations, + collectionAndChunks.changedChunks); + }(); + + return std::make_shared<RoutingTableHistory>(std::move(newRoutingHistory)); +} + } // namespace CachedDatabaseInfo::CachedDatabaseInfo(DatabaseTypeValueHandle&& dbt) : _dbt(std::move(dbt)){}; @@ -585,103 +672,22 @@ CatalogCache::CollectionCache::LookupResult CatalogCache::CollectionCache::_look auto collectionAndChunks = _catalogCacheLoader.getChunksSince(nss, lookupVersion).get(); - // If a refresh doesn't find new information -> re-use the existing RoutingTableHistory. - // Do not re-use the existing routing table if there was a metadata format change. - if (isIncremental && collectionAndChunks.changedChunks.size() == 1 && - collectionAndChunks.changedChunks[0].getVersion() == - existingHistory->optRt->getVersion() && - collectionAndChunks.changedChunks[0].getVersion().getTimestamp().is_initialized() == - existingHistory->optRt->getVersion().getTimestamp().is_initialized()) { - - const auto& newVersion = collectionAndChunks.changedChunks[0].getVersion(); - tassert( - 7032310, - fmt::format("allowMigrations field of collection '{}' changed without changing the " - "collection version {}. Old value: {}, new value: {}", - nss.toString(), - newVersion.toString(), - existingHistory->optRt->allowMigrations(), - collectionAndChunks.allowMigrations), - collectionAndChunks.allowMigrations == existingHistory->optRt->allowMigrations()); - - const auto& oldReshardingFields = existingHistory->optRt->getReshardingFields(); - const auto& newReshardingFields = collectionAndChunks.reshardingFields; - tassert( - 7032311, - fmt::format("reshardingFields field of collection '{}' changed without changing " - "the collection version {}. Old value: {}, new value: {}", - nss.toString(), - newVersion.toString(), - oldReshardingFields->toBSON().toString(), - newReshardingFields->toBSON().toString()), - [&] { - if (oldReshardingFields && newReshardingFields) - return oldReshardingFields->toBSON().woCompare( - newReshardingFields->toBSON()) == 0; - else - return !oldReshardingFields && !newReshardingFields; - }()); - - // Despite we didn't find new info, we must update the time of this entry on the cache - newComparableVersion.setChunkVersion(newVersion); - return LookupResult(OptionalRoutingTableHistory(existingHistory->optRt), - std::move(newComparableVersion)); - } - - auto newRoutingHistory = [&] { - // If we have routing info already and it's for the same collection epoch, we're - // updating. Otherwise, we're making a whole new routing table. - if (isIncremental && - existingHistory->optRt->getVersion().epoch() == collectionAndChunks.epoch) { - if (existingHistory->optRt->getVersion().getTimestamp().is_initialized() != - collectionAndChunks.creationTime.is_initialized()) { - return existingHistory->optRt - ->makeUpdatedReplacingTimestamp(collectionAndChunks.creationTime) - .makeUpdated(collectionAndChunks.reshardingFields, - collectionAndChunks.allowMigrations, - collectionAndChunks.changedChunks); - } else { - return existingHistory->optRt->makeUpdated(collectionAndChunks.reshardingFields, - collectionAndChunks.allowMigrations, - collectionAndChunks.changedChunks); - } - } - - auto defaultCollator = [&]() -> std::unique_ptr<CollatorInterface> { - if (!collectionAndChunks.defaultCollation.isEmpty()) { - // The collation should have been validated upon collection creation - return uassertStatusOK( - CollatorFactoryInterface::get(opCtx->getServiceContext()) - ->makeFromBSON(collectionAndChunks.defaultCollation)); - } - return nullptr; - }(); - - return RoutingTableHistory::makeNew(nss, - collectionAndChunks.uuid, - KeyPattern(collectionAndChunks.shardKeyPattern), - std::move(defaultCollator), - collectionAndChunks.shardKeyIsUnique, - collectionAndChunks.epoch, - collectionAndChunks.creationTime, - collectionAndChunks.timeseriesFields, - std::move(collectionAndChunks.reshardingFields), - collectionAndChunks.allowMigrations, - collectionAndChunks.changedChunks); - }(); + std::shared_ptr<RoutingTableHistory> newRoutingHistory = createUpdatedRoutingTableHistory( + opCtx, nss, isIncremental, existingHistory, collectionAndChunks); + invariant(newRoutingHistory); - newRoutingHistory.setAllShardsRefreshed(); + newRoutingHistory->setAllShardsRefreshed(); // Check that the shards all match with what is on the config server std::set<ShardId> shardIds; - newRoutingHistory.getAllShardIds(&shardIds); + newRoutingHistory->getAllShardIds(&shardIds); for (const auto& shardId : shardIds) { uassertStatusOKWithContext(Grid::get(opCtx)->shardRegistry()->getShard(opCtx, shardId), str::stream() << "Collection " << nss << " references shard which does not exist"); } - const ChunkVersion newVersion = newRoutingHistory.getVersion(); + const ChunkVersion newVersion = newRoutingHistory->getVersion(); newComparableVersion.setChunkVersion(newVersion); LOGV2_FOR_CATALOG_REFRESH(4619901, @@ -694,8 +700,7 @@ CatalogCache::CollectionCache::LookupResult CatalogCache::CollectionCache::_look "duration"_attr = Milliseconds(t.millis())); _updateRefreshesStats(isIncremental, false); - return LookupResult(OptionalRoutingTableHistory(std::make_shared<RoutingTableHistory>( - std::move(newRoutingHistory))), + return LookupResult(OptionalRoutingTableHistory(std::move(newRoutingHistory)), std::move(newComparableVersion)); } catch (const DBException& ex) { _stats.countFailedRefreshes.addAndFetch(1); |