summaryrefslogtreecommitdiff
path: root/src/mongo/s/chunk_manager_targeter.cpp
diff options
context:
space:
mode:
authorLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
committerLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
commit4cb8841196d0625dfa3825aa326f071cd27c7b8b (patch)
tree1682a647d4463397c119183369ae6f750d5fdcff /src/mongo/s/chunk_manager_targeter.cpp
parentaa03c6362cbaa767638e6eed9b031d86dd2643d1 (diff)
parent8f0827553e09872941945a093b647a4211a9db7f (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.cpp99
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(