pitr

package
v1.0.13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 28, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package pitr implements point-in-time recovery via pg_basebackup and WAL archiving.

The catalog (~/.nself/wal-catalog.json) tracks base backup timestamps and WAL segment metadata. The recovery orchestrator uses the catalog to locate the correct base backup and WAL segments for a given target time.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CatalogPath

func CatalogPath() (string, error)

CatalogPath returns the default catalog path.

func Disable

func Disable(cfg *config.Config) error

Disable removes the PITR configuration snippet so that WAL archiving stops on the next container restart.

func Enable

func Enable(cfg *config.Config, pitrCfg EnableConfig) error

Enable writes the PostgreSQL configuration snippet that activates WAL archiving. The snippet is written to:

.nself/pitr/postgresql.conf.d/pitr.conf

Mount this file into the PostgreSQL container to activate PITR.

func ParseTargetTime

func ParseTargetTime(s string) (time.Time, error)

ParseTargetTime parses a target time string in one of two forms:

  • RFC3339 absolute: "2026-04-22T15:30:00Z"
  • Relative duration: "30 minutes ago", "2 hours ago", "1 day ago"

Returns the resolved UTC time or an error.

func PruneRetention

func PruneRetention(ctx context.Context, catalogPath string, opts PruneOptions) (int, error)

PruneRetention removes catalog entries and (optionally) remote/local files older than the configured retention window. Returns the number of entries pruned.

func Restore

func Restore(ctx context.Context, cfg *config.Config, opts RestoreOptions) error

Restore orchestrates a full PITR restore to TargetTime using the WAL catalog and the project's Postgres container.

High-level steps:

  1. Load catalog and locate the latest base backup before TargetTime.
  2. Download and optionally decrypt the base backup.
  3. Write postgresql.auto.conf with recovery_target_time.
  4. Stop Postgres, replace data dir, start Postgres in recovery mode.
  5. Poll until recovery completes (pg_is_in_recovery() returns false).

func TakeBaseBackup

func TakeBaseBackup(ctx context.Context, cfg *config.Config, destDir, encryptRecipient string) (string, time.Time, error)

TakeBaseBackup runs pg_basebackup against the project's Postgres container and stores the resulting tar archive at destDir. If encryptRecipient is non-empty the archive is encrypted with age before writing.

Returns the path to the written archive file and the backup timestamp.

Types

type BaseBackup

type BaseBackup struct {
	Timestamp time.Time `json:"timestamp"`
	RemoteKey string    `json:"remote_key"` // e.g. pitr/base/20260422T020000.tar.age
	SizeBytes int64     `json:"size_bytes,omitempty"`
}

BaseBackup describes a pg_basebackup snapshot stored at a remote destination.

type Catalog

type Catalog struct {
	BaseBackups []BaseBackup `json:"base_backups"`
	WALSegments []WALSegment `json:"wal_segments"`
}

Catalog is the on-disk PITR catalog stored at ~/.nself/wal-catalog.json.

func LoadCatalog

func LoadCatalog(path string) (*Catalog, error)

LoadCatalog reads the catalog from disk. Returns an empty catalog if the file does not exist yet.

func (*Catalog) AddBaseBackup

func (c *Catalog) AddBaseBackup(path string, bb BaseBackup) error

AddBaseBackup appends a new base backup entry and saves the catalog.

func (*Catalog) AddWALSegment

func (c *Catalog) AddWALSegment(path string, seg WALSegment) error

AddWALSegment appends a WAL segment entry and saves the catalog.

func (*Catalog) LatestBaseBackupBefore

func (c *Catalog) LatestBaseBackupBefore(target time.Time) (BaseBackup, error)

LatestBaseBackupBefore returns the most recent base backup whose timestamp is at or before target. Returns an error if no suitable backup exists.

func (*Catalog) NewestWALTime

func (c *Catalog) NewestWALTime() (time.Time, bool)

NewestWALTime returns the end time of the latest WAL segment.

func (*Catalog) OldestRecoverableTime

func (c *Catalog) OldestRecoverableTime() (time.Time, bool)

OldestRecoverableTime returns the start of the earliest WAL segment, or the earliest base backup timestamp — whichever is earlier.

func (*Catalog) PruneOlderThan

func (c *Catalog) PruneOlderThan(cutoff time.Time) (pruned int)

PruneOlderThan removes base backups and WAL segments older than the cutoff from the in-memory catalog. Call Save() after to persist.

func (*Catalog) Save

func (c *Catalog) Save(path string) error

Save persists the catalog to disk atomically (write to temp file, then rename).

func (*Catalog) WALSegmentsForRange

func (c *Catalog) WALSegmentsForRange(start, end time.Time) []WALSegment

WALSegmentsForRange returns WAL segments whose time range overlaps [start, end].

type EnableConfig

type EnableConfig struct {
	Destination       string // remote destination URL (s3://, r2://, etc.)
	EncryptRecipient  string // age public key recipient for encryption
	RetentionDays     int    // WAL retention window in days
	WALArchiveTimeout int    // archive_timeout in seconds
}

EnableConfig holds the PITR enable options.

type PruneOptions

type PruneOptions struct {
	// RetentionDays is the number of days to retain WAL segments and base
	// backups. Segments older than Now()-RetentionDays are deleted.
	RetentionDays int

	// RemoteDeleteFn is called for each remote key that should be deleted.
	// Implementations must be idempotent (safe to call on already-deleted keys).
	// If nil, only the catalog is updated (no remote deletion).
	RemoteDeleteFn func(ctx context.Context, key string) error

	// LocalBaseBackupDir is the directory where local base backup archives are
	// stored. Files in this directory whose names match pruned entries are
	// removed. Set to "" to skip local file deletion.
	LocalBaseBackupDir string
}

PruneOptions holds configuration for the retention pruning pass.

type RestoreOptions

type RestoreOptions struct {
	// TargetTime is the point in time to recover to. The database will be
	// restored to the state it held at this timestamp.
	TargetTime time.Time

	// CatalogPath is the path to the WAL catalog. Defaults to ~/.nself/wal-catalog.json.
	CatalogPath string

	// IdentityPath is the path to the age identity file for decrypting encrypted
	// base backups and WAL segments. Required if segments are encrypted.
	IdentityPath string

	// WorkDir is a scratch directory for the restore operation. Defaults to a
	// OS temp directory under pitr-restore-*.
	WorkDir string

	// AutoPromote, when true, calls pg_ctl promote after recovery completes.
	AutoPromote bool

	// ContainerName overrides the Postgres container name derived from cfg.
	ContainerName string
}

RestoreOptions holds options for a PITR restore operation.

type WALSegment

type WALSegment struct {
	Start     time.Time `json:"start"`
	End       time.Time `json:"end"`
	RemoteKey string    `json:"remote_key"`
}

WALSegment describes a single archived WAL segment.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL