summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcos José Grillo Ramírez <marcos.grillo@mongodb.com>2020-08-03 15:03:09 +0200
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-08-04 11:23:57 +0000
commit71a444f8d9d8cd6841a5e618dcde107334653008 (patch)
tree072ffc1ee533c0d931f53d2ead1321a9c3e82682
parent1f0fbdcc0da395e1afc0554e398c5a4c83c72539 (diff)
downloadmongo-71a444f8d9d8cd6841a5e618dcde107334653008.tar.gz
SERVER-50077 Set unsharded shard version on collection creation only on primary node on the shard op observer and clear the filtering metadata if the shard register update or the refresh fails on shardCollection
-rw-r--r--src/mongo/db/s/shard_server_op_observer.cpp2
-rw-r--r--src/mongo/db/s/shardsvr_shard_collection.cpp34
2 files changed, 27 insertions, 9 deletions
diff --git a/src/mongo/db/s/shard_server_op_observer.cpp b/src/mongo/db/s/shard_server_op_observer.cpp
index 4e5009c8748..f8e80658e21 100644
--- a/src/mongo/db/s/shard_server_op_observer.cpp
+++ b/src/mongo/db/s/shard_server_op_observer.cpp
@@ -468,7 +468,7 @@ void ShardServerOpObserver::onCreateCollection(OperationContext* opCtx,
// sharded or unsharded and set it on the CSR. If this method is called with the metadata as
// UNKNOWN, this means an internal collection creation, which can only be UNSHARDED
auto* csr = CollectionShardingRuntime::get(opCtx, collectionName);
- if (!csr->getCurrentMetadataIfKnown())
+ if (opCtx->writesAreReplicated() && !csr->getCurrentMetadataIfKnown())
csr->setFilteringMetadata(opCtx, CollectionMetadata());
}
diff --git a/src/mongo/db/s/shardsvr_shard_collection.cpp b/src/mongo/db/s/shardsvr_shard_collection.cpp
index b83b444f52f..95fb4a22143 100644
--- a/src/mongo/db/s/shardsvr_shard_collection.cpp
+++ b/src/mongo/db/s/shardsvr_shard_collection.cpp
@@ -500,7 +500,15 @@ void refreshAllShards(OperationContext* opCtx,
const NamespaceString& nss,
const ShardId& dbPrimaryShardId,
const std::vector<ChunkType>& initialChunks) {
- forceShardFilteringMetadataRefresh(opCtx, nss);
+ // If the refresh fails, then the shard will end with a shardVersion UNSHARDED.
+ try {
+ forceShardFilteringMetadataRefresh(opCtx, nss);
+ } catch (const DBException&) {
+ UninterruptibleLockGuard noInterrupt(opCtx->lockState());
+ AutoGetCollection autoColl(opCtx, nss, MODE_IX);
+ CollectionShardingRuntime::get(opCtx, nss)->clearFilteringMetadata(opCtx);
+ throw;
+ }
auto shardRegistry = Grid::get(opCtx)->shardRegistry();
@@ -544,13 +552,23 @@ UUID shardCollection(OperationContext* opCtx,
const InitialSplitPolicy::ShardCollectionConfig& initialChunks) {
// Insert chunk documents to config.chunks on the config server.
writeFirstChunksToConfig(opCtx, initialChunks);
-
- updateShardingCatalogEntryForCollection(opCtx,
- nss,
- targetState,
- initialChunks,
- *request.getCollation(),
- request.getUnique());
+ // If an error happens when contacting the config server, we don't know if the update
+ // succeded or not, which might cause the local shard version to differ from the config
+ // server, so we clear the metadata to allow another operation to refresh it.
+ try {
+ updateShardingCatalogEntryForCollection(opCtx,
+ nss,
+ targetState,
+ initialChunks,
+ *request.getCollation(),
+ request.getUnique());
+
+ } catch (const DBException&) {
+ UninterruptibleLockGuard noInterrupt(opCtx->lockState());
+ AutoGetCollection autoColl(opCtx, nss, MODE_IX);
+ CollectionShardingRuntime::get(opCtx, nss)->clearFilteringMetadata(opCtx);
+ throw;
+ }
refreshAllShards(opCtx, nss, dbPrimaryShardId, initialChunks.chunks);
};