summaryrefslogtreecommitdiff
path: root/src/mongo/db/catalog_raii.cpp
diff options
context:
space:
mode:
authorAntonio Fuschetto <antonio.fuschetto@mongodb.com>2022-04-07 07:08:24 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-04-07 07:36:54 +0000
commit487babfa93b6f6f2fb500ecb5411045be89e881c (patch)
tree65face2984292add5ec37900a61ed86bfb119a91 /src/mongo/db/catalog_raii.cpp
parentb003e8c7aa45e09660a7644fe70763e6b6f5d4ce (diff)
downloadmongo-487babfa93b6f6f2fb500ecb5411045be89e881c.tar.gz
SERVER-65107 Check the shard version when AutoGetCollection is instantiated and there is neither collection nor view
Diffstat (limited to 'src/mongo/db/catalog_raii.cpp')
-rw-r--r--src/mongo/db/catalog_raii.cpp33
1 files changed, 28 insertions, 5 deletions
diff --git a/src/mongo/db/catalog_raii.cpp b/src/mongo/db/catalog_raii.cpp
index b861af2f10b..d52a15a3ece 100644
--- a/src/mongo/db/catalog_raii.cpp
+++ b/src/mongo/db/catalog_raii.cpp
@@ -295,6 +295,9 @@ AutoGetCollection::AutoGetCollection(
return;
}
+ const auto receivedShardVersion{
+ OperationShardingState::get(opCtx).getShardVersion(_resolvedNss)};
+
if ((_view = catalog->lookupView(opCtx, _resolvedNss))) {
uassert(ErrorCodes::CommandNotSupportedOnView,
str::stream() << "Namespace " << _resolvedNss.ns() << " is a timeseries collection",
@@ -305,17 +308,37 @@ AutoGetCollection::AutoGetCollection(
<< " is a view, not a collection",
viewMode == AutoGetCollectionViewMode::kViewsPermitted);
- const auto receivedShardVersion{
- OperationShardingState::get(opCtx).getShardVersion(_resolvedNss)};
uassert(StaleConfigInfo(_resolvedNss,
*receivedShardVersion,
ChunkVersion::UNSHARDED() /* wantedVersion */,
ShardingState::get(opCtx)->shardId()),
- str::stream() << "Namespace " << _resolvedNss << " is a view and the shard version"
- << " attached to the request must be UNSHARDED, instead it is "
- << *receivedShardVersion,
+ str::stream() << "Namespace " << _resolvedNss << " is a view therefore the shard "
+ << "version attached to the request must be unset or UNSHARDED",
!receivedShardVersion || *receivedShardVersion == ChunkVersion::UNSHARDED());
+
+ return;
}
+
+ // There is neither a collection nor a view for the namespace, so if we reached to this point
+ // there are the following possibilities depending on the received shard version:
+ // 1. ChunkVersion::UNSHARDED: The request comes from a router and the operation entails the
+ // implicit creation of an unsharded collection. We can continue.
+ // 2. ChunkVersion::IGNORED: The request comes from a router that broadcasted the same to all
+ // shards, but this shard doesn't own any chunks for the collection. We can continue.
+ // 3. boost::none: The request comes from client directly connected to the shard. We can
+ // continue.
+ // 4. Any other value: The request comes from a stale router on a collection or a view which
+ // was deleted time ago (or the user manually deleted it from from underneath of sharding).
+ // We return a stale config error so that the router recovers.
+
+ uassert(StaleConfigInfo(_resolvedNss,
+ *receivedShardVersion,
+ boost::none /* wantedVersion */,
+ ShardingState::get(opCtx)->shardId()),
+ str::stream() << "No metadata for namespace " << _resolvedNss << " therefore the shard "
+ << "version attached to the request must be unset, UNSHARDED or IGNORED",
+ !receivedShardVersion || *receivedShardVersion == ChunkVersion::UNSHARDED() ||
+ *receivedShardVersion == ChunkVersion::IGNORED());
}
Collection* AutoGetCollection::getWritableCollection(OperationContext* opCtx) {