replicated: whole-cluster SIGKILL discards acked messages already in every node's segment files (recovery truncates to a frontier only checkpoints publish)
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 45/100
Direzione di ricerca
Start with core/integration/tests/cluster/crash_durability.rs and run the failing replicated recovery test using the command in the issue. Then trace the issue’s named recovery paths, PartitionPrepareJournal::open, recover_unpublished_tail, recover_segment_files, and PartitionPersistence::append_batch. Done means the replicated test recovers the acknowledged payloads after whole-cluster SIGKILL, with recovery still stopping at an invalid or torn record.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Bug description
With durability = replicated, a whole-cluster SIGKILL loses acknowledged messages that were already written to every node's segment files. On restart, each replica truncates its segment back to the last published WAL frontier and logs:
WARN journal::partition_journal::segments: discarding unpublished segment bytes beyond the durable WAL frontier group=0 incarnation=1 start_offset=0 durable_bytes=0 discarded_bytes=9510
Buffered appends do not publish the frontier. Only PartitionPrepareJournal::sync(), checkpoint rewrites and a few control operations (segment enable, view certification) do. PartitionPersistence::append_batch calls sync() only for durable appends, so a replicated partition's frontier stays where its last checkpoint or control operation left it. Recovery trusts only the frontier: when both slots verify, PartitionPrepareJournal::open discards everything after it, as the comment on recover_unpublished_tail says ("the tail is discarded as it always was"). recover_segment_files then truncates the segment to segments.tail.
SIGKILL does not lose a completed write(), because the page cache outlives the process. That is the premise of crash_durability.rs, and the README states the same contract:
A crash (SIGKILL, OOM kill) loses the WAL writes not yet handed to the OS, and power loss also loses what the OS had not written to disk. Under
replicated,qor more such crashes at once can lose the most recently acknowledged writes.
The second sentence alone does not bound the loss, but the first one does: SIGKILL loses the writes not yet handed to the OS. Expected: a whole-cluster SIGKILL loses at most the writes still in process memory. Actual: it loses everything after the last frontier publication, even though those bytes are on disk on all three nodes. Checkpoints, durable appends, persisted consumer-offset stores, the shutdown drain and a few control operations publish the frontier. replicated appends do not, so on a busy replicated partition the published frontier can sit far behind the data.
Failing test
PR #4632 adds given_replicated_eager_flush_topic_when_the_whole_cluster_is_killed_should_recover_flushed_data to core/integration/tests/cluster/crash_durability.rs. It is the replicated twin of the existing given_eager_flush_topic_when_the_whole_cluster_is_killed_should_recover_flushed_data:
- Create a 1-partition topic with
messages_required_to_save = 1anddurability = Replicated. - Send 30 single-message batches and record each confirmed offset.
- Wait until every node's segment files contain all 30 payloads (
wait_until_payloads_installed). kill_cluster()(SIGKILL on every node), thenrestart_cluster().- Poll from offset 0.
On master b15c8e1e9 it fails with:
replicated acked data already in every node's segments must survive a whole-cluster SIGKILL: 0 of 30 acked offsets readable (0 polled, in order: true), first missing or payload-mismatched offset: Some(0)
The persisted twin passes in the same run. All three nodes log durable_bytes=0 discarded_bytes=9510, which is 30 messages of 317 bytes.
Real-process numbers
A 3-node cluster in Docker (apache/iggy:edge, revision 44c7dc834), 2 CPUs and 4 GiB per node, 2 shards, data on volumes. Six producers send about 2,000 msg/s in batches of 20 to a topic with 6 partitions, replicated, and default flush thresholds. Producers retry every send until it is acknowledged. All three nodes get SIGKILL 20 s into the run and restart 15 s later. A verifier then reads every partition from offset 0.
- Lost: 33,860 of 179,760 acknowledged messages. About 40,000 were sent before the kill, so recovery kept roughly the first 15%.
- Order and gaps: no reordering, no offset gaps, no duplicates. The lost messages are a suffix of each partition.
- Discarded bytes: each node logs the discard line for every partition, with the same numbers on all three nodes. For example, partition 5 kept
durable_bytes=525039and droppeddiscarded_bytes=2677984. The discarded bytes summed over the 6 partitions (about 10.6 MB at 319 bytes per message) equal the lost count. persisted: 0 lost in the same scenario.
The same scenario on f6dfbdbb3, before #4387 added the frontier-owned segment recovery, lost 2,829 of 179,400 (1.6%). We reported that on #4266.
Possible directions (for discussion, not in the PR)
- On open, let a
replicatedpartition adopt the WAL records after the published frontier that verify as an unbroken chain (op sequence, parent checksum, segment reservation), and stop at the first record that does not verify. A torn tail after power loss stops the walk. The log stays untrusted for the election as #4500 already does, so a quorum of trusted replicas still decides the view. - If this loss is intended, change the README to say that a whole-cluster crash under
replicatedloses everything since the last frontier publication, which on a busy partition can be most of the data written since the cluster started.
Versions
- master
b15c8e1e9(integration test, built from source) apache/iggy:edgerevision44c7dc834(real-process run)
Reproduction
cargo build --bin iggy-server
cargo test -p integration --test mod -- --ignored given_replicated_eager_flush_topic_when_the_whole_cluster_is_killed_should_recover_flushed_data
Related: #4266 (recovery contract for Replicated, closed by #4500), #4092 (durability policies), #4387 (frontier-owned segment recovery).
Found and reproduced with an AI agent (Claude Code), following CONTRIBUTING's "Bugs Found by an Agent".
- Lingua principale
- Rust
- Stelle
- 5.2k
- Fork
- 502
- Merge medio
- 2g 21h
- PR unite (30g)
- 159
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Include un Dockerfile o un file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di apache/iggy
-
Go examples: add a message envelope producer and consumerForse già presa @ThunderGod77 l’ha presa 4 giorni fa. Apertago good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
apache/iggy#4694 · 3 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
HTTP client treats a consumer group as a plain consumerForse già presa @mohitduhan19 l’ha presa 22 giorni fa. Apertabug rust server
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
apache/iggy#4408 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Add the fail-fast connection option to the Rust and Python quick-startsForse già presa @QIW9 l’ha presa 10 giorni fa. Apertadocs good first issue
Difficoltà 1/5 1-3 ore Idoneità per principianti 92/100
apache/iggy#4261 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
ResourceNotFound from the binary protocol prints an empty keyForse già presa @xalestar l’ha presa 1 giorno fa. Apertaapi python rust
apache/iggy#4767 · 2 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
Node SDK: send accepts malformed user headers that fail during pollingForse già presa @Subham-KRLX l’ha presa 2 giorni fa. Apertabug good first issue javascript
apache/iggy#4750 · 3 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
Issue simili
-
enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
-
bug order-flow studies ui
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
userFRM/egui-charts#2417 ·
I maintainer di solito rispondono entro 1 giorno
-
In a plain-text message, Font, Font Size, Font Color and Text Highlight Color stay liveForse già presa @ragelfundionctrumnar l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
UCS-Care-Group/mailcraft#862 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
smoltcp-rs/smoltcp#1243 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 4 giorni