diff options
author | Antonio Fuschetto <antonio.fuschetto@mongodb.com> | 2022-04-07 07:08:24 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-04-07 07:36:54 +0000 |
commit | 487babfa93b6f6f2fb500ecb5411045be89e881c (patch) | |
tree | 65face2984292add5ec37900a61ed86bfb119a91 /src/mongo/db/catalog_raii.cpp | |
parent | b003e8c7aa45e09660a7644fe70763e6b6f5d4ce (diff) | |
download | mongo-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.cpp | 33 |
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) { |