bool CollectionShardingState::collectionIsSharded() { auto metadata = getMetadata().getMetadata(); if (metadata && (metadata->getCollVersion().isStrictlyEqualTo(ChunkVersion::UNSHARDED()))) { return false; } // If 'metadata' is null, then the shard doesn't know if this collection is sharded or not. In // this scenario we will assume this collection is sharded. We will know sharding state // definitively once SERVER-24960 has been fixed. return true; }
ChunkVersion forceShardFilteringMetadataRefresh(OperationContext* opCtx, const NamespaceString& nss, bool forceRefreshFromThisThread) { invariant(!opCtx->lockState()->isLocked()); invariant(!opCtx->getClient()->isInDirectClient()); auto const shardingState = ShardingState::get(opCtx); invariant(shardingState->canAcceptShardedCommands()); const auto routingInfo = uassertStatusOK(Grid::get(opCtx)->catalogCache()->getCollectionRoutingInfoWithRefresh( opCtx, nss, forceRefreshFromThisThread)); const auto cm = routingInfo.cm(); if (!cm) { // No chunk manager, so unsharded. // Exclusive collection lock needed since we're now changing the metadata AutoGetCollection autoColl(opCtx, nss, MODE_IX, MODE_X); auto css = CollectionShardingState::get(opCtx, nss); css->refreshMetadata(opCtx, nullptr); return ChunkVersion::UNSHARDED(); } { AutoGetCollection autoColl(opCtx, nss, MODE_IS); auto metadata = CollectionShardingState::get(opCtx, nss)->getMetadata(opCtx); // We already have newer version if (metadata && metadata->getCollVersion().epoch() == cm->getVersion().epoch() && metadata->getCollVersion() >= cm->getVersion()) { LOG(1) << "Skipping refresh of metadata for " << nss << " " << metadata->getCollVersion() << " with an older " << cm->getVersion(); return metadata->getShardVersion(); } } // Exclusive collection lock needed since we're now changing the metadata AutoGetCollection autoColl(opCtx, nss, MODE_IX, MODE_X); auto css = CollectionShardingState::get(opCtx, nss); auto metadata = css->getMetadata(opCtx); // We already have newer version if (metadata && metadata->getCollVersion().epoch() == cm->getVersion().epoch() && metadata->getCollVersion() >= cm->getVersion()) { LOG(1) << "Skipping refresh of metadata for " << nss << " " << metadata->getCollVersion() << " with an older " << cm->getVersion(); return metadata->getShardVersion(); } std::unique_ptr<CollectionMetadata> newCollectionMetadata = stdx::make_unique<CollectionMetadata>(cm, shardingState->getShardName()); css->refreshMetadata(opCtx, std::move(newCollectionMetadata)); return css->getMetadata(opCtx)->getShardVersion(); }
Status CollectionShardingState::waitForClean(OperationContext* opCtx, const NamespaceString& nss, OID const& epoch, ChunkRange orphanRange) { while (true) { boost::optional<CleanupNotification> stillScheduled; { AutoGetCollection autoColl(opCtx, nss, MODE_IX); auto css = CollectionShardingState::get(opCtx, nss); { // First, see if collection was dropped, but do it in a separate scope in order to // not hold reference on it, which would make it appear in use auto metadata = css->_metadataManager->getActiveMetadata(css->_metadataManager); if (!metadata || metadata->getCollVersion().epoch() != epoch) { return {ErrorCodes::StaleShardVersion, "Collection being migrated was dropped"}; } } stillScheduled = css->trackOrphanedDataCleanup(orphanRange); if (!stillScheduled) { log() << "Finished deleting " << nss.ns() << " range " << redact(orphanRange.toString()); return Status::OK(); } } log() << "Waiting for deletion of " << nss.ns() << " range " << orphanRange; Status result = stillScheduled->waitStatus(opCtx); if (!result.isOK()) { return result.withContext(str::stream() << "Failed to delete orphaned " << nss.ns() << " range " << orphanRange.toString()); } } MONGO_UNREACHABLE; }
/* static */ Status CollectionShardingState::waitForClean(OperationContext* opCtx, NamespaceString nss, OID const& epoch, ChunkRange orphanRange) { do { auto stillScheduled = boost::optional<CleanupNotification>(); { AutoGetCollection autoColl(opCtx, nss, MODE_IX); // First, see if collection was dropped. auto css = CollectionShardingState::get(opCtx, nss); { auto metadata = css->_metadataManager->getActiveMetadata(css->_metadataManager); if (!metadata || metadata->getCollVersion().epoch() != epoch) { return {ErrorCodes::StaleShardVersion, "Collection being migrated was dropped"}; } } // drop metadata stillScheduled = css->trackOrphanedDataCleanup(orphanRange); if (!stillScheduled) { log() << "Finished deleting " << nss.ns() << " range " << redact(orphanRange.toString()); return Status::OK(); } } // drop collection lock log() << "Waiting for deletion of " << nss.ns() << " range " << orphanRange; Status result = stillScheduled->waitStatus(opCtx); if (!result.isOK()) { return Status{result.code(), str::stream() << "Failed to delete orphaned " << nss.ns() << " range " << orphanRange.toString() << ": " << result.reason()}; } } while (true); MONGO_UNREACHABLE; }