diff options
author | Jamie Heppenstall <jamie.heppenstall@mongodb.com> | 2019-07-23 15:40:39 -0400 |
---|---|---|
committer | Jamie Heppenstall <jamie.heppenstall@mongodb.com> | 2019-08-01 11:09:29 -0400 |
commit | 5cbe01663884b321c45145c29bb9d9668125392e (patch) | |
tree | c9fd3bda635b7521578be83d263f536f50651bd0 /src/mongo/db/s | |
parent | b33f7ebe86ed14eb330eaacf9b367ffc2aefb7a3 (diff) | |
download | mongo-5cbe01663884b321c45145c29bb9d9668125392e.tar.gz |
SERVER-42152 Delete existing chunks on new epoch in persisted routing table cache
Diffstat (limited to 'src/mongo/db/s')
-rw-r--r-- | src/mongo/db/s/shard_metadata_util.cpp | 15 | ||||
-rw-r--r-- | src/mongo/db/s/shard_metadata_util.h | 5 | ||||
-rw-r--r-- | src/mongo/db/s/shard_server_catalog_cache_loader.cpp | 33 |
3 files changed, 51 insertions, 2 deletions
diff --git a/src/mongo/db/s/shard_metadata_util.cpp b/src/mongo/db/s/shard_metadata_util.cpp index 627f955fd67..d08c5f4cd79 100644 --- a/src/mongo/db/s/shard_metadata_util.cpp +++ b/src/mongo/db/s/shard_metadata_util.cpp @@ -432,6 +432,21 @@ Status dropChunksAndDeleteCollectionsEntry(OperationContext* opCtx, const Namesp } } +void dropChunks(OperationContext* opCtx, const NamespaceString& nss) { + DBDirectClient client(opCtx); + + // Drop the config.chunks collection associated with namespace 'nss'. + BSONObj result; + if (!client.dropCollection(ChunkType::ShardNSPrefix + nss.ns(), kLocalWriteConcern, &result)) { + auto status = getStatusFromCommandResult(result); + if (status != ErrorCodes::NamespaceNotFound) { + uassertStatusOK(status); + } + } + + LOG(1) << "Successfully cleared persisted chunk metadata for collection '" << nss << "'."; +} + Status deleteDatabasesEntry(OperationContext* opCtx, StringData dbName) { try { DBDirectClient client(opCtx); diff --git a/src/mongo/db/s/shard_metadata_util.h b/src/mongo/db/s/shard_metadata_util.h index 7a5d8be6824..31ca31f37cd 100644 --- a/src/mongo/db/s/shard_metadata_util.h +++ b/src/mongo/db/s/shard_metadata_util.h @@ -211,6 +211,11 @@ Status updateShardChunks(OperationContext* opCtx, Status dropChunksAndDeleteCollectionsEntry(OperationContext* opCtx, const NamespaceString& nss); /** + * Drops locally persisted chunk metadata associated with 'nss': only drops the chunks collection. + */ +void dropChunks(OperationContext* opCtx, const NamespaceString& nss); + +/** * Deletes locally persisted database metadata associated with 'dbName': removes the databases * collection entry. */ diff --git a/src/mongo/db/s/shard_server_catalog_cache_loader.cpp b/src/mongo/db/s/shard_server_catalog_cache_loader.cpp index c889866bfd1..cf158829ef5 100644 --- a/src/mongo/db/s/shard_server_catalog_cache_loader.cpp +++ b/src/mongo/db/s/shard_server_catalog_cache_loader.cpp @@ -46,6 +46,7 @@ #include "mongo/s/catalog/type_shard_database.h" #include "mongo/s/client/shard_registry.h" #include "mongo/s/grid.h" +#include "mongo/util/fail_point_service.h" #include "mongo/util/log.h" namespace mongo { @@ -56,6 +57,8 @@ using CollectionAndChangedChunks = CatalogCacheLoader::CollectionAndChangedChunk namespace { +MONGO_FAIL_POINT_DEFINE(hangPersistCollectionAndChangedChunksAfterDropChunks); + AtomicWord<unsigned long long> taskIdGenerator{0}; /** @@ -75,6 +78,24 @@ ThreadPool::Options makeDefaultThreadPoolOptions() { return options; } +void dropChunksIfEpochChanged(OperationContext* opCtx, + const NamespaceString& nss, + const CollectionAndChangedChunks& collAndChunks, + const ChunkVersion& maxLoaderVersion) { + if (collAndChunks.epoch != maxLoaderVersion.epoch() && + maxLoaderVersion != ChunkVersion::UNSHARDED()) { + // If the collection has a new epoch, delete all existing chunks in the persisted routing + // table cache. + dropChunks(opCtx, nss); + + if (MONGO_FAIL_POINT(hangPersistCollectionAndChangedChunksAfterDropChunks)) { + log() << "Hit hangPersistCollectionAndChangedChunksAfterDropChunks failpoint"; + MONGO_FAIL_POINT_PAUSE_WHILE_SET_OR_INTERRUPTED( + opCtx, hangPersistCollectionAndChangedChunksAfterDropChunks); + } + } +} + /** * Takes a CollectionAndChangedChunks object and persists the changes to the shard's metadata * collections. @@ -83,7 +104,8 @@ ThreadPool::Options makeDefaultThreadPoolOptions() { */ Status persistCollectionAndChangedChunks(OperationContext* opCtx, const NamespaceString& nss, - const CollectionAndChangedChunks& collAndChunks) { + const CollectionAndChangedChunks& collAndChunks, + const ChunkVersion& maxLoaderVersion) { // Update the collections collection entry for 'nss' in case there are any new updates. ShardCollectionType update = ShardCollectionType( nss, collAndChunks.epoch, collAndChunks.shardKeyPattern, collAndChunks.shardKeyIsUnique); @@ -107,6 +129,12 @@ Status persistCollectionAndChangedChunks(OperationContext* opCtx, } // Update the chunks. + try { + dropChunksIfEpochChanged(opCtx, nss, collAndChunks, maxLoaderVersion); + } catch (const DBException& ex) { + return ex.toStatus(); + } + status = updateShardChunks(opCtx, nss, collAndChunks.changedChunks, collAndChunks.epoch); if (!status.isOK()) { return status; @@ -1036,7 +1064,8 @@ void ShardServerCatalogCacheLoader::_updatePersistedCollAndChunksMetadata( } uassertStatusOKWithContext( - persistCollectionAndChangedChunks(opCtx, nss, *task.collectionAndChangedChunks), + persistCollectionAndChangedChunks( + opCtx, nss, *task.collectionAndChangedChunks, task.minQueryVersion), str::stream() << "Failed to update the persisted chunk metadata for collection '" << nss.ns() << "' from '" << task.minQueryVersion.toString() << "' to '" << task.maxQueryVersion.toString() << "'. Will be retried."); |