diff --git a/src/mongo/s/client/shard_registry.cpp b/src/mongo/s/client/shard_registry.cpp index 75a30f77e74..ba7cf7334a8 100644 --- a/src/mongo/s/client/shard_registry.cpp +++ b/src/mongo/s/client/shard_registry.cpp @@ -169,7 +169,7 @@ ShardRegistry::Cache::LookupResult ShardRegistry::_lookup(OperationContext* opCt auto lastForcedReloadIncrement = _forceReloadIncrement.load(); LOGV2_DEBUG(4620250, - 2, + 1, "Starting ShardRegistry::_lookup", "cachedData"_attr = cachedData ? cachedData->toBSON() : BSONObj{}, "cachedData.getTime()"_attr = cachedData ? cachedData.getTime() : Time{}, @@ -184,7 +184,7 @@ ShardRegistry::Cache::LookupResult ShardRegistry::_lookup(OperationContext* opCt if (!cachedData) { auto [reloadedData, maxTopologyTime] = ShardRegistryData::createFromCatalogClient(opCtx, _shardFactory.get()); - + LOGV2_INFO(9112102, "In case 1: Got data from configsvr"); return {std::move(reloadedData), std::move(maxTopologyTime), {}}; } else if (timeInStore.topologyTime > cachedData.getTime().topologyTime || lastForcedReloadIncrement > cachedData.getTime().forceReloadIncrement) { @@ -193,9 +193,10 @@ ShardRegistry::Cache::LookupResult ShardRegistry::_lookup(OperationContext* opCt auto [mergedData, removedShards] = ShardRegistryData::mergeExisting(*cachedData, reloadedData); - + LOGV2_INFO(9112103, "In case 2: Got data from configsvr"); return {std::move(mergedData), std::move(maxTopologyTime), std::move(removedShards)}; } else { + LOGV2_INFO(9112104, "In case 3: No lookup"); return {*cachedData, cachedData.getTime().topologyTime, {}}; } }(); @@ -235,7 +236,7 @@ ShardRegistry::Cache::LookupResult ShardRegistry::_lookup(OperationContext* opCt Time returnTime{returnTopologyTime, rsmIncrementForConnStrings, lastForcedReloadIncrement}; LOGV2_DEBUG(4620251, - 2, + 1, "Finished ShardRegistry::_lookup", "returnData"_attr = returnData.toBSON(), "returnTime"_attr = returnTime); @@ -580,8 +581,12 @@ SharedSemiFuture ShardRegistry::_getDataAsync auto now = VectorClock::get(_service)->getTime(); // The topologyTime should be advanced to the gossiped topologyTime. Timestamp topologyTime = now.topologyTime().asTimestamp(); - _cache->advanceTimeInStore( - _kSingleton, Time(topologyTime, _rsmIncrement.load(), _forceReloadIncrement.load())); + auto time = Time(topologyTime, _rsmIncrement.load(), _forceReloadIncrement.load()); + if (_cache->advanceTimeInStore(_kSingleton, time)) { + LOGV2_INFO(9112100, "Got True from advanceTimeInStore: ", "Time: "_attr = time.toString()); + } else { + LOGV2_INFO(9112101, "Got False from advanceTimeInStore: ", "Time: "_attr = time.toString()); + } return _cache->acquireAsync(_kSingleton, CacheCausalConsistency::kLatestKnown); } @@ -929,4 +934,34 @@ BSONObj ShardRegistryData::toBSON() const { return bob.obj(); } +bool ShardRegistry::Time::operator>(const Time& other) const { + + // SERVER-56950: When setFCV(v4.4) overlaps with a ShardRegistry reload, + // the ShardRegistry can fall into an infinite loop of lookups + bool cond = ((!topologyTime.isNull() && !other.topologyTime.isNull() && + topologyTime > other.topologyTime) || + (other.topologyTime.isNull() && !topologyTime.isNull()) || + rsmIncrement > other.rsmIncrement || + forceReloadIncrement > other.forceReloadIncrement); + LOGV2_INFO( + 9112101, "Time this > other: ", "eval: "_attr = cond, "this: "_attr = this->toString(), "other: "_attr = other.toString()); + return cond; +} + +bool ShardRegistry::Time::operator<(const Time& other) const { + + bool cond = ((!topologyTime.isNull() && !other.topologyTime.isNull() && + topologyTime < other.topologyTime) || + (!other.topologyTime.isNull() && topologyTime.isNull()) || + rsmIncrement < other.rsmIncrement || + forceReloadIncrement < other.forceReloadIncrement); + LOGV2_INFO(9112102, + "Time this < other: ", + "eval: "_attr = cond, + "this: "_attr = this->toString(), + "other: "_attr = other.toString()); + return cond; +}; + } // namespace mongo + diff --git a/src/mongo/s/client/shard_registry.h b/src/mongo/s/client/shard_registry.h index 1427cd8d2f7..f81fc2680f8 100644 --- a/src/mongo/s/client/shard_registry.h +++ b/src/mongo/s/client/shard_registry.h @@ -401,23 +401,11 @@ private: bool operator!=(const Time& other) const { return !(*this == other); } - bool operator>(const Time& other) const { - return ((!topologyTime.isNull() && !other.topologyTime.isNull() && - topologyTime > other.topologyTime) || - (other.topologyTime.isNull() && !topologyTime.isNull()) || - rsmIncrement > other.rsmIncrement || - forceReloadIncrement > other.forceReloadIncrement); - }; + bool operator>(const Time& other) const; bool operator>=(const Time& other) const { return (*this > other) || (*this == other); } - bool operator<(const Time& other) const { - return ((!topologyTime.isNull() && !other.topologyTime.isNull() && - topologyTime < other.topologyTime) || - (!other.topologyTime.isNull() && topologyTime.isNull()) || - rsmIncrement < other.rsmIncrement || - forceReloadIncrement < other.forceReloadIncrement); - }; + bool operator<(const Time& other) const;; bool operator<=(const Time& other) const { return !(*this > other); }