diff options
| author | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-11 15:07:35 -0300 |
|---|---|---|
| committer | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-11 15:07:35 -0300 |
| commit | 4cb8841196d0625dfa3825aa326f071cd27c7b8b (patch) | |
| tree | 1682a647d4463397c119183369ae6f750d5fdcff /src/mongo/s/chunk_manager_targeter.cpp | |
| parent | aa03c6362cbaa767638e6eed9b031d86dd2643d1 (diff) | |
| parent | 8f0827553e09872941945a093b647a4211a9db7f (diff) | |
Update upstream source from tag 'upstream/6.0.0'master
Update to upstream version '6.0.0'
with Debian dir 5604a80ec1c96ca76f25f40d78e6ef855abec322
Diffstat (limited to 'src/mongo/s/chunk_manager_targeter.cpp')
| -rw-r--r-- | src/mongo/s/chunk_manager_targeter.cpp | 99 |
1 files changed, 35 insertions, 64 deletions
diff --git a/src/mongo/s/chunk_manager_targeter.cpp b/src/mongo/s/chunk_manager_targeter.cpp index f750554ea56..bdb386420c6 100644 --- a/src/mongo/s/chunk_manager_targeter.cpp +++ b/src/mongo/s/chunk_manager_targeter.cpp @@ -43,8 +43,6 @@ #include "mongo/db/query/canonical_query.h" #include "mongo/db/query/collation/collation_index_key.h" #include "mongo/db/query/collation/collator_factory_interface.h" -#include "mongo/db/stats/counters.h" -#include "mongo/db/timeseries/metadata.h" #include "mongo/db/timeseries/timeseries_constants.h" #include "mongo/db/timeseries/timeseries_options.h" #include "mongo/db/timeseries/timeseries_update_delete_util.h" @@ -65,8 +63,6 @@ namespace mongo { namespace { -MONGO_FAIL_POINT_DEFINE(waitForDatabaseToBeDropped); - enum CompareResult { CompareResult_Unknown, CompareResult_GTE, CompareResult_LT }; constexpr auto kIdFieldName = "_id"_sd; @@ -230,8 +226,6 @@ bool isMetadataDifferent(const ChunkManager& managerA, const ChunkManager& manag } // namespace -const size_t ChunkManagerTargeter::kMaxDatabaseCreationAttempts = 3; - ChunkManagerTargeter::ChunkManagerTargeter(OperationContext* opCtx, const NamespaceString& nss, boost::optional<OID> targetEpoch) @@ -245,45 +239,13 @@ ChunkManagerTargeter::ChunkManagerTargeter(OperationContext* opCtx, * user request is on the view namespace, we implicity tranform the request to the buckets namepace. */ ChunkManager ChunkManagerTargeter::_init(OperationContext* opCtx, bool refresh) { - const auto createDatabaseAndGetRoutingInfo = [&opCtx, &refresh](const NamespaceString& nss) { - size_t attempts = 1; - while (true) { - try { - cluster::createDatabase(opCtx, nss.db()); - - if (refresh) { - uassertStatusOK( - Grid::get(opCtx)->catalogCache()->getCollectionRoutingInfoWithRefresh(opCtx, - nss)); - } - - if (MONGO_unlikely(waitForDatabaseToBeDropped.shouldFail())) { - LOGV2(8314600, "Hanging due to waitForDatabaseToBeDropped fail point"); - waitForDatabaseToBeDropped.pauseWhileSet(opCtx); - } - - return uassertStatusOK(getCollectionRoutingInfoForTxnCmd(opCtx, nss)); - } catch (const ExceptionFor<ErrorCodes::NamespaceNotFound>&) { - LOGV2_INFO(8314601, - "Failed initialization of routing info because the database has been " - "concurrently dropped", - logAttrs(nss), - "attemptNumber"_attr = attempts, - "maxAttempts"_attr = kMaxDatabaseCreationAttempts); - - if (attempts++ >= kMaxDatabaseCreationAttempts) { - // The maximum number of attempts has been reached, so the procedure fails as it - // could be a logical error. At this point, it is unlikely that the error is - // caused by concurrent drop database operations. - throw; - } - } - } - }; + cluster::createDatabase(opCtx, _nss.db()); - createDatabaseAndGetRoutingInfo(_nss); - - auto cm = createDatabaseAndGetRoutingInfo(_nss); + if (refresh) { + uassertStatusOK( + Grid::get(opCtx)->catalogCache()->getCollectionRoutingInfoWithRefresh(opCtx, _nss)); + } + auto cm = uassertStatusOK(getCollectionRoutingInfoForTxnCmd(opCtx, _nss)); // For a sharded time-series collection, only the underlying buckets collection is stored on the // config servers. If the user operation is on the time-series view namespace, we should check @@ -299,18 +261,27 @@ ChunkManager ChunkManagerTargeter::_init(OperationContext* opCtx, bool refresh) // back to the view namespace and reset '_isRequestOnTimeseriesViewNamespace'. if (!cm.isSharded() && !_nss.isTimeseriesBucketsCollection()) { auto bucketsNs = _nss.makeTimeseriesBucketsNamespace(); - auto bucketsPlacementInfo = createDatabaseAndGetRoutingInfo(bucketsNs); - if (bucketsPlacementInfo.isSharded()) { + if (refresh) { + uassertStatusOK(Grid::get(opCtx)->catalogCache()->getCollectionRoutingInfoWithRefresh( + opCtx, bucketsNs)); + } + auto bucketsRoutingInfo = + uassertStatusOK(getCollectionRoutingInfoForTxnCmd(opCtx, bucketsNs)); + if (bucketsRoutingInfo.isSharded()) { _nss = bucketsNs; - cm = std::move(bucketsPlacementInfo); + cm = std::move(bucketsRoutingInfo); _isRequestOnTimeseriesViewNamespace = true; } } else if (!cm.isSharded() && _isRequestOnTimeseriesViewNamespace) { // This can happen if a sharded time-series collection is dropped and re-created. Then we // need to reset the namepace to the original namespace. _nss = _nss.getTimeseriesViewNamespace(); - auto newCm = createDatabaseAndGetRoutingInfo(_nss); - cm = std::move(newCm); + + if (refresh) { + uassertStatusOK( + Grid::get(opCtx)->catalogCache()->getCollectionRoutingInfoWithRefresh(opCtx, _nss)); + } + cm = uassertStatusOK(getCollectionRoutingInfoForTxnCmd(opCtx, _nss)); _isRequestOnTimeseriesViewNamespace = false; } @@ -352,7 +323,7 @@ BSONObj ChunkManagerTargeter::extractBucketsShardKeyFromTimeseriesDoc( if (auto metaField = timeseriesOptions.getMetaField(); metaField) { if (auto metaElement = doc.getField(*metaField); !metaElement.eoo()) { - timeseries::metadata::normalize(metaElement, builder, timeseries::kBucketMetaFieldName); + builder.appendAs(metaElement, timeseries::kBucketMetaFieldName); } } @@ -415,10 +386,6 @@ std::vector<ShardEndpoint> ChunkManagerTargeter::targetUpdate(OperationContext* const auto& updateOp = itemRef.getUpdate(); - if (updateOp.getMulti()) { - updateManyCount.increment(1); - } - // If the collection is not sharded, forward the update to the primary shard. if (!_cm.isSharded()) { // TODO (SERVER-51070): Remove the boost::none when the config server can support @@ -535,11 +502,8 @@ std::vector<ShardEndpoint> ChunkManagerTargeter::targetDelete(OperationContext* itemRef.getLet(), itemRef.getLegacyRuntimeConstants()); - if (deleteOp.getMulti()) { - deleteManyCount.increment(1); - } - BSONObj deleteQuery = deleteOp.getQ(); + BSONObj shardKey; if (_cm.isSharded()) { if (_isRequestOnTimeseriesViewNamespace) { uassert(ErrorCodes::NotImplemented, @@ -565,13 +529,20 @@ std::vector<ShardEndpoint> ChunkManagerTargeter::targetDelete(OperationContext* deleteQuery = BSONObj(); } } + + // Sharded collections have the following further requirements for targeting: + // + // Limit-1 deletes must be targeted exactly by shard key *or* exact _id + shardKey = + uassertStatusOK(_cm.getShardKeyPattern().extractShardKeyFromQuery(expCtx, deleteQuery)); } - // We first try to target based on the delete's query. It is always valid to forward any delete - // to a single shard, so return immediately if we are able to target a single shard. - auto endpoints = uassertStatusOK(_targetQuery(expCtx, deleteQuery, collation)); - if (endpoints.size() == 1) { - return endpoints; + // Target the shard key or delete query + if (!shardKey.isEmpty()) { + auto swEndpoint = _targetShardKey(shardKey, collation); + if (swEndpoint.isOK()) { + return std::vector{std::move(swEndpoint.getValue())}; + } } // We failed to target a single shard. @@ -600,7 +571,7 @@ std::vector<ShardEndpoint> ChunkManagerTargeter::targetDelete(OperationContext* << ", shard key pattern: " << _cm.getShardKeyPattern().toString(), !_cm.isSharded() || deleteOp.getMulti() || isExactIdQuery(opCtx, *cq, _cm)); - return endpoints; + return uassertStatusOK(_targetQuery(expCtx, deleteQuery, collation)); } StatusWith<std::vector<ShardEndpoint>> ChunkManagerTargeter::_targetQuery( |
