Skip to content

backup (stage C, enterprise): include cold-tier objects in backups and restores #1086

Closed

Description

@xe-nvdk

⚠️ Internal work only. Community contributions are not being accepted for this issue.

This is part of a four-stage piece of planned work on backups (per-database scoping, remote targets, cluster safety, cold tier) that Basekick Labs is implementing internally. Please do not open PRs against it; they will be closed without review. Discussion and questions in the comments are welcome.

Stages: 0 cluster safety #1083 → A database scoping #1084 → B remote targets #1085 → C cold tier #1086. Order is fixed; A and B can ship to OSS before 0 only if the docs say "not for clusters yet", and the node gate from 0 lands before any of them is advertised to a cluster. Origin: a prospect asked for a different backup target per database (their audit database to its own bucket). For an audit database, long retention and mostly cold, the answer is complete only with C.

Summary

A backup walks the hot backend only (dataStorage.ListObjects(ctx, ""), internal/backup/backup.go:114). Cold-tier objects live in a separate backend and tiering deletes a migrated file's Raft manifest entry (cmd/arc/main.go:4533-4558), so cold files are in neither the listing nor the manifest. For an audit database with long retention, most of the data is cold, so a per-database backup of it would be mostly empty today and the operator would not notice until a restore. The remote-targets stage makes that visible with an INCOMPLETE marker; this stage makes the backup contain the data.

Changes

  • The cold walk cannot reuse the cluster-safety stage's manifest cross-check, since cold entries are gone from the manifest. It walks the cold backend for the scoped databases guided by the tier rows (internal/tiering, per-node since fix(tiering): keep a cluster node's tier metadata in step with its own disk #1062; the rows on a just-promoted primary may lag, so the walk reconciles rows against the cold listing and reports the difference).
  • The backup manifest records the tier per file.
  • Restore writes cold files back to the node's cold tier when it has one, recording the tier row, or to hot otherwise, reported as a count; the query layer routes from tier rows, so the row is what makes the restored file queryable.
  • Per-target routing applies to cold files the same way as hot ones.
  • Enterprise: tiering is licence-gated, so this stage inherits the gate; no new CanUseX.

Matrix rows

Configuration Expected
Standalone with tiering, scoped db partly cold hot and cold files both in the backup; manifest records tier
Restore onto a node with a cold tier cold files to cold, rows recorded
Restore onto a node without a cold tier cold files to hot, counted
Pattern 1, primary just promoted, tier rows lagging walk reconciles rows against the cold listing; difference reported
Pattern 2 cold bucket is shared; files written once
Cold backend unreachable mid-run run fails; stated in status

Acceptance

Regression tests that fail on main for the cold walk, tier recorded per file, both restore destinations. A binary run against the SeaweedFS cold tier with a scoped database that has cold rows, backup then restore, verify the measurement is queryable without a manual tiering scan. Release note in RELEASE_NOTES_2027.01.1.md; docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpriority: mediumCorrectness or operability gap with a workaround

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions