Skip to content

Paimon 1.0 full-compaction recovery can lose final changelog after APPEND #318

Closed as not planned

Description

@liuyongvs

Problem

Released Paimon 1.0.0 can acknowledge recovery of a full-compaction commit while permanently losing that commit's changelog. A batch scan still sees the newest value. A streaming consumer waiting for those final updates can therefore wait indefinitely.

This is reproduced with the released Paimon writer, commit and reader APIs, without a Flink planner, StreamFusion operators, or native kernels. It is independent of the writer cleanup defect fixed in #309.

Deterministic two-row reproducer

Create a one-bucket primary-key table (k INT, v INT) with changelog-producer=full-compaction and default deletion-vector settings:

  1. Write (1,10), perform full compaction and commit. Start a stream scan and consume its initial snapshot.
  2. Write (1,20), perform full compaction, and prepare the final commit. Confirm its compact increment contains changelog files.
  3. Fail one manifest read after the final APPEND snapshot is durable, before the separate COMPACT snapshot becomes durable.
  4. Recreate the commit object with the same commit user, and recover the original messages with filterAndCommit.
  5. Compare a fresh batch scan and the existing incremental stream scan.
Scenario Latest snapshot Fresh batch values Incremental changelog
No injected failure COMPACT [20] Includes 20
Injected failure followed by recovery APPEND [20] []

The recovered case fails the unchanged requirement that the final changelog include 20. It does not merely hit a short deadline. The control passes and recovery fails on both JDK 11 and 17. Additional standalone runs remove every StreamFusion production class directory/JAR from the classpath and use only canonical released dependency JARs plus the diagnostic classes; they reproduce the same missing changelog. The earlier deletion-vector split-commit reproducer also still fails separately (20 expected, 10 observed).

Implementation evidence

The released FileStoreCommitImpl.commit writes APPEND and COMPACT separately under the same commit identifier. filterCommitted discards a pending identifier once any snapshot from that user has that identifier, so recovery after APPEND can discard the pending COMPACT and its changelog.

The current PR #315 CI failure is consistent with missing final changelog, but its exact cause is not established by this standalone reproducer:

  • Paimon 1.0 parity job reports 241/242 upstream cases passed and PrimaryKeyFileStoreTableITCase.testFullCompactionChangelogProducerStreamingRandom timed out after 180 seconds.
  • Retained inventory shows one producer, two sink subtasks, local-merge-buffer-size=5m, four buckets and partitions, 64 keys per partition, and injected filesystem failures.
  • The writer restores checkpoint 4 and later checkpoint 13, then finishes at 04:44:37 UTC. The consumer keeps completing checkpoints and waiting until the test timeout at 04:47:13 UTC.
  • The artifact lacks the failed warehouse snapshots/manifests needed to prove the split-commit sequence for that invocation.

Proposed resolution

  1. Retain the failing CI warehouse and compare final APPEND/COMPACT snapshots, commit identifiers, manifests and changelog files. Replay both stock and native readers against the same retained state.
  2. Keep the deterministic two-row regression as an opt-in diagnostic; keep the original randomized upstream case and its assertions/deadline enabled.
  3. If the captured failure is this released SDK defect, the upstream recovery protocol must account for incomplete APPEND/COMPACT pairs rather than filtering the entire identifier. Validate retries, idempotence and crash points around both snapshots, then adopt a canonical verified upstream release.
  4. If native writing or scanning introduces an additional difference, address it separately with stock/native twins over identical snapshots and failure locations.

StreamFusion should retain released dependencies and exact stock semantics. Raising deadlines, weakening final-row assertions, editing upstream tests, or enabling unverified recovery behavior does not resolve missing durable changelog.

Activity

  1. liuyongvs commented on Oct 10, 2026

    @liuyongvs
    CollaboratorAuthor

    Revalidated on main bf9837c00c3513c88a3739dcefab549f037da3fb with the released dependencies. The split-commit recovery defect is still reproducible, and the released Paimon 2.0.0 line also loses final full-compaction changelog.

    Released dependency / diagnostic No failure control Failure after durable APPEND, followed by recovery
    Paimon 1.0.0, deletion-vector diagnostic PaimonSplitCommitRecoveryReproducerTest Latest value 20 Latest value 10, expected 20
    Paimon 2.0.0, full-compaction diagnostic PaimonFullCompactionCommitRecoveryTest `+I 1 10, -U 1

    In the Paimon 2.0.0 diagnostic, the fresh data scan still sees 20; the failing assertion is specifically the missing update changelog. Both diagnostics directly use released writer/committer/reader APIs and do not execute native operators.

    Reproduction commands from this commit:

    mvn -Pflink-1.18,paimon1 -pl streamfusion-paimon1 -am test \
      -Dsf.runtime.tests.skip=true -Dtest=PaimonSplitCommitRecoveryReproducerTest \
      -Dsurefire.failIfNoSpecifiedTests=false -Dsf.paimon1.reproduceSplitCommit=true
    
    mvn -Ppaimon -pl streamfusion-paimon -am test \
      -Dsf.runtime.tests.skip=true -Dtest=PaimonFullCompactionCommitRecoveryTest \
      -Dsurefire.failIfNoSpecifiedTests=false -Dsf.paimon.reproduceSplitCommit=true

    Each diagnostic has one passing control and one failing injected-recovery invocation. This is separate from the normally enabled module suites: Paimon 1.x ran 95 records with its two opt-in diagnostic tests skipped; Paimon 2.x ran 697 records with its opt-in diagnostic class skipped. A green default module suite does not establish correctness at this split-commit failure boundary.

    Please retain this issue as the recovery tracker across the affected released SDK lines. A verified canonical upstream release or an explicitly reviewed compatibility strategy is still needed; increasing consumer timeouts would not restore the missing durable changelog.

  2. liuyongvs commented on Oct 12, 2026

    @liuyongvs
    CollaboratorAuthor

    PR #333's new Paimon 1.0 parity failure now retains enough durable state to identify the split-commit recovery boundary in an actual lookup invocation.

    Head: 2f6295946034e09719ceadd21f5e8eee0125dd45, based on main c048cfbe. The suite runs all 242 unchanged upstream tests; 241 pass and testLookupChangelogProducerStreamingRandom times out after 180 seconds. This differs from the fetcher retirement exception addressed by #334.

    Table: pt STRING, k INT, v1 BIGINT, v2 STRING, primary key (pt,k), partitioned by pt; four buckets, changelog-producer=lookup, lookup-wait=false, deletion vectors disabled, precommit compaction disabled. Two producers imply 512 terminal keys.

    The captured sequence is:

    1. Both producer jobs ultimately finish, with the second recovering from checkpoints after compaction conflicts.
    2. Snapshot 15 contains the first producer's final changelog. Snapshot 16 persists the second producer's final APPEND at Long.MAX_VALUE.
    3. Its compaction fails with File deletion conflicts detected! Give up committing. after APPEND is durable. Recovery eventually finishes without any COMPACT snapshot for that final identifier.
    4. A fresh batch scan sees all 512 terminal values. The committed changelog contains only 256 terminal keys, so the enabled upstream checker continues waiting for the other 256.

    This is verified using the released stock reader with every StreamFusion production class/JAR excluded. Exact stock/native split replay also agrees on 73 splits and 2,290 changelog rows, including RowKinds and all four fields; the native replay executes its decoder over 83 files. The replay starts at snapshot 1 and is finite. It verifies captured durable state and reader parity, without reconstructing live scheduling or claiming that every concurrent native writer schedule matches stock.

    Original evidence artifact contains the warehouse, snapshots, manifests, data/changelog files, Surefire report, inventory and diagnostics.

    Follow-up commit e97e9ea9 in PR #333 extends the existing opt-in two-row released-SDK diagnostic to lookup as well as full-compaction. On JDK 11 and 17, with StreamFusion production classes/JARs excluded:

    Producer No-failure control Fail after durable APPEND, recover original commit
    full-compaction Final update present Assertion fails: batch [20], changelog []
    lookup Final update present Assertion fails: batch [20], changelog []

    The compact increment is checked to contain the final changelog before injecting the failure. The failure must occur after APPEND, and the batch assertion still requires the latest value. The missing changelog assertion is kept as a failure; this is not reported as a passing recovery test.

    Reproduce the diagnostic with released dependencies:

    mvn -Pflink-1.18,paimon1 -pl streamfusion-paimon1 -am \
      -Dtest=PaimonFullCompactionRecoveryReproducerTest \
      -Dsurefire.failIfNoSpecifiedTests=false \
      -Dsf.paimon1.reproduceFullCompactionCommit=true test

    Expected current result: four invocations, two passing controls and two failing final-changelog assertions. The diagnostic remains opt-in; the original randomized upstream SQL test and its deadline remain enabled and unchanged.

    This issue remains unresolved. The new evidence extends its scope to lookup and establishes the actual captured CI failure boundary; it does not repair the canonical released commit protocol. The connector documentation and docs/benchmarks/results/paimon-lookup-split-commit-2026-10-12.json record the evidence and its limits.

  3. liuyongvs commented on Oct 13, 2026

    @liuyongvs
    CollaboratorAuthor

    PR #335 has another retained full-compaction failure at the same unresolved recovery boundary.

    Paimon 1.0 compatibility job: 241/242 unchanged upstream cases pass; PrimaryKeyFileStoreTableITCase.testFullCompactionChangelogProducerStreamingRandom times out after 180 seconds. The producer jobs eventually finish, but their captured final snapshots are incomplete:

    Snapshot Commit user Identifier Kind
    17 b8c9fb8c-5781-42ee-866f-0b5621f25c13 Long.MAX_VALUE APPEND
    18 0068105e-d837-420f-b402-28b86b379a7c Long.MAX_VALUE APPEND
    19 0068105e-d837-420f-b402-28b86b379a7c Long.MAX_VALUE COMPACT

    There is no final COMPACT for the other commit user and no snapshot after 19. Each producer contributes 256 terminal keys, so the unchanged checker requires 512 terminal values.

    Independent reads of the retained table use the released Paimon 1.0.0 APIs and released dependency JARs, with every StreamFusion production class directory/JAR excluded:

    Released stock read Rows Live keys Keys at terminal value
    Fresh batch scan 512 INSERT 512 512
    Default streaming-start scan, then poll until no more splits 512 INSERT 512 256

    The streaming scan checkpoints snapshot 20 and has no further split. This establishes that the captured durable streaming state lacks half the terminal values even though the batch data contains them. Increasing the consumer deadline cannot create the missing final changelog.

    This new read is a finite retained-state diagnostic. It does not replay every historical split from snapshot 1, reconstruct live writer scheduling, or establish full stock/native writer parity. The existing deterministic released-SDK two-row diagnostic and the earlier #333 historical replay remain separate evidence.

    Main #336 changes string-window admission and does not change Paimon commit recovery. #335 has been rebased onto main b2e6e629; its four Flink/JDK window-regression legs and Rust core tests pass. This rebase does not repair the released split-commit protocol. The original Paimon assertions, injected failures and 180-second deadline remain unchanged and enabled.

    The issue is currently closed, but the released recovery limitation remains reproducible. The remaining resolution still requires a verified canonical dependency release or an explicitly reviewed compatibility strategy that safely recovers incomplete APPEND/COMPACT pairs, including retries, idempotence and failures around both snapshots.

  4. jordepic commented on Oct 15, 2026

    @jordepic
    Collaborator

    Deferring StreamFusion-side work on this for now. This is an upstream Paimon recovery bug that also affects Paimon’s standard Flink connector, rather than a StreamFusion-specific defect; the released-SDK reproductions above demonstrate the underlying issue without StreamFusion.

    We’ll revisit when a verified upstream fix is available in a canonical release. The proposed upstream fix is tracked in apache/paimon#10568.

  5. jordepic commented on Oct 15, 2026

    @jordepic
    Collaborator

    Closing as not planned for StreamFusion, following the decision above. The incomplete APPEND/COMPACT recovery defect reproduces in released Paimon without StreamFusion and involves the core commit protocol also used by Paimon's stock Flink connector. The stock connector has lookup-specific recovery safeguards (apache/paimon#3512 and apache/paimon#5796), so this is not a claim that every stock Flink configuration fails.

    We will not implement a StreamFusion-specific recovery workaround. Keep the released dependency and existing recovery diagnostics; reassess when a verified canonical upstream release is available. The proposed upstream fix remains apache/paimon#10568; closing this issue does not mean that defect is fixed.

    Decision recorded in 3dfb0997.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions