feat: reshuffle block metadata after pruning - #20400
Open
SkyFan2002 wants to merge 2 commits into
Open
Conversation
SkyFan2002
marked this pull request as draft
August 27, 2026 15:42
SkyFan2002
marked this pull request as ready for review
August 27, 2026 18:18
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I hereby agree to the terms of the CLA available at: https://docs.databend.com/dev/policies/cla/
Summary
This PR improves read parallelism for distributed Fuse scans by reshuffling the surviving block metadata after pruning.
Previously, lazy Fuse segments were distributed before pruning. Although the segments could be evenly assigned across executors, pruning might leave very different numbers of blocks on each node. The surviving block reads could therefore remain concentrated on one or a few executors, causing scan skew and underutilizing the rest of the cluster.
This PR separates distributed Fuse scanning into the following stages:
FusePruneruns the existing pruning pipeline and emits emptyDataBlocks carryingBlockPartitionMeta.FuseBlockPartInfoand redistributes the metadata across executors.FuseBlockReadexpands the exchanged metadata back to the configured I/O parallelism and reads the actual block data on the destination nodes.The exchange uses a stable bucket order based on each node's persistent
cache_id, rather than the transient exchange destination order. This keeps block ownership stable when exchange destination ordering changes and avoids unnecessarily reducing persistent-cache locality.Activation conditions
The metadata exchange is enabled only when all of the following conditions are met:
enable_distributed_pruning = 1enable_prune_pipeline = 1The physical-plan rewrite is applied only when the scan belongs to a fragment that can host readers on all executors. A scan in the root fragment may be coordinator-only, so it keeps the original
TableScanpath.Scans that do not satisfy these conditions also continue to use the existing path. Disabling either distributed pruning or the prune pipeline therefore provides a fallback without the new metadata exchange.
Implementation details
TableScan, then injects the metadata exchange after the row-data exchanges have been finalized.FusePrune, a source operator that emits pruned block partitions without reading block data.FuseBlockRead, which consumes exchanged block partitions and performs the existing Fuse block-read and scan-output processing.FusePruneas a source fragment and propagates itsDataSourcePlanthrough fragment serialization.FusePartExchangeInjectorthat:BlockPartitionMeta.FuseBlockPartInfo.cache_idordering when mapping hash buckets to exchange outputs.BlockPartitionMetaserializable across Flight while retaining the completeFuseBlockPartInfo, including block indexes, statistics, bloom-filter locations, ranges, and virtual-block metadata.Reviewer focus
Please pay particular attention to the following areas:
Physical-plan placement
src/query/service/src/physical_plans/physical_distributed_pruning.rsPartition routing and cache stability
src/query/service/src/servers/flight/v1/exchange/fuse_part_exchange.rscache_idgives the expected stable ownership and cache-locality behavior when exchange destination order changes.Exchange and serialization correctness
BlockPartitionMetaand the fullFuseBlockPartInfosurvive the Flight serialization round trip.Pipeline construction and parallelism
src/query/storages/fuse/src/operations/read_data.rssrc/query/storages/fuse/src/operations/read/fuse_source.rsCompatibility with existing scan behavior
Performance trade-off
Test coverage
The added coverage includes:
cache_idbucket mapping independent of exchange destination order.BlockPartitionMetaserialization round trip.Tests
Validation:
cargo check -p databend-query --libcargo test -p databend-query --lib create_builds_prune_exchange_read_shape -- --nocapturecargo test -p databend-query --lib fuse_part_exchange -- --nocapturecargo clippy -p databend-query --lib -- -D warningscargo fmt --all -- --checkType of change
AI assistance
This change is