fix(backup): never run a restore again after its data committed

A restore commits its transaction and then rebuilds the chart tiers. A
worker that stopped during that rebuild left the job running with a stale
heartbeat, and the boot sweep and the admission check treated it like any
interrupted job: the sweep queued it again, so the second run deleted and
re-wrote the account and lost whatever was written in between, and a second
interruption closed it with "rolled back, nothing was changed", which was
false.

The job now records `committedAt` (added to migration 0347, which has not
shipped) and awaits that write before the rebuild starts. The sweep and the
admission check close a committed job as `failed_after_commit`, never queue
it again, and evict the account's caches. The rebuild itself is left to the
nightly and boot passes that already rebuild missing tiers.

The module comment now says what an interrupted restore does (restarted
once, then failed) and what happens to other writes while a restore runs:
new rows are written at once, updates to rows the restore already deleted
wait on their lock until it commits or rolls back.
This commit is contained in:
Marc-André Bombeck committed 2026-09-25 08:49:45 +02:00
1 parent c327ae81d5
commit 3abbad048e
7 files changed
+171 -21

No files matched your search

+2 -1
View File
@@ -71590,7 +71590,8 @@ components:
additionalProperties: false
description: "One restore job. `phase` and `progress` describe a running job; `result` is set once it `succeeded` (the
same report the synchronous restore used to answer with, less `restored`); `failure` once it `failed`.
`attempts` counts the starts: a job whose worker stopped is started again, at most twice."
`attempts` counts the starts: a job whose worker stopped before the data was committed is started once more; one
that stopped after the commit is closed as `failed_after_commit` and never run again."
AdminBackupRestorePhase:
type: string
enum: