[client-v2] Every compressed read fails on ClickHouse 26.9+: response reader is hardcoded to LZ4 but the server default codec is now ZSTD(3)

Aperta
#3,105 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
64/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
java
Ambito
databases

Direzione di ricerca

Inizia da client-v2's ClickHouseLZ4InputStream.java, in particolare dal percorso di refill alla riga 112, e traccia il modo in cui le risposte HTTP compresse raggiungono i response reader usati da getTableSchema e dalle altre letture. Riproduci il problema contro clickhouse/clickhouse-server:head con compress=1, quindi verifica che le risposte compresse LZ4, ZSTD e quelle non compresse siano gestite in base ai rispettivi byte del metodo del frame senza interrompere le letture esistenti.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Summary

ClickHouse #108786 ("Switch the default compression to ZSTD(3) for table data and network", merged 2026-09-05, Version info says merged into 26.9.1.810, so included in 26.9 and later) changes CompressionCodecFactory::getDefaultCodec from LZ4 to ZSTD(3).

The HTTP compress=1 framed output is one of the direct getDefaultCodec users. client-v2 requests compress=1 by default and pipes the response body through ClickHouseLZ4InputStream, which asserts the LZ4 block magic byte, so every compressed read fails against ClickHouse 26.9+:

com.clickhouse.client.api.ClientException: Invalid LZ4 magic byte: '-112'
	at com.clickhouse.client.api.internal.ClickHouseLZ4InputStream.refill(ClickHouseLZ4InputStream.java:112)
	at com.clickhouse.client.api.internal.ClickHouseLZ4InputStream.read(ClickHouseLZ4InputStream.java:62)
	...
	at com.clickhouse.client.api.internal.TableSchemaParser.readTSKV(TableSchemaParser.java:23)
	at com.clickhouse.client.api.Client.getTableSchemaImpl(Client.java:1872)
	at com.clickhouse.client.api.Client.getTableSchema(Client.java:1847)

getTableSchema is just where we hit it first — this is not specific to schema introspection, it affects any compressed response.

Per that PR's own changelog, the HTTP compress=1 path has no runtime rollback: it is not controlled by the compatibility setting, per-column CODEC, or the server <compression> config. So this cannot be worked around server-side.

Affected versions
  • client-v2 0.9.5 — verified failing
  • client-v2 0.10.0 (latest release) — same ClickHouseLZ4InputStream with the same Invalid LZ4 magic byte check, so also affected
  • Server: ClickHouse 26.9+ (reproduced on clickhouse/clickhouse-server:head = 26.9.1.943). 26.8 and earlier are unaffected by this bug.
Root cause / evidence

-112 is 0x90 signed. Raw curl against 26.9.1.943 confirms the framing:

$ curl -s -u default:x 'localhost:8123/?compress=1' --data-binary 'DESCRIBE TABLE t FORMAT TSKV' | xxd | head -2
00000000: 151e 70e4 4490 8555 b0c4 8424 d0d8 731d  ..p.D..U...$..s.
00000010: 9065 0000 00c0 0000 0028 b52f fd20 c09d  .e.......(./. ..

After the 16-byte checksum, offset 0x10 is 0x90 — the compression method byte for ZSTD, exactly the byte reported in the exception — and offset 0x18 is 28 b5 2f fd, the ZSTD magic number. ClickHouseLZ4InputStream expects 0x82 there.

The same request without compress=1 returns plain readable TSKV.

Reproduce
docker run -d --name chhead -e CLICKHOUSE_PASSWORD=x -p 8123:8123 clickhouse/clickhouse-server:head
# then any client-v2 read, e.g.
# client.getTableSchema("t", "default")
Suggested fix

The compressed frame is self-describing — ClickHouse#108786 explicitly relies on "the receiver auto-detects the codec", which holds for the server's own readers. client-v2 does not auto-detect; it assumes LZ4. The response reader should dispatch on the compression method byte in the frame header (0x82 LZ4, 0x90 ZSTD, 0x02 none) rather than asserting LZ4, and gain a ZSTD decompression path.

Note on interaction with #3070 / #3094

On 26.9+ this bug currently masks the X-ClickHouse-Format precedence bug (#3070, #3094): the stream dies in refill before readTSKV ever sees bytes. I verified the header bug is still present on 26.9.1.943 — curl -H 'format: TSKV' ... --data-binary 'DESCRIBE TABLE t' returns TabSeparated there too. So fixing only this issue will move getTableSchema back to failing with Non-null columnName and columnType are required; both need to land.

Setting compressServerResponse(false) sidesteps this issue alone, but for the same reason it is not a usable workaround for getTableSchema, and it costs compression on every read.

Context

Found while running the ClickHouse Flink connector test suite against ClickHouse HEAD.

Lingua principale
Java
Stelle
1.6k
Fork
637
Merge medio
2g 12h
PR unite (30g)
28

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di ClickHouse/clickhouse-java

Tutte le issue di ClickHouse/clickhouse-java

Issue simili

Altre issue su Java

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.