You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Retention is the one subsystem that deletes acknowledged data on purpose, and it has never run against a real cluster under faults.
No drill turns it on. A search for MALACHI_RETENTION in docker-compose.cluster.yml and scripts/*.sh matches nothing; the compose file passes MALACHI_LOG_ROLL_MAX_AGE_MS through (line 88) and none of the three retention variables, which exist only in config/runtime.exs:273-275.
The tests are in-process: test/malachi/cluster/retention_test.exs (the pure rule), test/malachi/cluster/retention_coordinator_test.exs (which passes its OWN copy of the expire function at lines 104-108, so the production Application.expire_segment/1 runs in no test), and the policy cases in test/malachi/metadata_test.exs.
The harness exists and has earned its keep: scripts/chaos_lib.sh, scripts/chaos_checker.exs (modes produce and verify, main/1 clauses at lines 539 and 549), and the node, storage, config-deploy and reshard-restart drills.
The defects of #190 were found by reading code. The dependency list is long because this drill certifies what those issues build; the point is to find the next such defect by running the system.
Plan
A. A dedicated drill and a checker mode. scripts/docker-retention-chaos.sh on top of scripts/chaos_lib.sh, with the retention variables and a small :segment_max_bytes passed through docker-compose.cluster.yml so segments seal and expire within seconds (MALACHI_RETENTION_INTERVAL_MS already exists, so the sweep can run every second with no code change). A new verify-retention mode in scripts/chaos_checker.exs that knows the policy and each record's acknowledgment time. Invariants:
Nothing younger than the policy (plus a stated grace window) is unreadable.
A leader killed between the control-plane delete and the replica delete converges with zero orphan directories.
It runs as its own CI job on the cadence of the other drills. Cost: 1.5 to 2.5 weeks.
B. Multinode ExUnit only. Peer BEAM nodes under the :multinode tag. Cost: about 1 week. Faster and less flaky, but no real disks, no kill -9, no containers: it cannot express invariants 2 and 4 faithfully.
C. Turn retention on inside the storage drill. No new script. That drill's core invariant is "every acknowledged record is readable", which retention falsifies by design; bending its checker would weaken a certification that currently means something.
Do nothing. Retention stays certified by unit tests and code review.
Recommendation: A. Invariants 2 and 4 are the ones most likely to hide bugs, and only a real cluster can state them.
Risks and open questions
CI duration and flakiness. A flaky drill is a P0 bug in this project. Every invariant needs an explicit grace window (policy, plus sweep interval, plus seal time, plus injected skew) derived from the configuration and printed in the report, never a bare sleep.
The kill window of invariant 2 is microseconds wide. Between BrokerServer.delete_segment/2 and the first replica delete there is no natural pause. Options: an env-gated delay seam in the expire function (production code that exists only for the drill), or a statistical approach of many kills under a one-second sweep. Recommendation: the seam, documented, off by default, and rejected at boot outside a drill profile. Needs a decision.
Clock skew inside Docker. Containers share the host kernel clock. RetentionCoordinator has a :clock option (lib/malachi/cluster/retention_coordinator.ex:46), but sealed_at is stamped by whichever node seals. Open question: a test-only clock offset setting honored by both, or libfaketime in the image?
Whatever it finds. Findings become their own P0 bug issues with the evidence attached; they are not fixed inside this PR, so the drill may land with a known-failing invariant marked as such.
Measurements count on Linux only. Local macOS runs are smoke runs (Docker Desktop shares only /Users, Colima needs explicit cpusets); the certification result is the CI run.
Checked, not a risk: the existing checker already separates producing from verifying and keeps an acknowledgment file, so the new mode extends its input (add the acknowledgment time) and does not need a second checker.
Ten consecutive green runs on Linux CI before the job becomes required, with the duration recorded.
The checker's new mode has unit coverage for the grace-window arithmetic and for the orphan-directory scan.
The report artifact lists, per run: segments expired, orphans found and removed, the largest observed gap between policy age and actual deletion, and consumer skips.
Full suite including mix test --only multinode, mix format --check-formatted, mix credo --strict, mix dialyzer, mix docs --warnings-as-errors, coverage on touched files.
The four existing chaos drills still pass with the compose changes, retention off by default.
PR
Branch
test/retention-chaos-drill
Description
Adds a retention chaos drill and a checker mode that certify retention in a real cluster: nothing young is lost, a leader kill mid-expiry leaves no orphan directories, slow groups are not skipped below their commit, and clock skew or a vnode split does not create holes.
Part of #185.
Blocked by #190, #197, #194, #198, #199, #200.
Context
Retention is the one subsystem that deletes acknowledged data on purpose, and it has never run against a real cluster under faults.
MALACHI_RETENTIONin docker-compose.cluster.yml and scripts/*.sh matches nothing; the compose file passesMALACHI_LOG_ROLL_MAX_AGE_MSthrough (line 88) and none of the three retention variables, which exist only in config/runtime.exs:273-275.Application.expire_segment/1runs in no test), and the policy cases in test/malachi/metadata_test.exs.produceandverify,main/1clauses at lines 539 and 549), and the node, storage, config-deploy and reshard-restart drills.The defects of #190 were found by reading code. The dependency list is long because this drill certifies what those issues build; the point is to find the next such defect by running the system.
Plan
A. A dedicated drill and a checker mode. scripts/docker-retention-chaos.sh on top of scripts/chaos_lib.sh, with the retention variables and a small
:segment_max_bytespassed through docker-compose.cluster.yml so segments seal and expire within seconds (MALACHI_RETENTION_INTERVAL_MSalready exists, so the sweep can run every second with no code change). A newverify-retentionmode in scripts/chaos_checker.exs that knows the policy and each record's acknowledgment time. Invariants:It runs as its own CI job on the cadence of the other drills. Cost: 1.5 to 2.5 weeks.
B. Multinode ExUnit only. Peer BEAM nodes under the
:multinodetag. Cost: about 1 week. Faster and less flaky, but no real disks, nokill -9, no containers: it cannot express invariants 2 and 4 faithfully.C. Turn retention on inside the storage drill. No new script. That drill's core invariant is "every acknowledged record is readable", which retention falsifies by design; bending its checker would weaken a certification that currently means something.
Do nothing. Retention stays certified by unit tests and code review.
Recommendation: A. Invariants 2 and 4 are the ones most likely to hide bugs, and only a real cluster can state them.
Risks and open questions
BrokerServer.delete_segment/2and the first replica delete there is no natural pause. Options: an env-gated delay seam in the expire function (production code that exists only for the drill), or a statistical approach of many kills under a one-second sweep. Recommendation: the seam, documented, off by default, and rejected at boot outside a drill profile. Needs a decision.RetentionCoordinatorhas a:clockoption (lib/malachi/cluster/retention_coordinator.ex:46), butsealed_atis stamped by whichever node seals. Open question: a test-only clock offset setting honored by both, or libfaketime in the image?Verification
mix test --only multinode,mix format --check-formatted,mix credo --strict,mix dialyzer,mix docs --warnings-as-errors, coverage on touched files.PR
Branch
Description