/**
|
* Attempt to read the collection and chunk metadata. May not read all the updates if the metadata
|
* for the collection is being updated concurrently.
|
*
|
* TODO: this is unsafe without an index on the relevant chunks collection. Will be used when
|
* SERVER-27714 is done.
|
*
|
* If the epoch changes while reading the chunks, returns an empty object.
|
*/
|
StatusWith<CollectionAndChangedChunks> getImcompletePersistediMetadataSinceVersion(
|
OperationContext* opCtx,
|
const NamespaceString& nss,
|
ChunkVersion version) {
|
|
try {
|
CollectionAndChangedChunks collAndChunks = getPersistedMetadataSinceVersion(
|
opCtx,
|
nss,
|
version,
|
false);
|
if (collAndChunks.changedChunks.empty()) {
|
// Found a collections entry, but the chunks are being updated.
|
return CollectionAndChangedChunks();
|
}
|
|
// Make sure the collections entry epoch has not changed since we began reading chunks --
|
// an epoch change between reading the collections entry and reading the chunk metadata
|
// would invalidate the chunks.
|
|
auto afterShardCollectionsEntry = uassertStatusOK(readShardCollectionsEntry(opCtx, nss));
|
if (shardCollectionEntry.getEpoch() != afterShardCollectionsEntry.getEpoch()) {
|
// The collection was dropped and recreated since we began. Return empty results.
|
return CollectionAndChangedChunks();
|
}
|
|
return collAndChunks;
|
} catch (const DBException& ex) {
|
Status status = ex.toStatus();
|
if (status == ErrorCodes::NamespaceNotFound) {
|
return CollectionAndChangedChunks();
|
}
|
return Status(
|
ErrorCodes::OperationFailed,
|
str::stream() << "Failed to reload local metadata due to '"
|
<< status.toString()
|
<< "'.");
|
}
|
}
|