Skip to content

fix: use HTTP compression when requesting Lz4 for result sets - #482

Merged
abonander merged 8 commits into
mainfrom
ab/lz4-frame
Sep 30, 2026
Merged

abonander merged 8 commits into
mainfrom
ab/lz4-frame

Conversation

@abonander

@abonander abonander commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Summary

ClickHouse/ClickHouse#108786 (released in 26.9) introduced a regression where compress=1 now means Zstd when existing client versions assumed compress=1 always meant Lz4 (#468, ClickHouse/clickhouse-java#3105).

This was then partially addressed in ClickHouse/ClickHouse#119825 by letting us select Lz4 compression with network_compression_method=lz4, theoretically letting us roll back to the previous behavior. However, it turns out that network_compression_method cannot be set by read-only users (#476 (comment)), which is a known use-case for this crate so setting this unconditionally is unfortunately a non-starter.

I started on a branch to change wholesale over to Zstd but it required enabling the zstd feature by default to fix this for all users. I think this would be better to do in a new major version and then we can drop lz4 as a default feature (https://github.com/ClickHouse/clickhouse-rs/compare/ab/zstd-native-framing).

The only fix that doesn't require any user-facing changes is to switch to using HTTP compression exclusively (for result sets; native framing is still used for inserts for now). However, lz4_flex's frame format implementation does not work in async code (it depends on the blocking Read trait and is not re-entrant, so we can't just write an adapter that returns WouldBlock), so it required hand-rolling our own.

Using async-compression is also a non-starter because it links the native liblz4 library which was previously dropped because a pure Rust implementation was desired (#107). Even though the zstd feature ends up linking libzstd, I have to assume some users prefer the lz4 feature simply because it does not pull in any native dependencies.

Fixes #468

Fixes #483 (by a happy little accident!)

Checklist

Delete items not relevant to your PR:

  • A human-readable description of the changes was provided so that we can include it in CHANGELOG later

@codecov

codecov Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

@abonander
abonander merged commit d72ea54 into main Sep 30, 2026
7 of 8 checks passed
@abonander
abonander deleted the ab/lz4-frame branch September 30, 2026 05:42
mattsse added a commit to tempoxyz/tidx that referenced this pull request Oct 6, 2026
ClickHouse 26.9 switched the codec of `compress=1` HTTP responses to
ZSTD
([ClickHouse#108786](ClickHouse/ClickHouse#108786)),
but the `clickhouse` crate 0.14 only decodes LZ4 native frames. Against
`clickhouse-server:latest`, which all of our compose files use, every
sink query fails with `decompression error: incorrect magic number`,
starting with the version check in `ensure_schema`.

The sink client now sets `network_compression_method=lz4`. Every 26.9
stable release honors it for `compress=1` responses
([ClickHouse#119825](ClickHouse/ClickHouse#119825)),
and older servers already respond with LZ4. The upstream crate fix
([clickhouse-rs#482](ClickHouse/clickhouse-rs#482))
is unreleased; it avoids this setting because read-only users cannot
change it, which doesn't matter for the sink since it needs write
access. The query engine in `src/clickhouse.rs` uses plain reqwest
without `compress=1` and was not affected.

This also fixes
`test_backfill_replays_blocks_with_extra_block_versions`, which failed
on every server version. It wrote the stale and canonical versions of
block 1 in one INSERT, which ReplacingMergeTree collapses on insert, so
the two-version precondition never held. The product check is correct
(`canonical_blocks_present` reads without `FINAL`). The test now writes
the stale version separately into another monthly partition so it
survives until the backfill repairs it. Stopping merges would not work
here because it also blocks the repair's `ALTER TABLE ... DELETE`
mutation.

The ClickHouse integration tests pass against both 26.9.8.3 and
25.12.11.4.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants