bobhan1 opened a new pull request, #70350:
URL: https://github.com/apache/doris/pull/70350

   ### Background
   
   MoW compaction records a mapping from each input row to its output segment 
and row ID. Delete bitmap conversion and inverted-index merging consume this 
mapping, whose dense representation stores two `uint32_t` values for every 
physical input row, including filtered rows.
   
   ### What problem does this PR solve?
   
   Issue Number: None
   Related PR: None
   PR Type: Performance
   
   Problem Summary:
   
   Large tablets can require gigabytes of row-ID mapping memory and repeatedly 
fail base compaction when allocations exceed the memory limit. This PR adds 
opt-in compression during construction, using fixed 4096-source-row blocks with 
delta varint64 and Zstd level 1. It adapts delete bitmap and SNII consumers to 
bounded decoding while preserving validation and error propagation. 
`enable_compressed_rowid_conversion` defaults to `false`, so existing 
deployments keep their current representation unless explicitly enabled.
   
   ### Details
   
   - **Change map:** 1,183 production lines changed, 644 test lines, 57 
documentation lines, and no generated files. The compressed storage kernel 
accounts for 625 production lines; source views and destination-prefix 
translation for 258; SNII validation and posting access for 213; mode 
selection, bitmap error propagation, configuration and build integration for 
the remaining 87. Tests cover storage representations, consumer equivalence, 
allocation accounting and performance observations.
   - **Why it was slow:** Memory is the bottleneck: the dense array costs 8 
bytes per physical input row, or 8 GB for one billion rows, before other 
compaction allocations. Allocation failures can prevent compaction from 
completing.
   - **Optimization:** Seal fixed source-row blocks during merge, without 
assuming a maximum number of rows per segment. EMPTY and LINEAR omit redundant 
values; DELTA uses delta varints with Zstd only when beneficial; RAW64 caps 
payload expansion. A shared 1 MiB paged arena avoids a separate allocation for 
every block. Each source has a directory with 32 bytes per block and a lazy 32 
KiB active builder; codec workspaces are bounded by one block. Finalization 
releases builders and the encoder, then derives destination positions from 
actual output segment row counts using 64-bit prefixes. SNII retains one 
decoded block per prepared source and shares one decoder workspace per 
executing plan. Significant allocations use Doris memory tracking; lookup 
errors propagate as `Status` instead of being mistaken for deleted rows.
   - **Results:** Four synthetic benchmarks each build and read all 262,144 
physical source rows, using 1 or 16 sources, approximately 10% missing rows, 
and two target-gap distributions. The dense array alone is 2,097,152 bytes. The 
compressed directory is 2,048 bytes in each case, and sequential reads decode 
exactly 64 blocks even when sources are interleaved.
   
   | Sources | Gap parameter | Encoded payload (bytes) | Retained kernel 
allocation (bytes) | Tracked build/overall peak (bytes) |
   | ---: | ---: | ---: | ---: | ---: |
   | 1 | 1 | 20,273 | 1,050,832 | 1,470,944 |
   | 1 | 16 | 185,936 | 1,050,832 | 1,470,944 |
   | 16 | 1 | 20,704 | 1,051,792 | 1,963,424 |
   | 16 | 16 | 229,915 | 1,051,792 | 1,963,424 |
   
   Retained allocation includes directory capacity, the entire 1 MiB arena page 
and storage-kernel metadata. The consumer-tracker peak includes transient 
allocations and reader workspaces; it is requested allocation size, not RSS. 
These kernel measurements exclude allocator bookkeeping, benchmark 
oracle/baseline copies, the enclosing source index/destination prefix and other 
compaction state. The enclosing index and prefix also use tracked allocators 
but are tested separately. A separate billion-row EMPTY-source test verifies 
its complete 7,812,512-byte directory; it is not a billion-row compression 
benchmark.
   
   On the local ASAN/O0 build, construction took 65.4–95.3 ms, one cold lookup 
per block took 3.5–10.3 ms, and sequential lookup took 80.0–101.4 ms versus 
2.9–5.9 ms for the direct dense scan. The 4,096 grouped sparse lookups took 
31.8–446.4 ms, and 4,096 random lookups took 211.5–446.5 ms. These are 
diagnostic observations, with UT assertions included in sequential timing, not 
optimized production throughput or end-to-end compaction results.
   
   - **Applicability and cost:** Compression is limited to eligible MoW 
UNIQUE-key compactions. Cluster-key tables, sequence-map tables, compactions 
requiring CLucene and legacy inverted-index debug dumps retain DENSE. The 
source streams must advance monotonically. Sparse/random access can repeatedly 
decode blocks, and small maps can be dominated by arena tail space and 
per-source workspaces. No spill or external CLucene API changes are introduced.
   - **Behavior change:** The new dynamic BE setting enables an alternative 
in-memory representation for eligible compactions. DENSE remains the default. 
Bitmap visibility rules and SNII bounds, monotonicity, uniqueness and complete 
destination coverage validation are retained; persistent formats and FE/BE 
protocols are unchanged.
   
   ### Testing
   
   Locally, 69/69 tests passed in `ASAN_UT` at commit 
`fbedc9a49fd8e05e950f82b241099d9dfc8cc8cd`, based on master 
`4c63661f60f96c694757000640bcebc832e8bb6d`:
   
   ```sh
   bash run-be-ut.sh --run \
     
--filter='CompressedRowIdMapTest.*:CompressedRowIdMapBenchmark.*:SniiRowIdConversionTest.*:SniiPostingCursorTest.*:SniiIndexCompactionTest.*:TestRowIdConversion.*:VParquetWriterTest.HiveAndIcebergParquetPageIndexOptions'
 \
     -j32
   ```
   
   Coverage includes all representations, deletion holes, wide ordinals, arena 
page boundaries, independent cursors, backward seeks, malformed payloads, 
allocation failures and balanced memory accounting. Consumer tests compare 
compressed mappings with DENSE, verify physical segment IDs and visibility 
filtering, and check that an in-memory SNII merge produces byte-identical 
null/posting data to a rebuilt index. The additional Parquet case verifies the 
upstream page-index test after rebasing.
   
   Repository clang-format 16 checks on changed files, 
`build-support/check-build-hygiene.sh` and `git diff --check` passed. Actual 
local/cloud compaction, concurrent loading, lock-hold time and optimized 
production timing are deferred to a separate validation phase. clang-tidy was 
not run.
   
   ### Notes for Reviewers
   
   See 
[`be/test/storage/rowid_conversion_benchmark.md`](https://github.com/bobhan1/doris/blob/fbedc9a49fd8e05e950f82b241099d9dfc8cc8cd/be/test/storage/rowid_conversion_benchmark.md)
 for reproducible commands and precise accounting boundaries. The small 
benchmark's single arena page must not be extrapolated as a new page for every 
262,144 rows in a larger shared map.
   
   The explicit `cloud/config.h` include in `segment_read_ahead.cpp` fixes its 
direct `is_cloud_mode` dependency exposed by changed unity-batch boundaries. 
The compressed codec source is excluded from unity compilation because it uses 
Zstd's static workspace API. Keep the setting disabled by default pending 
actual compaction validation.
   
   ### Release note
   
   An experimental `enable_compressed_rowid_conversion` BE setting can reduce 
row-ID mapping memory for eligible MoW compactions. It is disabled by default.
   
   ### Check List (For Author)
   
   - Behavior changed: Yes (see Details)
   - Does this need documentation: Yes; the in-tree benchmark guide covers 
developer use. User documentation will follow actual compaction validation.
   - Pre-submission status: Partially verified: targeted ASAN unit tests pass; 
actual compaction validation and optimized performance measurements are pending.
   
   ### AI Disclosure
   
   - Tool: OpenAI Codex (GPT-6)
   - Generated: Implementation, unit tests, benchmark, developer guide and PR 
description.
   - Human review: Pending.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to