summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergi Mateo Bellido <sergi.mateo-bellido@mongodb.com>2021-02-13 14:55:37 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-02-16 08:45:08 +0000
commit881a8d0ddad5a9209ca6083736ac6729183ff25e (patch)
tree62529f357975b001a29bebf70236b4c409f57656
parentb2b19a82e94957d0142658a90a80cf8bcc2beb58 (diff)
downloadmongo-881a8d0ddad5a9209ca6083736ac6729183ff25e.tar.gz
SERVER-54566 Fixing the CatalogCacheLoader behavior when handling an update metadata format task
It fixes 3 things: - Do not assume that after an update metadata format task there is always a common task that updates some chunks. - Minor bug computing the flag that specifies whether the results that are sent back to the CatalogCache must be patched-up. - Minor bug patching-up the results that are sent back.
-rw-r--r--src/mongo/db/s/shard_server_catalog_cache_loader.cpp74
1 files changed, 41 insertions, 33 deletions
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 aa82c7d916c..1ba225f6747 100644
--- a/src/mongo/db/s/shard_server_catalog_cache_loader.cpp
+++ b/src/mongo/db/s/shard_server_catalog_cache_loader.cpp
@@ -368,20 +368,22 @@ ChunkVersion getLocalVersion(OperationContext* opCtx, const NamespaceString& nss
return uassertStatusOK(std::move(swRefreshState)).lastRefreshedCollectionVersion;
}
+/**
+ * if 'mustPatchUpMetadataResults' is true, it sets the current 'timestamp' to all 'changedChunks'.
+ * Does nothing otherwise.
+ */
void patchUpChangedChunksIfNeeded(bool mustPatchUpMetadataResults,
- CollectionAndChangedChunks& collAndChunks) {
+ const boost::optional<Timestamp>& timestamp,
+ std::vector<ChunkType>& changedChunks) {
+
if (!mustPatchUpMetadataResults)
return;
- const boost::optional<Timestamp> newTimestamp = collAndChunks.creationTime;
- std::for_each(
- collAndChunks.changedChunks.begin(),
- collAndChunks.changedChunks.end(),
- [&newTimestamp](ChunkType& chunk) {
- const ChunkVersion version = chunk.getVersion();
- chunk.setVersion(ChunkVersion(
- version.majorVersion(), version.minorVersion(), version.epoch(), newTimestamp));
- });
+ std::for_each(changedChunks.begin(), changedChunks.end(), [&timestamp](ChunkType& chunk) {
+ const ChunkVersion version = chunk.getVersion();
+ chunk.setVersion(ChunkVersion(
+ version.majorVersion(), version.minorVersion(), version.epoch(), timestamp));
+ });
}
} // namespace
@@ -884,35 +886,42 @@ StatusWith<CollectionAndChangedChunks> ShardServerCatalogCacheLoader::_getLoader
// - the epoch changed in the enqueued metadata.
// Whichever the cause, the persisted metadata is out-dated/non-existent. Return enqueued
// results.
- patchUpChangedChunksIfNeeded(enqueuedMetadata.mustPatchUpMetadataResults, enqueued);
+ patchUpChangedChunksIfNeeded(enqueuedMetadata.mustPatchUpMetadataResults,
+ enqueued.creationTime,
+ enqueued.changedChunks);
return enqueued;
} else {
// There can be overlap between persisted and enqueued metadata because enqueued work can
// be applied while persisted was read. We must remove this overlap.
+ // Note also that the enqueued changed Chunks set may be empty (e.g. there is only one
+ // update metadata format task)
+
+ if (!enqueued.changedChunks.empty()) {
+ const ChunkVersion minEnqueuedVersion = enqueued.changedChunks.front().getVersion();
+
+ // Remove chunks from 'persisted' that are GTE the minimum in 'enqueued' -- this is
+ // the overlap.
+ auto persistedChangedChunksIt = persisted.changedChunks.begin();
+ while (persistedChangedChunksIt != persisted.changedChunks.end() &&
+ persistedChangedChunksIt->getVersion().isOlderThan(minEnqueuedVersion)) {
+ ++persistedChangedChunksIt;
+ }
+ persisted.changedChunks.erase(persistedChangedChunksIt, persisted.changedChunks.end());
- const ChunkVersion minEnqueuedVersion = enqueued.changedChunks.front().getVersion();
-
- // Remove chunks from 'persisted' that are GTE the minimum in 'enqueued' -- this is
- // the overlap.
- auto persistedChangedChunksIt = persisted.changedChunks.begin();
- while (persistedChangedChunksIt != persisted.changedChunks.end() &&
- persistedChangedChunksIt->getVersion().isOlderThan(minEnqueuedVersion)) {
- ++persistedChangedChunksIt;
+ // Append 'enqueued's chunks to 'persisted', which no longer overlaps. Also add
+ // 'enqueued's reshardingFields and allowMigrations setting to 'persisted'.
+ persisted.changedChunks.insert(persisted.changedChunks.end(),
+ enqueued.changedChunks.begin(),
+ enqueued.changedChunks.end());
}
- persisted.changedChunks.erase(persistedChangedChunksIt, persisted.changedChunks.end());
-
- // Append 'enqueued's chunks to 'persisted', which no longer overlaps. Also add 'enqueued's
- // reshardingFields and allowMigrations setting to 'persisted'.
- persisted.changedChunks.insert(persisted.changedChunks.end(),
- enqueued.changedChunks.begin(),
- enqueued.changedChunks.end());
// We may need to patch up the changed chunks because there was a metadata format change
- patchUpChangedChunksIfNeeded(enqueuedMetadata.mustPatchUpMetadataResults, persisted);
+ patchUpChangedChunksIfNeeded(enqueuedMetadata.mustPatchUpMetadataResults,
+ enqueued.creationTime,
+ persisted.changedChunks);
-
- // The collection info in enqueued metadata may be more recent than the persited metadata
+ // The collection info in enqueued metadata may be more recent than the persisted metadata
persisted.creationTime = enqueued.creationTime;
persisted.reshardingFields = std::move(enqueued.reshardingFields);
persisted.allowMigrations = enqueued.allowMigrations;
@@ -1451,11 +1460,10 @@ ShardServerCatalogCacheLoader::CollAndChunkTaskList::getEnqueuedMetadataForTerm(
collAndChunks = CollectionAndChangedChunks();
mustPatchUpMetadataResults = false;
} else if (task.collectionAndChangedChunks->epoch != collAndChunks.epoch) {
- // The current task has a new epoch (refine shard key or resharding op) -> the
- // aggregated results aren't interesting so we overwrite them with the current
- // CollAndChangedChunks and unset the flag
+ // The current task has a new epoch -> the aggregated results aren't interesting so we
+ // overwrite them. The task may be an update metadata format task, so propagate the flag
collAndChunks = *task.collectionAndChangedChunks;
- mustPatchUpMetadataResults = false;
+ mustPatchUpMetadataResults = task.updateMetadataFormat;
} else if (task.updateMetadataFormat) {
// The current task is an update task -> we only update the Timestamp of the aggregated
// results and set the flag