Skip to content

[Backport release-1.5] fix(backups/postgres): purge stale recovery cluster on repeat in-place restore - #3321

Merged
myasnikovdaniil merged 2 commits into
release-1.5from
backport-3318-to-release-1.5
Aug 4, 2026
Merged

myasnikovdaniil merged 2 commits into
release-1.5from
backport-3318-to-release-1.5

Conversation

@github-actions

Copy link
Copy Markdown

Description

Backport of #3318 to release-1.5.

@dosubot dosubot Bot added area/database Issues or PRs related to managed databases (postgres, mariadb, redis, etcd, kafka, clickhouse) kind/backport Categorizes issue or PR as requiring a backport to the current release line kind/bug Categorizes issue or PR as related to a bug labels Jul 16, 2026
…e restore

A repeat in-place PostgreSQL RestoreJob into an already-restored target
silently no-opped: the destructive purge was skipped because the live
Cluster still carried spec.bootstrap.recovery left over from the previous
restore, and the re-purge guard mistook that for a freshly-recovered
Cluster produced by this restore's own purge. The job then reported
Succeeded while the PVC, disk, and data were never touched.

Tell the two apart by the Cluster's creationTimestamp relative to the
RestoreJob's StartedAt: only a recovery Cluster created at/after StartedAt
is treated as this restore's own and skipped; one that predates StartedAt
is leftover from an earlier completed restore and is purged so the restore
re-bootstraps from the backup.

Signed-off-by: Ivan Okhotnikov <[email protected]>
(cherry picked from commit cf1b6ba)
(cherry picked from commit c85c9f3)
(cherry picked from commit 507a48762292665343195da99913d64d4b256906)
…onservative freshness tie

Address review feedback on the repeat in-place restore fix:

- Make the freshness discriminator strict (creationTimestamp > StartedAt) so
  an exact tie resolves to "not fresh" and the caller purges, matching the
  function's stated conservative default; a fresh Cluster is always created
  well after StartedAt so this never misclassifies the status-write-race path.
- Document why a wall-clock timestamp comparison was chosen over recording the
  purged Cluster's UID on the TargetPurged condition (the UID approach leans on
  the same status write the race path assumes can fail).
- Add a reconcile-level regression test that drives reconcileCNPGRestore end to
  end with a fake client: a stale leftover recovery Cluster from a prior restore
  is purged, and a Cluster this restore just re-created is not re-purged. This
  covers the actual call site where #3311 lived, not just the pure helpers.

Signed-off-by: Ivan Okhotnikov <[email protected]>
(cherry picked from commit a8494d8)
(cherry picked from commit 0fdf3b5)
(cherry picked from commit 2d6083ccb6f418a35ba1ae058b3a91f7edcc89fd)
@myasnikovdaniil
myasnikovdaniil force-pushed the backport-3318-to-release-1.5 branch from 0fdf3b5 to 629a972 Compare July 31, 2026 05:27
@github-actions github-actions Bot added area/release Issues or PRs related to release tooling (changelog, backport, release pipeline) size/L This PR changes 100-499 lines, ignoring generated files labels Jul 31, 2026
@myasnikovdaniil
myasnikovdaniil merged commit b3204c5 into release-1.5 Aug 4, 2026
8 checks passed
@myasnikovdaniil
myasnikovdaniil deleted the backport-3318-to-release-1.5 branch August 4, 2026 08:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/database Issues or PRs related to managed databases (postgres, mariadb, redis, etcd, kafka, clickhouse) area/release Issues or PRs related to release tooling (changelog, backport, release pipeline) kind/backport Categorizes issue or PR as requiring a backport to the current release line kind/bug Categorizes issue or PR as related to a bug size/L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants