dbmaintain

package
v0.0.6 Latest Latest
Warning

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

Go to latest
Published: Oct 16, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package dbmaintain implements VACUUM + ANALYZE maintenance for the cloop state database (Task 20107).

It complements pkg/dbverify (Task 20094 — integrity checking) and the statedb migration framework (Task 20101 — schema lifecycle) to round out the database lifecycle management story:

cloop db verify   → detect on-disk corruption (PRAGMA integrity_check)
cloop migrate     → bring schema up to current binary's version
cloop db maintain → reclaim freelist + refresh planner stats (this pkg)

Operations performed:

  • VACUUM: rewrites the database file with no free space, returning reclaimed pages to the filesystem. Required after large deletes such as `cloop compact` or step-history pruning, otherwise the file keeps its peak size forever.
  • ANALYZE: refreshes per-index statistics so the query planner picks good plans as table sizes change. Cheap; we always run it after a successful VACUUM.
  • A TRUNCATE checkpoint of the write-ahead log (Task 20392). VACUUM writes the whole database through the log, and SQLite never shrinks the log file on its own, so without it a run that handed back the freelist would leave a log the size of the database behind it.

Auto-mode logic: if the current page_count exceeds AutoGrowthThreshold times the page_count recorded after the last vacuum, run; otherwise skip. First-ever invocation always runs (there is no prior baseline to compare against).

Index

Constants

View Source
const AutoGrowthThreshold = 1.20

AutoGrowthThreshold gates --auto runs: vacuum only when the current page_count exceeds threshold × last_vacuum.page_count_after. 1.20 = "must have grown at least 20% since the last vacuum".

Variables

View Source
var ErrPeerHubLive = errors.New("dbmaintain: another hub instance is live")

ErrPeerHubLive is returned when a VACUUM is refused because another hub holds the control-plane lease. Callers match on it to print advice rather than a stack of wrapped errors.

Functions

This section is empty.

Types

type Options

type Options struct {
	// DryRun reports estimated reclaimable bytes (freelist_count × page_size)
	// without performing VACUUM or ANALYZE. Nothing is written to the DB —
	// not even a maintenance_log row.
	DryRun bool

	// Auto enables growth-gated execution. When set and a prior vacuum exists,
	// Run is a no-op unless the DB has grown >AutoGrowthThreshold since.
	// If no prior vacuum exists, Auto behaves as a normal run (so cron-style
	// usage from a fresh project does the right thing on first call).
	Auto bool

	// SkipAnalyze runs only VACUUM. Useful in tests; not exposed via CLI.
	SkipAnalyze bool

	// Retention, when non-nil, applies the audit-trail retention window
	// before vacuuming (Task 20218). Pruning without a VACUUM leaves the
	// freed pages on the freelist, so the database on disk does not shrink;
	// doing both in one pass is the only way an operator sees the 2.4 GB come
	// back. Nil disables it, which is the default and what every caller that
	// has not opted into retention gets.
	//
	// The prune runs first and its outcome is reported even when the
	// subsequent VACUUM fails — the rows really were sealed and removed, and
	// a report that hid that would send an operator looking for them.
	Retention *RetentionOptions

	// AllowConcurrentHub skips the live-peer check before VACUUM. It exists
	// for tests and for an operator who knows the lease row is stale in a way
	// the probe cannot see; it is not exposed as a plain --force because the
	// failure it unblocks is rewriting a database file underneath a running
	// hub's open connections.
	AllowConcurrentHub bool
}

Options configures Run.

type Report

type Report struct {
	DBPath string

	DryRun      bool
	AutoSkipped bool

	// Reason carries human-readable rationale for the auto-mode decision
	// ("auto: no prior vacuum recorded", "auto: page_count 12345 > 1.20×8000
	// last vacuum", "auto: skipped — DB has grown only 5% since last vacuum").
	Reason string

	Before     statedb.SizeStats
	After      statedb.SizeStats
	BytesFreed int64

	// Operations lists the actions performed in order, e.g. ["VACUUM",
	// "ANALYZE"]. Empty for dry-run or auto-skipped runs.
	Operations []string

	// Retention is the audit-prune outcome when Options.Retention was set,
	// nil otherwise. Populated for dry runs too, where it describes what
	// would have been sealed.
	Retention *auditretention.Report

	// AfterPrune is the size measured between the prune and the VACUUM. It
	// exists so an operator can see which of the two did the work: the prune
	// moves rows to the freelist, only the VACUUM returns pages to the
	// filesystem. Zero when no prune ran.
	AfterPrune statedb.SizeStats

	// LastEntry is the most recent maintenance_log row prior to this run,
	// or nil if no maintenance has been recorded before. Populated for both
	// dry-run and real runs so the UI/CLI can surface "last maintained N ago".
	LastEntry *statedb.MaintenanceLogEntry

	// EstimatedReclaim is the dry-run estimate of bytes that VACUUM could
	// reclaim, derived from freelist_count × page_size. Only populated when
	// DryRun is true.
	EstimatedReclaim int64

	// WALBefore and WALAfter are the write-ahead log's size when the run
	// began and when it ended (Task 20392). A run that changed nothing — a
	// dry run, an --auto skip, a refusal — reports the same size twice.
	WALBefore int64
	WALAfter  int64
	// WALCheckpoint is the TRUNCATE checkpoint a real run ends with, nil when
	// none ran. Busy means another connection was still using the log; the
	// log keeps its size and nothing failed.
	WALCheckpoint *statedb.WALCheckpoint
}

Report summarises a maintain run.

func Run

func Run(dbPath string, opts Options) (*Report, error)

Run opens the database at dbPath, performs the requested maintenance, and returns a Report. The connection is opened via statedb.Open so any pending schema migrations (including 0002_maintenance_log) run first.

type RetentionOptions

type RetentionOptions struct {
	// Days is the retention window. Rows older than this are sealed and
	// removed. Must be positive; zero means the caller did not want
	// retention and should have left Options.Retention nil.
	Days int

	// ExportDir is where sealed prefixes are written.
	ExportDir string

	// Actor is recorded on the anchor.
	Actor string

	// ControlPlane is the control-plane database whose audit-forward cursors
	// hold this chain (Task 20426). Empty looks in the database itself and in
	// the control plane its forwarded-by record names; see
	// auditforward.RetentionHold.
	ControlPlane string

	// Force prunes past the rows the audit sinks have acknowledged.
	Force bool
}

RetentionOptions is the audit-retention half of a maintain run.

Jump to

Keyboard shortcuts

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