sqlitedisk

package
v0.16.2 Latest Latest
Warning

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

Go to latest
Published: Sep 29, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

Package sqlitedisk replicates SQLite-provider disks from a runner to the coordinator's backup API. It supplies litestream with a ReplicaClient that speaks Miren RPC instead of S3, and a Manager that owns one replicated database per attached disk.

Index

Constants

View Source
const ReplicaClientType = "miren"

ReplicaClientType identifies this backend in litestream's logs.

Variables

This section is empty.

Functions

func BackupKey

func BackupKey(appID, volumeName string) string

BackupKey builds a coordinator backup key for one app's disk.

The coordinator uses the key as a single directory name and rejects anything that is not [a-zA-Z0-9][a-zA-Z0-9._-]*, while app IDs contain a slash and volume names are user-supplied. Sanitizing alone could collide (two distinct inputs mapping to the same safe string), so a digest of the exact input is appended to keep distinct disks distinct.

func EnsureDatabase

func EnsureDatabase(path string) error

EnsureDatabase makes sure a SQLite database exists at path and is in WAL mode, which litestream requires in order to replicate it.

It is safe to call on an existing database: opening it and setting the journal mode it already has is a no-op, so a restored database is left exactly as it was.

Types

type Manager

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

Manager owns the replicated databases for every SQLite-provider disk attached on this node: one litestream.DB per backup key, each replicating to the coordinator.

A nil *Manager is usable and does nothing. That keeps the runner's wiring simple when the coordinator backup service is unreachable — disks still attach and apps still run, they just are not backed up.

func NewManager

func NewManager(log *slog.Logger, client *sqlitebackup_v1alpha.SqliteBackupClient) *Manager

NewManager returns a Manager replicating through client.

func (*Manager) Close

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

Close stops replicating every database. Errors are collected so one failing database cannot strand the others still running.

func (*Manager) DeregisterOwner

func (m *Manager) DeregisterOwner(ctx context.Context, owner string) error

DeregisterOwner releases everything an owner registered, stopping replication for any database it was the last owner of.

Teardown calls this rather than deriving keys again, because the entities the keys came from may already be deleted. Unknown owners are ignored so teardown can run unconditionally.

func (*Manager) Register

func (m *Manager) Register(ctx context.Context, owner, key, dbPath string) error

Register attaches owner to the database at dbPath, restoring it from the coordinator first when this node has no copy, and begins replicating it.

Registering a key that is already replicated adds owner to it rather than starting a second replicator: the database keeps replicating until every owner has released it. Re-registering the same owner is a no-op.

Restore happens before replication starts, so a database that exists locally is never overwritten by a backup — EnsureExists only acts on a missing file, and succeeds when there is no backup to restore (a genuinely new disk).

type ReplicaClient

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

ReplicaClient stores a single database's LTX files on the coordinator.

func NewReplicaClient

func NewReplicaClient(log *slog.Logger, client *sqlitebackup_v1alpha.SqliteBackupClient, key string) *ReplicaClient

NewReplicaClient returns a client that stores files under key.

func (*ReplicaClient) DeleteAll

func (c *ReplicaClient) DeleteAll(ctx context.Context) error

DeleteAll discards every file stored for this database.

func (*ReplicaClient) DeleteLTXFiles

func (c *ReplicaClient) DeleteLTXFiles(ctx context.Context, a []*ltx.FileInfo) error

DeleteLTXFiles removes the named files. Files already gone are not an error.

func (*ReplicaClient) Init

func (c *ReplicaClient) Init(ctx context.Context) error

Init is a no-op: the RPC connection is established before the client is built.

func (*ReplicaClient) LTXFiles

func (c *ReplicaClient) LTXFiles(ctx context.Context, level int, seek ltx.TXID, useMetadata bool) (ltx.FileIterator, error)

LTXFiles lists the files stored at a level, starting at seek.

useMetadata is ignored: the coordinator stamps each file's transaction timestamp onto its mtime at write time, so listed timestamps are always the accurate ones and never need a second metadata fetch.

func (*ReplicaClient) OpenLTXFile

func (c *ReplicaClient) OpenLTXFile(ctx context.Context, level int, minTXID, maxTXID ltx.TXID, offset, size int64) (io.ReadCloser, error)

OpenLTXFile streams one file back from the coordinator.

The RPC call pushes bytes into a pipe and only returns once the transfer finishes, so it runs in the background while the caller reads. Peeking a single byte before returning forces a failure that happened before any data was sent — a missing file, most importantly — to surface here rather than on a later Read, because litestream branches on os.IsNotExist at the call site.

func (*ReplicaClient) SetLogger

func (c *ReplicaClient) SetLogger(logger *slog.Logger)

func (*ReplicaClient) Type

func (c *ReplicaClient) Type() string

func (*ReplicaClient) WriteLTXFile

func (c *ReplicaClient) WriteLTXFile(ctx context.Context, level int, minTXID, maxTXID ltx.TXID, rd io.Reader) (*ltx.FileInfo, error)

WriteLTXFile uploads a file and returns the metadata the coordinator recorded.

Jump to

Keyboard shortcuts

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