mirror of
https://github.com/lightningnetwork/lnd.git
synced 2026-08-13 12:32:48 +02:00
This commit introduces a migration-only interface set that lets the KV-to-SQL migration load and verify the raw SQL KV schema directly, bypassing the walletdb/kvdb bucket abstraction. Normal application code continues to use the bucket APIs; these helpers exist solely to make the one-time bulk migration fast and verifiable. MigrationBulkKVStore is the entry point. It exposes CheckEmpty to guard against migrating into a populated table, TruncateTargetTable to recover from an interrupted fresh-only attempt, and two transaction openers: BeginBulk for loading and BeginBulkVerify for batched verification. The write path inserts buckets one at a time to obtain generated ids. It inserts leaves in batches, leaving the concrete bulk strategy to the backend. The read path walks the tree level with FetchTopLevel and FetchChildren. MigrationBulkChild uses an explicit IsBucket flag rather than inspecting the value column. This prevents an empty leaf value from being confused with the SQL NULL marker used for buckets. The interfaces use the same build constraints as the SQL kvdb backends. Backends expose the migration capability explicitly; the first concrete implementation is Postgres-only.
109 lines
3.7 KiB
Go
109 lines
3.7 KiB
Go
//go:build kvdb_postgres || (kvdb_sqlite && !(windows && (arm || 386)) && !(linux && (ppc64 || mips || mipsle || mips64)))
|
|
|
|
package sqlbase
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/btcsuite/btcwallet/walletdb"
|
|
)
|
|
|
|
// MigrationBackend combines the regular walletdb database operations with the
|
|
// migration-only bulk capabilities guaranteed by a migration backend.
|
|
type MigrationBackend interface {
|
|
walletdb.DB
|
|
MigrationBulkKVStore
|
|
}
|
|
|
|
// MigrationBulkKVStore exposes migration-only helpers for loading and verifying
|
|
// the SQL KV schema directly. Normal application code should continue to use
|
|
// the walletdb/kvdb bucket APIs.
|
|
type MigrationBulkKVStore interface {
|
|
// CheckEmpty returns whether the underlying KV table has no rows.
|
|
CheckEmpty(ctx context.Context) (bool, error)
|
|
|
|
// TruncateTargetTable unconditionally and irreversibly removes every
|
|
// row from the underlying KV table. It is only intended for fresh-only
|
|
// migration recovery when the caller owns the whole target table.
|
|
TruncateTargetTable(ctx context.Context) error
|
|
|
|
// BeginBulk opens a destination write transaction for bulk loading.
|
|
// Callers must defer Rollback immediately after a successful open; the
|
|
// rollback is a no-op after Commit and releases locks/connections on
|
|
// all other exits.
|
|
BeginBulk(ctx context.Context) (MigrationBulkKVTx, error)
|
|
|
|
// BeginBulkVerify opens a read transaction for batched verification.
|
|
// Callers must defer Rollback immediately after a successful open so
|
|
// the read transaction lock is always released.
|
|
BeginBulkVerify(ctx context.Context) (MigrationBulkKVVerifier, error)
|
|
}
|
|
|
|
// MigrationBulkLeaf is a leaf key/value row to be inserted under ParentID.
|
|
// ParentID must be a positive row ID returned by InsertBucket. Top-level leaves
|
|
// are not supported by the migration bulk API.
|
|
type MigrationBulkLeaf struct {
|
|
ParentID int64
|
|
|
|
// Key must be non-empty.
|
|
Key []byte
|
|
Value []byte
|
|
}
|
|
|
|
// MigrationBulkKVTx is a migration-only transaction for bulk-loading SQL KV
|
|
// data.
|
|
type MigrationBulkKVTx interface {
|
|
// InsertBucket inserts a bucket row with a non-empty key. It returns
|
|
// the generated id. A nil parentID creates a top-level bucket.
|
|
InsertBucket(ctx context.Context, parentID *int64, key []byte,
|
|
seq uint64) (int64, error)
|
|
|
|
// InsertLeaves inserts leaf rows with non-empty keys. Implementations
|
|
// may choose COPY, multi-row INSERT, or another backend-specific
|
|
// strategy.
|
|
InsertLeaves(ctx context.Context, leaves []MigrationBulkLeaf) error
|
|
|
|
// Commit atomically commits the bulk load transaction.
|
|
Commit() error
|
|
|
|
// Rollback aborts the bulk load transaction.
|
|
Rollback() error
|
|
}
|
|
|
|
// MigrationBulkChild is a single SQL KV row returned by the verifier helpers.
|
|
type MigrationBulkChild struct {
|
|
// ID is the SQL row id.
|
|
ID int64
|
|
|
|
// ParentID is nil for top-level rows.
|
|
ParentID *int64
|
|
|
|
// Key is the bucket key or leaf key.
|
|
Key []byte
|
|
|
|
// Value is the leaf value. It is nil for buckets.
|
|
Value []byte
|
|
|
|
// IsBucket identifies bucket rows explicitly. This avoids ambiguity
|
|
// between SQL NULL bucket markers and empty leaf values decoded as nil.
|
|
IsBucket bool
|
|
|
|
// Sequence is the bucket sequence number. It is zero for unset
|
|
// sequences and for leaf rows.
|
|
Sequence uint64
|
|
}
|
|
|
|
// MigrationBulkKVVerifier reads SQL KV rows in batches for migration
|
|
// verification.
|
|
type MigrationBulkKVVerifier interface {
|
|
// FetchTopLevel returns all top-level rows ordered by key.
|
|
FetchTopLevel(ctx context.Context) ([]MigrationBulkChild, error)
|
|
|
|
// FetchChildren returns direct children for the given bucket ids,
|
|
// ordered by parent id and key.
|
|
FetchChildren(ctx context.Context,
|
|
parentIDs []int64) ([]MigrationBulkChild, error)
|
|
|
|
// Rollback closes the verifier transaction.
|
|
Rollback() error
|
|
}
|