dblifecycle

package
v0.70.2 Latest Latest
Warning

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

Go to latest
Published: Aug 28, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package dblifecycle is the single entry point the CLI (and, in a later phase, a gRPC surface) calls to perform database snapshot, restore, and truncate operations, so both front ends run exactly the same code path.

For now Service only supports the offline path: it opens its own *database.Database directly against the configured data directory, the same way the `load`/`mithril` CLI commands do. It must not be used concurrently with a running node (or another Service) pointed at the same data directory — a later phase adds a live-node path that quiesces a running node's storage layer first.

Index

Constants

This section is empty.

Variables

View Source
var ErrCloudPrimaryAutomaticSnapshots = errors.New(
	"automatic snapshots are unsupported with a cloud primary blob store",
)

ErrCloudPrimaryAutomaticSnapshots is returned when automatic snapshots are enabled with an S3 or GCS primary blob store. Those providers back up by iterating remote objects, so lifecycle.Snapshot would hold the database commit barrier for the whole, unbounded walk. Manual snapshots remain available because this restriction applies only to the epoch-boundary manager.

Functions

func ResolveTarget

func ResolveTarget(
	db *database.Database,
	target TruncateTarget,
) (models.Block, error)

ResolveTarget resolves target against db to a single canonical block. At least one of Slot, Hash, or BlockNumber must be set; when more than one is set, all supplied fields must agree on the same block. Exported so a live (in-process, already-open-node) truncate path can reuse the same resolution logic the offline Service.Truncate uses.

Resolution itself always goes through exactly one lookup — hash if present (the most specific identifier), else block number, else slot — per Resolve*'s existing binary-search-style implementations. Any other field the caller also supplied is then checked against the resolved block's actual Hash/Slot/Number and rejected on a mismatch, mirroring database/lifecycle.Truncate's own onLineage.Slot/Hash cross-check (target.ID/Hash/Slot must all genuinely agree before a destructive truncate proceeds) rather than silently trusting an unverified combination or, at the other extreme, rejecting a caller-supplied, mutually-consistent combination outright (e.g. an operator passing both a slot and a hash it already resolved, for extra safety).

Types

type LiveNode

type LiveNode interface {
	Snapshot(
		ctx context.Context,
		destDir string,
		name string,
		description string,
	) (lifecycle.Manifest, error)
	Restore(ctx context.Context, snapshotDir string) (lifecycle.Manifest, error)
	Truncate(
		ctx context.Context,
		target TruncateTarget,
	) (blocksRemoved uint64, err error)
}

LiveNode is satisfied by a running *dingo.Node (see node_lifecycle.go's Restore/Truncate methods there — this interface is defined here, not imported from the dingo package, specifically so dblifecycle does not need to import the root dingo package, which already imports dblifecycle for Manager; dingo.Node satisfies this interface structurally, with no additional wiring on its side.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager captures automatic database snapshots at epoch boundaries. It subscribes to event.EpochTransitionEventType on the EventBus — the same async, decoupled pattern ledger/snapshot.Manager uses for stake/reward snapshots — rather than the synchronous in-transaction hook: a multi-gigabyte database backup must never run inside the ledger's write transaction. Because Badger's Backup and SQLite's VACUUM INTO are both non-blocking for concurrent writers, this needs no node quiesce.

func NewManager

func NewManager(
	db *database.Database,
	eventBus *event.EventBus,
	cfg config.DatabaseLifecycleConfig,
	blobPluginName string,
	metadataPluginName string,
	destinationRegistry *lifecycle.DestinationRegistry,
	logger *slog.Logger,
) *Manager

NewManager creates a new automatic-snapshot manager. db and eventBus must not be nil once Start is called. blobPluginName/metadataPluginName are recorded in every automatic snapshot's manifest (the running database no longer tracks which provider names resolved its stores). destinationRegistry supplies the cloud destination schemes (s3, gcs) available for cfg.SnapshotCloudDestination — composition code owns constructing it; nil is valid when no cloud destination is configured.

func (*Manager) Start

func (m *Manager) Start(ctx context.Context) error

Start begins listening for epoch transitions and capturing automatic snapshots, if enabled. The provided context is used as the parent for the manager's internal context; cancelling it stops the manager.

func (*Manager) Stop

func (m *Manager) Stop() error

Stop stops the manager, waiting for any in-flight snapshot handler call to finish before returning — including when the context passed to Start was already cancelled externally (in which case Start's own cleanup goroutine may already be tearing things down concurrently; Stop still reliably waits for that same goroutine via loopWg, rather than racing it to separately decide the manager is already stopped and returning early — see the comment on that goroutine in Start for why two competing cleanup paths used to let Stop return before an in-flight handler call had actually exited).

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service performs database lifecycle operations against the data directory and plugins named in cfg. If bound to a LiveNode (SetLiveNode), Restore/Truncate delegate to it instead of operating offline — see SetLiveNode's doc comment for what that changes.

func NewService

func NewService(
	cfg *config.Config,
	destinationRegistry *lifecycle.DestinationRegistry,
	logger *slog.Logger,
) *Service

NewService creates a Service bound to cfg's database configuration (DatabasePath, Plugins.Storage, StorageMode, Network). destinationRegistry supplies the cloud destination schemes (s3, gcs) available for cfg.DatabaseLifecycle.SnapshotCloudDestination and any cloud snapshotDir passed to Restore — composition code owns constructing it; nil is valid when no cloud destination is ever used.

func (*Service) Restore

func (s *Service) Restore(
	ctx context.Context,
	snapshotDir string,
) (lifecycle.Manifest, error)

Restore populates the configured database's data directory from the snapshot at snapshotDir (offline mode: the data directory must not already exist, or must be empty), or — if SetLiveNode was called — quiesces and restores the bound running node's own data directory in-process instead.

func (*Service) SetLiveNode

func (s *Service) SetLiveNode(n LiveNode)

SetLiveNode binds Service to a running node. Once set, Restore/Truncate quiesce and reinitialize that node's live storage in-process instead of opening the configured data directory offline — the data directory must then be the one the live node itself is already using, since the node (not this Service) owns opening/closing it. Snapshot still never quiesces (see database/lifecycle's package doc) but also delegates, so it reads from the node's own open database instead of opening a second, competing handle on the same data directory.

func (*Service) Snapshot

func (s *Service) Snapshot(
	ctx context.Context,
	destDir string,
	name string,
	description string,
) (lifecycle.Manifest, error)

Snapshot captures a point-in-time backup of the configured database into destDir, which must not already exist, or — if SetLiveNode was called — captures it from the bound running node's own already-open database instead of opening a second, competing handle on the same data directory. name/description are applied to the local manifest before any cloud mirroring, per lifecycle.SnapshotToCloud's doc comment — pass "" for either to leave a snapshot unlabeled.

func (*Service) Truncate

func (s *Service) Truncate(
	ctx context.Context,
	target TruncateTarget,
) (uint64, error)

Truncate reverts the configured database to target: target becomes the new chain tip and everything after it is removed, per database/lifecycle.Truncate (offline mode), or — if SetLiveNode was called — quiesces and truncates the bound running node's own database in-process instead. Returns the number of blocks removed.

type TruncateTarget

type TruncateTarget struct {
	Slot        *uint64
	Hash        []byte
	BlockNumber *uint64
}

TruncateTarget identifies a truncate target by at least one of Slot, Hash, or BlockNumber. When more than one is set, ResolveTarget requires them to agree on the same block.

Jump to

Keyboard shortcuts

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