Repository navigation
feat(table): add append and primary-key compaction APIs - #1247
Merged
Merged
Conversation
Contributor
|
Wow what timing I was literally just curious about this |
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.
Purpose
Add a Rust API for consolidating table files and atomically publishing the replacement files in a COMPACT snapshot. Planning, execution and commit are separate so applications can schedule tasks across workers and commit completed subsets.
Related to #286: this provides the Rust compaction prerequisite; Python maintenance bindings remain separate.
Brief change log
Add
CompactBuilder,CompactPlanner,CompactExecutor, serializable plans/tasks/results, andTableCommit::commit_compact.Plan unaware append compaction with the batch packing rules from Java
AppendCompactCoordinator: select files belowtarget-file-size * compaction.small-file-ratio(default 0.7), sort by size, and accumulatefile_size + source.split.open-file-costto twice the target size. Emit a remaining group only when it meetscompaction.min.file-num(default 5). Ordinary read splits retain their separate sequence-orderedmax(file_size, open_file_cost)packing.Use Java's sequence-window best-effort strategy for unordered bucketed append tables; keep task planning independent of read split boundaries.
Rewrite complete PK buckets with deduplicate, first-row, partial-update and aggregation, preserving merge state, sequence numbers and tombstones.
Support fixed and dynamic PK buckets, including cross-partition dynamic buckets. Preserve HASH assignments and carry forward the latest HASH manifest when writes commit concurrently.
Validate captured inputs, schema and file metadata; reject conflicting rewrites and overlapping positive-level LSM ranges. Bound recovery scans to snapshots after the captured plan, reject plans invalidated by rollback, and keep task-subset retries idempotent. Rebuild file indexes and clean up unsubmitted outputs on execution failure.
Share a streaming
KeyValueDataFileWriterbetween ordinary PK write-buffer flushes and compaction. Compaction writes ordered physical KV batches directly; sequence allocation and flush-time merging stay in the ordinary writer. Collect key/sequence bounds, statistics and indexes incrementally.Separate format-buffer flushing from file rolling. Parquet/ORC/Avro/ROW keep files open across buffer flushes; formats that retain pending rows use bounded rolling as a fallback. Materialize partial output chunks for accurate resource accounting. Avoid orc-rust 0.8 predicate/positional-selection composition for indexed reads across flushed stripes, while preserving exact residual filtering.
Tests
Passed 95 relevant integration tests: 14 append compaction cases, 37 PK compaction cases, and write/resource/statistics/external-path/BLOB/sequence suites. Passed 229 focused unit tests with Vortex enabled, covering Java append planning, typed key ranges, commit/recovery, KV output, statistics and ORC.
Regression coverage also compares future writes before/after compaction, rejects non-replayable aggregate retract state, exercises effective aggregator overrides and ignored legacy retracts, checks concurrent positive-level conflicts, and covers rollback and bounded recovery.
Writer regression coverage verifies that tiny write buffers do not fragment Parquet/ORC/Avro/ROW compaction files, indexes and key/sequence bounds span multiple batches, row limits can split one input batch, byte targets roll independently, large input batches do not multiply memory charges, and Mosaic/Vortex retain bounded output buffers. The existing cases cover concurrent writes, snapshot history, merge engines, HASH assignments and migrations, changelog, external paths and failure cleanup.
API and Format
Adds the public Rust compaction API. Task selection and output sizing come from captured table options; there is no per-task file-count cap or size override on the builder. Uses existing data-file, manifest and COMPACT snapshot formats. Planning is stateless for each captured snapshot; streaming coordinator aging and scan paging remain outside this API.
Scope is unaware/unordered bucketed append tables and PK tables with
changelog-producer=none/input(first-row requiresnone). Row tracking, data evolution, deletion vectors, query authorization, rowkind fields, postpone buckets, dedicated blob/vector storage, non-HASH snapshot indexes, andlookup/full-compactionchangelog generation remain unsupported. Ordered bucketed append, append incremental clustering, PK clustering override and record-level expiration are explicitly rejected until their Java-specific rewrite contracts are implemented. Reducer groups whose aggregate DELETE/raw/initialization state cannot be replayed are rejected without publication, rather than changing subsequent write results; safe sum/delete cases and ignored partial-update retracts remain supported. PK compaction uses the existing 256 overlapping merge-input limit.Documentation
Add
docs/src/compaction.mdand its navigation entry, covering the API workflow, concurrency/retry behavior, merge-engine semantics, dynamic buckets and current limits.