Documentation
¶
Overview ¶
Package dbconn opens read-only, time-limited connections to MySQL and MariaDB servers.
Index ¶
- Variables
- func Address(cfg *mysql.Config) string
- func Describe(cfg *mysql.Config) string
- func ErrorText(err error) string
- func IsTimeout(err error) bool
- func ParseDSN(dsn, password string) (*mysql.Config, error)
- func WritePrivileges(grants []string, database string) []string
- type Row
- type Session
- type Snapshot
- func (s *Snapshot) Check(ctx context.Context) error
- func (s *Snapshot) Close() error
- func (s *Snapshot) Err() error
- func (s *Snapshot) ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
- func (s *Snapshot) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)
- func (s *Snapshot) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)
- func (s *Snapshot) QueryRowContext(ctx context.Context, query string, args ...any) *Row
- type SnapshotOptions
Constants ¶
This section is empty.
Variables ¶
var ErrBadDSN = errors.New("the DSN doesn't parse: expected user:password@tcp(host:port)/database or mysql://user:password@host:port/database")
ErrBadDSN is returned for a DSN that doesn't parse. The driver's own errors quote parts of the DSN, which can be the password, so ParseDSN returns this instead.
var ErrNotRepeatableRead = errors.New("the session did not take REPEATABLE READ, so it can't hold a snapshot")
ErrNotRepeatableRead is returned by OpenSnapshot when the session won't take REPEATABLE READ, the only level that holds a consistent snapshot.
var ErrSnapshotLost = errors.New("lost the connection that held the snapshot")
ErrSnapshotLost is returned by every call on a Snapshot after its connection or its transaction was lost: the snapshot went with it.
var ErrStatementRefused = errors.New("refused a statement the snapshot doesn't allow")
ErrStatementRefused is returned, before anything runs, for a statement a Snapshot doesn't allow: one that could end its transaction, write, lock rows or change the server. Its text never quotes the statement.
Functions ¶
func Describe ¶
Describe renders the connection target without the password, e.g. shop_ro@db.internal:3306/shop.
func ErrorText ¶ added in v0.3.0
ErrorText describes a failed statement without quoting the server's message, which can repeat bound arguments or bytes from a row. Reports and warnings use it for every statement that reads keys or values.
func IsTimeout ¶ added in v0.3.0
IsTimeout reports whether a statement was stopped by the client or server time limit.
func ParseDSN ¶
ParseDSN reads a connection string in either of these forms:
mysql://user:pass@host:3306/dbname?tls=true user:pass@tcp(host:3306)/dbname?tls=true
The URL form also accepts ?socket=/path/to/mysqld.sock. When the DSN has no password, password (usually from PRODMASK_PASSWORD) is used instead. Its errors never quote the DSN.
func WritePrivileges ¶
WritePrivileges reads SHOW GRANTS output and returns the privileges that would let the user change the given database.
Types ¶
type Row ¶ added in v0.6.0
type Row struct {
// contains filtered or unexported fields
}
Row is the result of QueryRowContext.
type Session ¶
type Session struct {
DB *sql.DB
Server model.ServerInfo
Database string
Timeout time.Duration
// ServerTimeout reports whether the server enforces Timeout itself
// (max_statement_time or max_execution_time). Without it, a statement
// the client gives up on keeps running on the server.
ServerTimeout bool
Warnings []string
}
Session is a pool of exactly one connection to the scanned database. Every connection in it is read-only, gives up waiting for metadata locks after a few seconds, and has a server-side statement timeout. Statements run one at a time, and autocommit is on, so no lock or snapshot outlives a statement. When a timeout kills the connection, database/sql opens a new one with the same settings.
type Snapshot ¶ added in v0.6.0
type Snapshot struct {
Server model.ServerInfo
Database string
// ID is the connection's CONNECTION_ID(), which another session can
// look for in the process list or end with KILL.
ID int64
// Started is when the snapshot was taken, by the local clock.
Started time.Time
// contains filtered or unexported fields
}
Snapshot is one pinned connection that sees a database as it was at one moment: a REPEATABLE READ transaction started READ ONLY, WITH CONSISTENT SNAPSHOT. Every statement runs on that connection, so InnoDB tables read minutes apart still agree with each other.
The connection is never replaced. A database/sql pool moves its work to a new connection when one breaks, which would quietly read the rest from a later moment; a pinned connection fails instead. Once the connection is lost, every later call returns ErrSnapshotLost, and the reader has to start again with a new snapshot.
The session reads TIMESTAMP values in UTC (time_zone '+00:00'), whatever the server's zone, and starts with SET NAMES utf8mb4. Statement time limits are off, since reading a whole table takes as long as it takes; waits for metadata locks are bounded. The connection may idle for as long as the server allows (wait_timeout at its maximum).
Only statements that keep the snapshot run: ExecContext takes SETs of session variables, and the query methods take reads (SELECT, SHOW, DESCRIBE, EXPLAIN, VALUES, TABLE, and WITH ... SELECT). INTO, locking reads and executable comments are refused anywhere. A refused statement returns ErrStatementRefused without running, and the snapshot stays. The rules don't vet functions, so callers must not call ones that write.
func OpenSnapshot ¶ added in v0.6.0
OpenSnapshot connects to the database in cfg and starts the snapshot.
func (*Snapshot) Check ¶ added in v0.6.0
Check confirms the snapshot still holds, so nothing was read from a later moment: the same connection answers, and its transaction is still open. SET TRANSACTION fails with error 1568 inside an open transaction; any other outcome means the transaction, and the snapshot, ended.
func (*Snapshot) Err ¶ added in v0.6.0
Err returns ErrSnapshotLost once a call found the connection lost, and nil before.
func (*Snapshot) ExecContext ¶ added in v0.6.0
ExecContext runs a SET of session variables in the snapshot's session. Anything else returns ErrStatementRefused without running.
func (*Snapshot) PrepareContext ¶ added in v0.6.0
PrepareContext prepares a read on the snapshot's connection. Queries through it use the binary protocol, which returns FLOAT and DOUBLE values exactly; the text protocol rounds them to a few digits.
func (*Snapshot) QueryContext ¶ added in v0.6.0
QueryContext runs a read in the snapshot. A connection lost while the rows are read shows up in rows.Err(), and then in every later call.
type SnapshotOptions ¶ added in v0.6.0
type SnapshotOptions struct {
// LockWait bounds how long a statement waits for a metadata lock
// (lock_wait_timeout). Default 10 seconds.
LockWait time.Duration
// NetWrite is how long the server waits for the client to take more
// rows before it gives up (net_write_timeout). A reader that writes
// each batch somewhere slow needs it long. Default 10 minutes.
NetWrite time.Duration
}
SnapshotOptions tunes the snapshot's session. Zero values pick the defaults.