Skip to content

Stop the feed-heartbeat migration claiming a retention sweep that runs - #646

Merged
xmap merged 1 commit into
mainfrom
fix-heartbeat-retention-comment
Aug 11, 2026
Merged

Stop the feed-heartbeat migration claiming a retention sweep that runs#646
xmap merged 1 commit into
mainfrom
fix-heartbeat-retention-comment

Conversation

@xmap

@xmap xmap commented Aug 11, 2026

Copy link
Copy Markdown
Owner

The header of 20260621040000_init_entries_run_feed_heartbeats.sql said "Retention sweeps prune old ping rows". Nothing prunes this table, or any other entries_* table. The only pruner in the tree is idempotency_pruner.py, which prunes idempotency_keys. Rows accumulate without limit, and a reader sizing the table trusted a bound that does not exist.

Found while auditing why 2-BM wrote 6568 permit-probe rows during a nine-hour EPICS outage.

The replacement also drops the old "BRIN-friendly" aside. This table has no BRIN index; its only index is a (run_id, recorded_at DESC) btree, so a time-range sweep would need its own index first.

Comment-only, but it touches an applied migration

Atlas chains its hashes, so re-hashing this one file rewrote 17 downstream entries in atlas.sum. Verified on a throwaway pg17 container holding the pre-edit hashes:

check result
atlas migrate status OK
atlas migrate apply (with a pending file present, not just the no-op path) OK
atlas migrate validate OK
architecture suite 30408 passed

The tradeoff: atlas migrate down now refuses across the 20260621040000..20260810120000 window, reporting the files as modified since applied. That path is a documented emergency escape hatch rather than a workflow, and nothing automated calls it. It can be restored whenever convenient with atlas migrate set 20260621030000 then atlas migrate set 20260810120000, which rewrites the revision hashes and executes no SQL.

No deploy required: no new migration, so EXPECTED_SCHEMA_VERSION is unchanged.

🤖 Generated with Claude Code

The header said "Retention sweeps prune old ping rows". Nothing prunes
this table, or any other entries_* table: the only pruner in the tree is
idempotency_pruner.py, which prunes idempotency_keys. A reader sizing
the table trusted a bound that does not exist, and rows accumulate
without limit. Found while auditing why 2-BM wrote 6568 permit-probe
rows during a nine-hour EPICS outage.

The replacement also drops the old "BRIN-friendly" aside. This table has
no BRIN index; its only index is a (run_id, recorded_at DESC) btree, so
a time-range sweep would need its own index first.

Comment-only. Editing an applied migration changes atlas.sum, and Atlas
chains its hashes, so 17 downstream entries were re-hashed. Verified on
a throwaway pg17 container holding the pre-edit hashes: status, apply
(with a pending file present, not just the no-op path), and validate all
pass. The tradeoff is that `atlas migrate down` now refuses across the
20260621040000..20260810120000 window, reporting the files as modified
since applied. That path is a documented emergency escape hatch, not a
workflow, and nothing automated calls it. Restore it when convenient
with `atlas migrate set 20260621030000` then `atlas migrate set
20260810120000`, which rewrites the revision hashes and executes no SQL.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Coverage report

This PR does not seem to contain any modification to coverable code.

@xmap
xmap merged commit 6df913d into main Aug 11, 2026
17 checks passed
@xmap
xmap deleted the fix-heartbeat-retention-comment branch August 11, 2026 17:54
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