feat(backup): 玩过的世界每天在停服后自动打一个定时恢复点,按服按 owner 保留 7 个、90 天过期

This commit is contained in:
Lemon-miaow committed 2026-09-27 00:02:49 +08:00
1 parent d6e1a6464c
commit 8ef7112dab
29 files changed
+1028 -59

No files matched your search

+9 -7
View File
@@ -123,15 +123,17 @@ func (s *PGStore) EvictableBackups(ctx context.Context) ([]StoredBackup, error)
return s.queryBackups(ctx, q)
}
// ExcessBackups lists server's present backups of one reason beyond the newest
// keep, oldest first: what the backup Job removes after adding one. protect, when
// set, is a backup id left out of the list whatever its age (the one a chained
// restore is about to extract).
func (s *PGStore) ExcessBackups(ctx context.Context, server, reason string, keep int, protect string) ([]StoredBackup, error) {
// ExcessBackups lists the present backups of one reason that owner holds of
// server beyond the newest keep, oldest first: what the backup Job removes after
// adding one. Another owner's backups of the same server (one it held before the
// world was reaped and claimed again) are theirs to restore and never counted.
// protect, when set, is a backup id left out of the list whatever its age (the
// one a chained restore is about to extract).
func (s *PGStore) ExcessBackups(ctx context.Context, server, owner, reason string, keep int, protect string) ([]StoredBackup, error) {
const q = `SELECT id, server_name, backup_ref, size_bytes, reason, COALESCE(sha256, '') FROM world_backups
WHERE server_name = $1 AND status = 'present' AND reason = $2 AND id <> $4
WHERE server_name = $1 AND COALESCE(former_owner, '') = $5 AND status = 'present' AND reason = $2 AND id <> $4
ORDER BY corrupt_at IS NULL DESC, created_at DESC OFFSET $3`
out, err := s.queryBackups(ctx, q, server, reason, keep, protect)
out, err := s.queryBackups(ctx, q, server, reason, keep, protect, owner)
for i, j := 0, len(out)-1; i < j; i, j = i+1, j-1 {
out[i], out[j] = out[j], out[i]
}
+12
View File
@@ -96,6 +96,14 @@ type Config struct {
// ManualCooldown is the shortest gap between two owner-requested backups
// of one server (default 10m); operators are not held to it.
ManualCooldown time.Duration
// ScheduledEvery is the spacing of the restore points felis-api takes of
// a world that has been played since its last one (default 1d; 0 turns
// them off). ScheduledKeep caps how many a server keeps (default 7), and
// ScheduledRetention is how long each is kept (default 90d, the reaper's
// retention): the newest ones are all a quiet world has.
ScheduledEvery time.Duration
ScheduledKeep int
ScheduledRetention time.Duration
// RequireOffsite holds each deletion until the world's archive has its
// off-site copy ([offsite] configured; internal/offsite records the copy).
// The archive is written on the run that finds the world idle, and the
@@ -124,6 +132,10 @@ func DefaultConfig() Config {
ManualKeep: 5,
ManualCooldown: 10 * time.Minute,
ScheduledEvery: Day,
ScheduledKeep: 7,
ScheduledRetention: 90 * Day,
VerifyEvery: 7 * Day,
VerifyPerRun: 10,
PartialAfter: 6 * time.Hour,