lnd/kvdb/postgres/db.go
ziggie 9f97c49adf
kvdb/sqlbase: add postgres migration bulk support
This commit implements MigrationBulkKVStore for Postgres/pgx. The
Postgres wrapper is available through an explicit constructor, so
regular Postgres and shared SQLite backends do not expose the migration
capability accidentally.

The bulk load transaction pins a dedicated *sql.Conn. InsertLeaves streams
rows through pgx COPY inside that transaction. The copied row count is
checked against the input to catch partial loads. Bucket rows are inserted
individually with RETURNING id so nested buckets can reference their parent.

Verification uses a read-only repeatable-read transaction. It fetches
children of a parent-id batch with a native pgx bigint-array and a single
ANY($1) query.

Migration transactions honor the WithTxLevelLock used by regular
transactions. Loads take the write lock and verification takes the
read lock. Commit and Rollback release both the lock and the dedicated
connection. Rollback is idempotent and tolerates an already-closed
transaction.
2026-07-16 12:51:56 -03:00

49 lines
1.6 KiB
Go

//go:build kvdb_postgres
package postgres
import (
"context"
"github.com/btcsuite/btcwallet/walletdb"
"github.com/lightningnetwork/lnd/kvdb/sqlbase"
)
// sqliteCmdReplacements defines a mapping from some SQLite keywords and phrases
// to their postgres counterparts.
var sqliteCmdReplacements = sqlbase.SQLiteCmdReplacements{
"BLOB": "BYTEA",
"INTEGER PRIMARY KEY": "BIGSERIAL PRIMARY KEY",
}
// newSQLBaseConfig builds the shared sqlbase config used by both the regular
// and migration Postgres backends from the passed backend config and prefix.
func newSQLBaseConfig(config *Config, prefix string) *sqlbase.Config {
return &sqlbase.Config{
DriverName: "pgx",
Dsn: config.Dsn,
Timeout: config.Timeout,
Schema: "public",
TableNamePrefix: prefix,
SQLiteCmdReplacements: sqliteCmdReplacements,
WithTxLevelLock: config.WithGlobalLock,
}
}
// newPostgresBackend returns a db object initialized with the passed backend
// config. If postgres connection cannot be established, then returns error.
func newPostgresBackend(ctx context.Context, config *Config, prefix string) (
walletdb.DB, error) {
return sqlbase.NewSqlBackend(ctx, newSQLBaseConfig(config, prefix))
}
// NewMigrationBackend returns a Postgres backend that explicitly exposes the
// migration-only bulk KV interface.
func NewMigrationBackend(ctx context.Context, config *Config, prefix string) (
sqlbase.MigrationBackend, error) {
return sqlbase.NewPostgresBackend(
ctx, newSQLBaseConfig(config, prefix),
)
}