statedb

package
v1.0.7 Latest Latest
Warning

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

Go to latest
Published: Oct 23, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Index

Constants

View Source
const (

	// TxStatusTableName is the name of the system table holding per-transaction status.
	TxStatusTableName = "tx_status"
)

Variables

View Source
var (

	// ErrDatabaseNotFound reports that a pool was opened against a database that does
	// not exist (SQLSTATE 3D000, invalid_catalog_name). It is exposed so a caller whose
	// database is guaranteed to exist can tell this apart from a connection failure and
	// treat it as the invariant violation it is, rather than retrying it.
	ErrDatabaseNotFound = errors.New("database does not exist")
)
View Source
var ErrUnexpectedSnapshotStatus = errors.New("unexpected _snapshot record status")

ErrUnexpectedSnapshotStatus reports that the locked `_snapshot` record was not in a status its caller required, so the update was not applied. It is not a fault: a concurrent checkpoint reaches it legitimately. It is never retryable, because the record has moved on -- re-reading cannot restore the caller's premise, and the caller must re-decide what to do from the new status.

View Source
var LatestSnapshotPointerKey = []byte("latest snapshot key")

LatestSnapshotPointerKey is the `metadata`-table key whose value is the tx_id of the most recently accepted `_snapshot` record, so a reader can look up that record's current status with a single key lookup instead of scanning the (small but growing) ns__snapshot table. Pre-seeded (NULL) at DB init and written atomically, in the same DB transaction as the `_snapshot` row it points to, by the validator-committer's commit path.

Functions

func ConfigureConnReadDeadline

func ConfigureConnReadDeadline(poolConfig *pgxpool.Config)

ConfigureConnReadDeadline configures pool connections with a per-read deadline so that reads on dead connections fail instead of hanging indefinitely.

We use a custom DialFunc that wraps every net.Conn with deadlineConn, which calls SetReadDeadline before each Read. Pool callbacks like AfterConnect or BeforeAcquire only fire once, so they can only set a single absolute deadline that expires even if the connection is healthy. Wrapping net.Conn lets us reset the deadline on every Read call.

The read timeout is set to 60 seconds, which is more than enough for read-set validation and commit operations. This can be made configurable if needed.

On macOS, Docker Desktop runs a userspace TCP proxy inside a Linux VM. When a container dies the proxy does not immediately close forwarded connections, so reads hang indefinitely. The deadlineConn wrapper ensures stuck reads fail within the timeout, allowing the pool to replace them. On Linux, reads already fail immediately via TCP RST when a node dies, so the wrapper is harmless.

func DataSourceName

func DataSourceName(d DataSourceNameParams) (string, error)

DataSourceName returns the data source name of the database.

func DecodeSnapshotState added in v1.0.6

func DecodeSnapshotState(raw []byte) (*committerpb.SnapshotState, error)

DecodeSnapshotState unmarshals a `_snapshot` record value.

func EncodeSnapshotState added in v1.0.6

func EncodeSnapshotState(state *committerpb.SnapshotState) ([]byte, error)

EncodeSnapshotState marshals a `_snapshot` record value.

func FmtNsID

func FmtNsID(sqlTemplate, namespaceID string) string

FmtNsID replaces the namespace placeholder with the namespace ID in an SQL template string.

func GetTablePreSplitTablets

func GetTablePreSplitTablets(ctx context.Context, pg *pgxpool.Pool, config *Config) (int, error)

GetTablePreSplitTablets determines the number of tablets to use for table pre-splitting. Returns 0 for PostgreSQL or when TablePreSplitTablets is not configured. Returns the configured value for YugabyteDB.

func IsYugabyteDB

func IsYugabyteDB(ctx context.Context, pool *pgxpool.Pool) (bool, error)

IsYugabyteDB queries the database version string to determine whether the backend is YugabyteDB. YugabyteDB's version() output contains "-YB-" (e.g., "PostgreSQL 11.2-YB-2.20.1.0 ..."), which distinguishes it from standard PostgreSQL.

func MakeNsTablesQuery

func MakeNsTablesQuery(nsID string, tablets int) string

MakeNsTablesQuery returns the query to create the table and functions for a namespace.

func MarkSnapshotCheckpointedInTx added in v1.0.6

func MarkSnapshotCheckpointedInTx(ctx context.Context, tx pgx.Tx, blockNum uint64) error

MarkSnapshotCheckpointedInTx marks the latest snapshot CHECKPOINTED in the caller's transaction. The checkpoint write and this update must commit together. Otherwise, a crash could leave the snapshot waiting for a checkpoint and block new snapshots.

An already-CHECKPOINTED record is left unchanged. A missing pointer or a different block returns a non-retryable error: the record no longer matches what was verified.

func NewPool

func NewPool(ctx context.Context, config *Config) (*pgxpool.Pool, error)

NewPool creates a new pool from a database config.

A pool open against a database that does not exist fails immediately rather than being retried: the database is provisioned before any service starts, so SQLSTATE 3D000 means the configured name is wrong or the cluster was never initialized, and no number of attempts changes either. Retrying it would spend the whole retry budget before reporting a condition that was decidable on the first try.

func SetupSystemTablesAndNamespaces

func SetupSystemTablesAndNamespaces(
	ctx context.Context, config *Config,
) error

SetupSystemTablesAndNamespaces creates the required system tables and namespaces in the database. This function should be called before operating against the database. It is safe to run multiple times.

func TableName

func TableName(nsID string) string

TableName returns the table name for the given namespace.

Types

type Config

type Config struct {
	Endpoints            []*connection.Endpoint `mapstructure:"endpoints" default:"localhost:5433"`
	Username             string                 `mapstructure:"username"`
	Password             string                 `mapstructure:"password"`
	Database             string                 `mapstructure:"database" default:"yugabyte"`
	MaxConnections       int32                  `mapstructure:"max-connections" default:"20" validate:"gt=0"`
	MinConnections       int32                  `mapstructure:"min-connections" default:"1" validate:"gte=0"`
	LoadBalance          bool                   `mapstructure:"load-balance"`
	Retry                *retry.Profile         `mapstructure:"retry" default:"max-elapsed-time=10m"`
	TLS                  TLSConfig              `mapstructure:"tls"`
	TablePreSplitTablets int                    `mapstructure:"table-pre-split-tablets"`
}

Config is the configuration for database initialization and connection. This configuration is shared across multiple services (VC, Query) and the init-db CLI command.

func (*Config) DataSourceName

func (d *Config) DataSourceName() (string, error)

DataSourceName returns the data source name of the database.

func (*Config) EndpointsString

func (d *Config) EndpointsString() string

EndpointsString returns the address:port as a string with comma as a separator between endpoints.

type DataSourceNameParams

type DataSourceNameParams struct {
	Username        string
	Password        string
	Database        string
	EndpointsString string
	LoadBalance     bool
	TLS             TLSConfig
}

DataSourceNameParams defines the parameters required to construct a database connection string.

type SnapshotStateManager added in v1.0.6

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

SnapshotStateManager reads and writes `_snapshot` records over a state-database pool. Callers hold one per process; it carries no per-record state, so it is safe to share.

func NewSnapshotStateManager added in v1.0.6

func NewSnapshotStateManager(pool *pgxpool.Pool, retryProfile *retry.Profile) *SnapshotStateManager

NewSnapshotStateManager returns a SnapshotStateManager over an already-open state-database pool. The caller keeps ownership of the pool, including closing it.

func (*SnapshotStateManager) ReadLatest added in v1.0.6

ReadLatest performs the full pointer-to-row read cycle: it looks up the latest-record pointer (LatestSnapshotPointerKey) and, when one is set, reads and decodes the `_snapshot` record it names.

Returns (nil, nil) when no snapshot has ever been accepted (pointer unset).

A pointer that names a missing row, and a row whose value does not decode, are both hard errors rather than "no snapshot": the pointer is written in the same DB transaction as the row it names, so either state is corruption. Reporting it as absent would let the validator-committer conclude no snapshot is in flight and accept a new one. Both are also non-retryable, because neither a missing row nor an undecodable value can resolve itself on a later attempt.

func (*SnapshotStateManager) Update added in v1.0.6

Update rewrites the `_snapshot` record for ref.TxId per update; TxRef and CloneDatabase are preserved because the existing record is decoded, mutated, and re-encoded rather than rebuilt.

The read and the write run inside a single DB transaction using SELECT ... FOR UPDATE (see selectSnapshotRecordForUpdateSQL), not READ COMMITTED alone: without the row lock a concurrent writer could commit between our SELECT and UPDATE, and we would still overwrite it with our stale re-encoded value, with no error at any point. The whole read-decode-mutate-encode-write sequence is retried as one unit, so a transient failure anywhere in it restarts from a fresh, consistent read.

The row lock stops a lost update; it does not stop a wrong-state transition, since this UPDATE matches on `key` alone and would apply whatever the locked row now holds. update.ExpectedStatus closes that: when set, the locked status must be one of the statuses the caller reasoned about, or the update is rejected with ErrUnexpectedSnapshotStatus. An empty ExpectedStatus keeps the write unconditional.

type SnapshotUpdate added in v1.0.6

type SnapshotUpdate struct {
	Status committerpb.SnapshotState_Status
	Digest []byte
	ErrMsg string

	// ExpectedStatus, when non-empty, aborts the update unless the locked row's status
	// is one of these; an empty slice writes unconditionally. See Update for why the row
	// lock alone does not give this.
	ExpectedStatus []committerpb.SnapshotState_Status
}

SnapshotUpdate bundles the fields SnapshotStateManager.Update can change. Status is required. A nil Digest keeps the record's existing Hash, because a status move that publishes no new digest (IN_PROGRESS) must not wipe one.

ErrMsg, by contrast, is written unconditionally: the diagnostic describes the status it arrives with, so a record that reaches COMPLETED after a failed attempt must not keep the failed attempt's error text, which would otherwise read as a completed snapshot that also failed.

type TLSConfig

type TLSConfig struct {
	Mode       string `mapstructure:"mode"`
	CACertPath string `mapstructure:"ca-cert-path"`
}

TLSConfig holds the database TLS mode and its necessary credentials.

Jump to

Keyboard shortcuts

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