Fix Iceberg REST catalog commit safety under post-commit network failure by il9ue · Pull Request #2003 · Altinity/ClickHouse · GitHub
Skip to content

Fix Iceberg REST catalog commit safety under post-commit network failure#2003

Open
il9ue wants to merge 3 commits into
antalya-26.3from
fix/iceberg-commit-safety-antalya-26.3
Open

Fix Iceberg REST catalog commit safety under post-commit network failure#2003
il9ue wants to merge 3 commits into
antalya-26.3from
fix/iceberg-commit-safety-antalya-26.3

Conversation

@il9ue

@il9ue il9ue commented Jul 3, 2026

Copy link
Copy Markdown

Found while working on #1609 (TRUNCATE storage-leak cleanup).

Changelog category (leave one):

  • Bug Fix

Changelog entry:

Fix possible data loss in Iceberg writes via REST catalog when a commit response is lost

Documentation entry for user-facing changes

When the network drops the response to a catalog commit that actually succeeded, ClickHouse retries the commit, sees the retry fail, and runs cleanup that deletes object-storage files the catalog still references, that might lead to possible table corruption. The fix cleans up only when the commit was cleanly rejected; ambiguous outcomes leave the files in place and abort instead of retrying.

CI/CD Options

Exclude tests:

  • Fast test
  • Integration Tests
  • Stateless tests
  • Stateful tests
  • Performance tests
  • All with ASAN
  • All with TSAN
  • All with MSAN
  • All with UBSAN
  • All with Coverage
  • All with Aarch64
  • All Regression
  • Disable CI Cache

Regression jobs to run:

  • Fast suites (mostly <1h)
  • Aggregate Functions (2h)
  • Alter (1.5h)
  • Benchmark (30m)
  • ClickHouse Keeper (1h)
  • Iceberg (2h)
  • LDAP (1h)
  • Parquet (1.5h)
  • RBAC (1.5h)
  • SSL Server (1h)
  • S3 (2h)
  • S3 Export (2h)
  • Swarms (30m)
  • Tiered Storage (2h)

il9ue and others added 3 commits July 3, 2026 09:33
On INSERT via a REST catalog, a commit whose response is lost was retried,
got a 409, collapsed to a bool false, and triggered cleanup that deleted the
files the now-live snapshot referenced. Replace the bool with a typed
CommitOutcome and, on failure, re-read the catalog to classify whether our
snapshot actually landed before deciding to clean up.
Follow-ups on the commit-safety fix.

Treat CommitOutcome::Unknown as a hard stop rather than a retryable false: a
lost-response commit may have already landed, so re-entering the transaction
retry loop would double-apply the write. Abort with DATALAKE_DATABASE_ERROR
(matching the retry-exhaustion convention) and preserve written files, guarding
the mutation cleanup path so the abort never deletes a possibly-committed
snapshot's data.

Also catch Poco::TimeoutException on the commit POST so a timed-out response is
classified through the same re-read path instead of leaking.

Adds an integration test that drives the Unknown path and asserts the write
aborts without double-applying and without deleting files.
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant