ormx

package module
v1.1.2 Latest Latest
Warning

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

Go to latest
Published: Jul 21, 2026 License: MIT Imports: 16 Imported by: 0

README

ormx

企业级 MySQL 数据访问封装(内部使用),单一活跃模块,包含两个包:

用途
github.com/gtkit/ormx 基于 GORM 的客户端——连接管理、集群读写分离、健康探活、事务死锁自动重试、写后读一致性窗口
github.com/gtkit/ormx/zlogger GORM 的 zap 日志适配——慢查询阈值、trace id 提取、SQL 参数脱敏

面向 go-jet 的 SQL-first 封装已分离为独立模块 github.com/gtkit/jetx

安装

go get github.com/gtkit/ormx

根包 ormx(GORM 客户端)

快速开始
import "github.com/gtkit/ormx"

client, err := ormx.Open(ctx,
    ormx.WithHost("127.0.0.1"),
    ormx.WithPort("3306"),
    ormx.WithDatabase("app"),
    ormx.WithUser("root"),
    ormx.WithPassword("secret"),
)
if err != nil {
    return err
}
defer client.Close()

db := client.DB() // *gorm.DB,直接走 GORM API
打开方式
入口 说明
ormx.Open(ctx, opts...) 按 Option 构建配置并连接,最常用
ormx.MustOpen(ctx, opts...) 同上,失败时 panic,适合启动期 wiring
ormx.OpenWithDB(ctx, sqlDB, opts...) 复用已有 *sql.DB(连接池设置仍会应用);sqlDB 所有权归调用方,Close() 不会关闭它
ormx.NewConfig(opts...) / cfg.With(opts...) / cfg.Open(ctx) 先构建 Config 值再打开,适合从配置文件映射、多实例复用基础配置

Config 是纯值类型:With 返回深拷贝后的新配置,不修改原值;Config.String() / %#v 输出自动把密码脱敏为 ******,可放心打日志。cfg.RedactedDSN() 返回脱敏后的 DSN 字符串。

base := ormx.NewConfig(
    ormx.WithHost("db.internal"),
    ormx.WithUser("app"),
    ormx.WithPassword(os.Getenv("DB_PASSWORD")),
)
orders, err := base.With(ormx.WithDatabase("orders"), ormx.WithName("orders")).Open(ctx)
users, err  := base.With(ormx.WithDatabase("users"), ormx.WithName("users")).Open(ctx)
选项函数
连接与 DSN
Option 默认值 说明
WithName(name) "default" 实例名,体现在健康报告、指标 label、事务重试事件中;多实例时建议显式设置
WithHost(host) 127.0.0.1 主机;设置后清空 Addr
WithPort(port) 3306 端口;设置后清空 Addr
WithAddress(addr) 完整地址(host:port),优先级高于 Host/Port
WithNetwork(network) tcp 网络类型(如 unix
WithDatabase(name) 数据库名
WithUser(user) 用户名
WithPassword(password) 密码(日志输出自动脱敏)
WithParseTime(enabled) true 是否把 DATETIME 解析为 time.Time
WithLocation(loc) time.Local DSN 时区
WithTimeout(d) 10s 建连超时
WithReadTimeout(d) 30s I/O 读超时
WithWriteTimeout(d) 30s I/O 写超时
WithTLSConfig(name) TLS 配置名(需先用 mysql.RegisterTLSConfig 注册)
WithCollation(collation) 驱动默认 连接 collation
WithConnectionAttributes(attrs) 连接属性(performance_schema.session_connect_attrs
WithDSNParam(key, value) 追加单个自定义 DSN 参数(如 charset
WithDSNParams(params) 批量追加 DSN 参数
连接池
Option 默认值 说明
WithMaxOpenConns(n) 50 最大打开连接数
WithMaxIdleConns(n) 10 最大空闲连接数
WithConnMaxLifetime(d) 30m 连接最大存活时间
WithConnMaxIdleTime(d) 10m 连接最大空闲时间
GORM 行为
Option 默认值 说明
WithGormLogger(log) GORM 默认 Warn 设置 gormlogger.Interface,通常配合 zlogger.New(...) 使用;未设置时输出错误 SQL 与超过 200ms 的慢 SQL
WithPrepareStmt(enabled) false 开启 PreparedStatement 缓存
WithPrepareStmtCache(maxSize, ttl) 不限制 PreparedStatement 缓存容量与 TTL
WithSkipDefaultTransaction(skip) false 跳过 GORM 单条写操作的默认事务
WithNowFunc(fn) time.Now GORM 时间函数(测试注入用)
WithNamingStrategy(strategy) IdentifierMaxLength: 64 整体替换命名策略
WithTablePrefix(prefix) 表名前缀
WithSingularTable(enabled) false 使用单数表名
WithDefaultContextTimeout(d) 0(不限制) GORM 操作默认 context 超时
WithDefaultTransactionTimeout(d) 0(不限制) GORM 事务默认超时
WithDryRun(enabled) false 只生成 SQL 不执行
WithQueryFields(enabled) false SELECT 时展开全部字段名而非 *
WithCreateBatchSize(n) 0 批量插入分批大小
WithTranslateError(enabled) false 把驱动错误翻译为 GORM 错误(如 ErrDuplicatedKey
SQL 日志开关

未传 WithGormLogger 时,GORM 使用默认 Warn 日志器向 stdout 输出错误 SQL 与超过 200ms 的慢 SQL,不记录正常快查询。日志通过 gormlogger.Interface 控制,不需要额外布尔开关:

// 完全关闭 SQL 日志
ormx.WithGormLogger(gormlogger.Discard)

// 记录错误 SQL 与慢 SQL(GORM 默认行为)
ormx.WithGormLogger(gormlogger.Default.LogMode(gormlogger.Warn))

// 记录全部 SQL,仅建议开发环境使用
ormx.WithGormLogger(gormlogger.Default.LogMode(gormlogger.Info))

生产环境需要结构化日志时,建议使用下文的 zlogger,并开启参数化查询,避免 SQL 绑定参数进入日志。

启动与健康
Option 默认值 说明
WithStartupPing(enabled) true Open 时先 Ping 验证连通性
WithStartupPingRetry(maxRetries, baseWait, maxWait) 0, 1s, 5s 启动 Ping 失败后的重试次数与退避区间
WithHealthProbe(probe) 自定义健康探针,在 Ping 通过后追加执行(如检查只读标记、复制延迟)
事务观测
Option 默认值 说明
WithTxRetryObserver(observer) 每次死锁重试前回调 TxRetryEvent(实例名、第几次、等待时长、错误),用于打点告警
MySQL Dialect(少用,对接非标准部署时才需要)
Option 默认值 说明
WithDriverName(name) mysql 自定义驱动名
WithServerVersion(version) 自动探测 手工指定服务端版本
WithSkipInitializeWithVersion(skip) false 跳过按版本初始化
WithDefaultStringSize(size) 0 string 字段默认长度
WithDisableDatetimePrecision(disable) false 禁用 datetime 精度(兼容 MySQL 5.6 以前)
WithDisableWithReturning(disable) false 禁用 RETURNING 子句
Client 方法
方法 说明
DB() *gorm.DB 取 GORM 句柄
SQLDB() *sql.DB 取底层 *sql.DB(可交给 jetx 等共享连接池)
Config() Config 配置快照(深拷贝)
Name() string 实例名(未设置时为 default
PingContext(ctx) error 连通性检查
Stats() sql.DBStats / StatsSnapshot() 连接池统计
HealthCheck(ctx) HealthReport 健康检查(Ping + 自定义探针,默认 5s 超时)
Metrics() []MetricSample 连接池指标采样(orm_db_* 系列,带 name/role label)
WithTx / WithReadTx 事务,见下节
Close() error 关闭连接池(OpenWithDB 包装的实例不关闭外部 *sql.DB
事务(死锁自动重试)
err := client.WithTx(ctx, nil, func(tx *gorm.DB) error {
    if err := tx.Create(&order).Error; err != nil {
        return err
    }
    return tx.Model(&stock).Update("count", gorm.Expr("count - ?", 1)).Error
})
  • fn 返回 nil 则提交,返回 error 则回滚;panic 时回滚后继续抛出。
  • 遇到 MySQL 死锁(1213)或锁等待超时(1205)时自动按带抖动的指数退避重试,默认最多 3 次。重试意味着 fn 可能执行多次,事务内逻辑须幂等。
  • 第二个参数可传 *sql.TxOptions 指定隔离级别/只读;WithReadTx(ctx, fn)ReadOnly: true 的便捷形式。

每次调用可用 TxOption 覆盖重试行为:

TxOption 默认值 说明
WithMaxRetries(n) 3 最大重试次数,0 禁用重试
WithRetryBaseWait(d) 5ms 退避基础等待
WithRetryMaxWait(d) 50ms 单次退避上限
err := client.WithTx(ctx, nil, fn, ormx.WithMaxRetries(5), ormx.WithRetryMaxWait(200*time.Millisecond))
多库多实例

配置按实例隔离(没有全局状态),每次 Open 返回独立的 *Client,各自持有独立连接池。连接多个库就是创建多个实例,按依赖注入交给各业务模块:

orderDB, err := ormx.Open(ctx, ormx.WithDatabase("orders"), ormx.WithName("orders") /* ... */)
userDB, err  := ormx.Open(ctx, ormx.WithDatabase("users"), ormx.WithName("users") /* ... */)

orderRepo := repo.NewOrderRepo(orderDB.DB())
userRepo  := repo.NewUserRepo(userDB.DB())
集群(读写分离 / 故障切换)

把一个主库和若干副本组成 Cluster:写请求路由到主库,读请求在健康副本间轮询,副本全挂时可回退主库。

primary, _ := ormx.Open(ctx, ormx.WithName("primary") /* ... */)
replica, _ := ormx.Open(ctx, ormx.WithName("replica-1") /* ... */)

cluster, err := ormx.NewCluster(primary, replica)
if err != nil {
    return err
}
defer cluster.Close() // 统一关闭全部节点

// 周期健康巡检:探活失败的节点标记 down,恢复后自动回到读池。
// RunHealthLoop 返回 error(interval ≤ 0 或集群已关闭),自起 goroutine 时需显式处理
go func() { _ = cluster.RunHealthLoop(ctx, 10*time.Second) }()

writeClient, err := cluster.WriteClient()      // 主库
readClient, err := cluster.ReaderClientCtx(ctx) // 副本轮询,感知写后读窗口

也可以直接用配置一步打开(副本并行建连):

cluster, err := ormx.OpenClusterWithOptions(ctx, primaryCfg, []ormx.Config{replicaCfg1, replicaCfg2},
    ormx.WithHealthCheckTimeout(3*time.Second),
)
ClusterOption
Option 默认值 说明
WithReadFallbackToPrimary(enabled) true 所有副本不可读时读请求回退主库
WithAutoRecoverReplicas(enabled) true 健康巡检中 Ping 恢复的 down 副本自动回到读池
WithHealthCheckTimeout(d) 5s 健康检查 Ping 的默认超时;调用方 context 有更短 deadline 时优先
Cluster 常用方法
方法 说明
WriteClient() (*Client, error) 取主库客户端,主库不可用时返回错误
ReaderClient() (*Client, error) 在 ready 副本间轮询取读客户端
ReaderClientCtx(ctx) (*Client, error) 同上,但 ctx 带写标记时强制路由主库(写后读一致性)
MustWriteDB() / MustReadDB() 直接取 *gorm.DB,不可用时 panic,仅适合启动期 wiring
WithTx(ctx, fn, txOpts...) 在主库上执行事务(含死锁重试)
WithReadTx(ctx, fn) 在读节点上执行只读事务(感知写标记)
HealthCheck(ctx) 并行探活所有节点,返回 ClusterHealthReport(up / degraded / down)
Refresh(ctx) 探活并更新节点状态(RunHealthLoop 内部周期调用的就是它)
RunHealthLoop(ctx, interval) 周期巡检,ctx 取消时退出;由调用方自起 goroutine
DrainReplica(name, cause) 把副本标记为 draining,摘出读池(发版、维护窗口用)。注意非长期粘性:副本探活失败转 down 后,恢复时会被健康巡检自动拉回读池;长期摘除需暂停健康循环
RecoverReplica(ctx, name) Ping 通过后把副本恢复为 ready
MarkPrimaryDown(cause) 把主库标记 down(注意:后续 Refresh Ping 成功会自动恢复 Ready)
SwitchPrimary(ctx, name) 把指定副本提升为主库,旧主库降级为 draining 副本
Nodes() / PrimaryNode() / ReplicaNodes() 节点状态快照
Metrics() 全部节点的连接池指标
Close() 关闭所有节点(去重,共享 Client 只关一次)

WriteDB() / ReadDB() / ReadDBCtx() 已标记 Deprecated(不可用时返回 nil,易引发空指针),新代码请用对应的 *Client 版本。

路由错误判断

集群读写路由失败可用 errors.Is 区分类型:

错误 含义
ormx.ErrNoReadableNode 没有可读节点(副本全部不可读,且回退主库被关闭或主库也不可读)
ormx.ErrPrimaryUnavailable 主库不可用(不存在或处于 down 状态)
ormx.ErrClusterClosed 集群已关闭
写后读一致性

主从复制存在延迟,"写完立刻读"可能从副本读到旧数据。在写入成功后给 context 打写标记,后续读请求即被路由到主库:

// 方式一:本次请求内一直读主库
ctx = ormx.ContextWithWriteFlag(ctx)

// 方式二:只在一个时间窗口内读主库,窗口过期自动恢复读副本(推荐)
ctx = ormx.ContextWithWriteWindow(ctx, 500*time.Millisecond)

readClient, err := cluster.ReaderClientCtx(ctx) // 命中写标记 → 主库
函数 说明
ContextWithWriteFlag(ctx) 标记写入,后续读路由主库(无过期)
ContextWithWriteWindow(ctx, ttl) 同上,但 ttl 过期后自动失效;ttl ≤ 0 等价于清除标记
ContextClearWriteFlag(ctx) 清除写标记
HasWriteFlag(ctx) bool 查询 ctx 当前是否带有效写标记
健康检查与指标

单实例与集群均提供健康检查和 Prometheus 风格的指标采样:

report := client.HealthCheck(ctx)
if !report.Healthy() {
    log.Printf("db down: %v", report.Error)
}

for _, m := range client.Metrics() {
    // m.Name 形如 orm_db_open_connections / orm_db_wait_count_total ...
    // m.Labels 含 name(实例名)与 role(standalone/primary/replica)
    gauge.With(m.Labels).Set(m.Value)
}

WithHealthProbe 可在 Ping 之外追加业务探针,例如校验副本只读:

ormx.WithHealthProbe(func(ctx context.Context, c *ormx.Client, role ormx.NodeRole) error {
    if role != ormx.RoleReplica {
        return nil
    }
    var readOnly int
    return c.DB().WithContext(ctx).Raw("SELECT @@read_only").Scan(&readOnly).Error
})

zlogger(GORM 的 zap 日志适配)

zlogger.New 返回一个实现 gormlogger.Interface 的日志器,通过 ormx.WithGormLogger 接入:

import (
    "github.com/gtkit/ormx"
    "github.com/gtkit/ormx/zlogger"
    gormlogger "gorm.io/gorm/logger"
    "go.uber.org/zap"
)

zlog, _ := zap.NewProduction()

client, err := ormx.Open(ctx,
    // ...连接选项...
    ormx.WithGormLogger(zlogger.New(
        zlogger.WithLogger(zlog),
        zlogger.WithLogLevel(gormlogger.Warn),
        zlogger.WithSlowThreshold(300*time.Millisecond),
        zlogger.WithIgnoreRecordNotFoundError(true),
        zlogger.WithParameterizedQueries(true),
        zlogger.WithTraceIDExtractor(func(ctx context.Context) string {
            if id, ok := ctx.Value("X-Request-ID").(string); ok {
                return id
            }
            return ""
        }),
    )),
)
选项函数
Option 默认值 说明
WithLogger(log) nop(不输出) 底层 *zap.Logger不设置则所有日志静默丢弃,必须传入
WithLogLevel(level) gormlogger.Warn 日志级别(Silent / Error / Warn / Info)
WithSlowThreshold(d) 200ms 慢查询阈值;执行耗时超过即按 Warn 输出 gorm slow query,设为 0 关闭慢查询日志
WithIgnoreRecordNotFoundError(enabled) false 忽略 gorm.ErrRecordNotFound,不作为错误日志输出
WithParameterizedQueries(enabled) false(兼容默认) 开启后日志中的 SQL 不带参数值(脱敏),只输出占位符语句;生产环境建议设为 true
WithTraceIDExtractor(fn) 从 context 提取 trace/request id,附加为 trace_id 字段,串联 SQL 日志与请求链路
输出行为

每条 SQL 日志包含字段:source(调用位置)、elapsed(耗时)、sqlrows(影响行数,-1 时省略)、trace_id(配置了 extractor 且能提取到时)。按以下优先级输出:

  1. 执行出错(且未被 RecordNotFound 忽略)→ Errorgorm query error,附 error 字段
  2. 耗时超过慢查询阈值 → Warngorm slow query,附 slow_threshold 字段
  3. 日志级别为 Info → Infogorm query(全量 SQL 日志,仅建议开发环境开启)

LogMode 遵循 GORM 约定返回调级别后的副本,可配合 db.Session(&gorm.Session{Logger: ...}) 做局部调级。

安全提示:WithParameterizedQueries(false) 会保留 SQL 绑定参数,可能把密码、Token 或其他敏感值写入日志,仅应在确认数据安全的受控排障环境使用。


发版

make tag             # patch 发版:自动 bump patch、跑门禁、打 tag 并推送
make tag BUMP=minor  # minor 发版(新增向后兼容的功能时)
make tag BUMP=major  # major 发版(破坏性变更时)

发版前提:工作区干净,且 CHANGELOG.md 已有目标版本条目(格式 ## [vX.Y.Z] - YYYY-MM-DD)。 门禁包含 vet、lint、race 测试、benchmark、覆盖率 ≥ 80% 与 govulncheck,任一失败即中止; tag message 自动携带该版本的 CHANGELOG 内容。

注意:升 major 到 v2 及以上时,必须先把 go.mod 的 module path 改为 github.com/gtkit/ormx/v2 并同步包内 import(Go Module 硬要求),make tag BUMP=major 不会自动处理这一步。

Documentation

Overview

Package ormx 提供基于 GORM 的企业级 MySQL 数据访问封装: 连接管理、集群读写分离、健康探活、事务死锁自动重试与写后读一致性窗口。

基本用法:

client, err := ormx.Open(ctx,
    ormx.WithHost("127.0.0.1"),
    ormx.WithPort("3306"),
    ormx.WithDatabase("app"),
    ormx.WithUser("root"),
    ormx.WithPassword(os.Getenv("DB_PASSWORD")),
)
if err != nil {
    return err
}
defer client.Close()

db := client.DB() // *gorm.DB,直接走 GORM API

事务通过 Client.WithTx 执行,遇 MySQL 死锁(1213)或锁等待超时(1205) 自动按带抖动的指数退避重试。

读写分离由 Cluster 提供:写请求路由主库,读请求在健康副本间轮询; 写入后用 ContextWithWriteWindow 打写标记,可在时间窗口内保证写后读一致性。

ClientCluster 均并发安全,可在多个 goroutine 间共享。 GORM 的 zap 日志适配见子包 zlogger。

Index

Examples

Constants

View Source
const (
	HealthStatusUp       HealthStatus = "up"
	HealthStatusDown     HealthStatus = "down"
	HealthStatusDegraded HealthStatus = "degraded"
	RoleStandalone       NodeRole     = "standalone"
	RolePrimary          NodeRole     = "primary"
	RoleReplica          NodeRole     = "replica"

	NodeStateReady    NodeState = "ready"
	NodeStateDraining NodeState = "draining"
	NodeStateDown     NodeState = "down"
)

健康状态(HealthStatus)、节点角色(NodeRole)与节点状态(NodeState)的预定义枚举值。

View Source
const Version = "v1.1.2"

Version 是 ormx 当前发布的版本号。

Variables

View Source
var (
	// ErrNoReadableNode 表示没有可用的读节点:所有副本均不可读,
	// 且回退主库被关闭或主库也不可读。
	ErrNoReadableNode = errors.New("ormx: no readable node available")
	// ErrPrimaryUnavailable 表示主库不可用(不存在或处于 down 状态)。
	ErrPrimaryUnavailable = errors.New("ormx: primary unavailable")
	// ErrClusterClosed 表示集群已关闭,不再接受任何操作。
	ErrClusterClosed = errors.New("ormx: cluster is closed")
)

集群路由的可判断错误,调用方可用 errors.Is 区分失败类型。

Functions

func ContextClearWriteFlag

func ContextClearWriteFlag(ctx context.Context) context.Context

ContextClearWriteFlag 清除 ctx 携带的写标记。

func ContextWithWriteFlag

func ContextWithWriteFlag(ctx context.Context) context.Context

ContextWithWriteFlag 在 ctx 上打写标记,表示刚发生过一次写入。 带该标记的 ctx 传给 Cluster.ReaderClientCtxCluster.ReadDBCtx 时, 读请求会被路由到主库而非副本,保证写后读一致性。

典型用法:写入成功后立即调用,本次请求内的后续读操作复用返回的 ctx。

ctx = ormx.ContextWithWriteFlag(ctx)
// 之后经 ReaderClientCtx(ctx) 的读请求会命中主库

func ContextWithWriteWindow

func ContextWithWriteWindow(ctx context.Context, ttl time.Duration) context.Context

ContextWithWriteWindow 在 ctx 上打带时限的写标记:ttl 内读请求路由主库, ttl 过后 HasWriteFlag 返回 false,读请求自动恢复走副本; ttl ≤ 0 等价于清除写标记。

func HasWriteFlag

func HasWriteFlag(ctx context.Context) bool

HasWriteFlag 报告 ctx 是否携带仍然有效的写标记 (由 ContextWithWriteFlagContextWithWriteWindow 设置)。

Types

type Client

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

Client 封装单个数据库连接,持有 GORM 实例与底层 *sql.DB。 Client 并发安全,可在多个 goroutine 间共享。

func MustOpen

func MustOpen(ctx context.Context, opts ...Option) *Client

MustOpen 以 NewConfig(opts...) 构建配置并调用 Config.MustOpen,失败时 panic。

func Open

func Open(ctx context.Context, opts ...Option) (*Client, error)

Open 以 NewConfig(opts...) 构建配置并调用 Config.Open,是最常用的入口函数。

func OpenWithDB

func OpenWithDB(ctx context.Context, sqlDB *sql.DB, opts ...Option) (*Client, error)

OpenWithDB 包装既有的 *sql.DB:GORM 初始化前会把 opts 中的连接池设置应用到 sqlDB。 无论成败,sqlDB 的所有权始终归调用方(Client.Close 不会关闭它)。

func (*Client) Close

func (c *Client) Close() error

Close 关闭底层 *sql.DB。仅当 Client 拥有该连接时才真正关闭,否则直接返回 nil。

func (*Client) Config

func (c *Client) Config() Config

Config 返回客户端配置的副本。

func (*Client) DB

func (c *Client) DB() *gorm.DB

DB 返回底层 *gorm.DB。

func (*Client) HealthCheck

func (c *Client) HealthCheck(ctx context.Context) HealthReport

HealthCheck 以 RoleStandalone 角色执行一次健康检查(Ping 加可选的 HealthProbe)并返回报告。 当 ctx 未设置 deadline 时使用内置默认超时,避免无限阻塞。

func (*Client) Metrics

func (c *Client) Metrics() []MetricSample

Metrics 返回连接池的指标采样列表,标签含客户端名称与 RoleStandalone 角色。

func (*Client) Name

func (c *Client) Name() string

Name 返回客户端名称,未在 Config 中配置时返回 "default"。

func (*Client) PingContext

func (c *Client) PingContext(ctx context.Context) error

PingContext 检测数据库连接是否可用。

func (*Client) SQLDB

func (c *Client) SQLDB() *sql.DB

SQLDB 返回底层 *sql.DB。

func (*Client) Stats

func (c *Client) Stats() sql.DBStats

Stats 返回底层连接池的统计信息。

func (*Client) StatsSnapshot

func (c *Client) StatsSnapshot() DBStatsSnapshot

StatsSnapshot 返回当前连接池统计信息的快照。

func (*Client) WithReadTx

func (c *Client) WithReadTx(ctx context.Context, fn func(tx *gorm.DB) error) error

WithReadTx 在只读事务中执行 fn,重试行为与 WithTx 的默认值一致。

func (*Client) WithTx

func (c *Client) WithTx(
	ctx context.Context, opts *sql.TxOptions, fn func(tx *gorm.DB) error, txOpts ...TxOption,
) error

WithTx 在事务中执行 fn:fn 返回 nil 则提交,返回 error 则回滚。 遇到 MySQL 死锁(1213)或锁等待超时(1205)时按带抖动的指数退避自动重试, 重试行为可通过 TxOption 调整;fn 为 nil 时返回错误。

type Cluster

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

Cluster 管理一主多副本的数据库节点拓扑,提供读写分离路由、 健康检查、副本摘除/恢复与主库切换能力。 所有方法并发安全(内部由 RWMutex 保护)。

func NewCluster

func NewCluster(primary *Client, replicas ...*Client) (*Cluster, error)

NewCluster 用已有的主库与副本客户端构建 Cluster。 等价于使用默认选项调用 NewClusterWithOptions。

func NewClusterWithOptions

func NewClusterWithOptions(primary *Client, replicas []*Client, opts ...ClusterOption) (*Cluster, error)

NewClusterWithOptions 用已有客户端与选项构建 Cluster。 primary 不能为 nil;副本不能为 nil 且节点名不能重复,否则返回错误。

func OpenCluster

func OpenCluster(
	ctx context.Context,
	primary Config,
	replicas ...Config,
) (*Cluster, error)

OpenCluster 按给定配置打开主库与各副本连接,并构建 Cluster。 等价于使用默认选项调用 OpenClusterWithOptions。

func OpenClusterWithOptions

func OpenClusterWithOptions(
	ctx context.Context,
	primary Config,
	replicas []Config,
	opts ...ClusterOption,
) (_ *Cluster, err error)

OpenClusterWithOptions 按给定配置打开主库连接,并行打开所有副本连接, 再按选项构建 Cluster。任一连接打开失败时会关闭已打开的连接并返回错误。

func (*Cluster) Close

func (c *Cluster) Close() error

Close 关闭集群并释放所有节点的底层连接(同一客户端只关闭一次), 返回各节点关闭错误的合并结果;重复调用返回 ErrClusterClosed。

func (*Cluster) DrainReplica

func (c *Cluster) DrainReplica(name string, cause error) error

DrainReplica 把指定名称的副本置为 draining 状态,将其从读流量中摘除; cause 记录为该节点的最近错误。副本不存在或集群已关闭时返回错误。

注意:draining 不是长期粘性状态。若该副本随后探活失败被 Refresh 置为 down, 待其探活恢复且开启 autoRecoverReplicas 时会被自动拉回 ready、重新接收读流量, 摘除意图即告失效——维护窗口内节点重启(Ping 短暂失败)恰好会触发这一路径。 需要长期摘除时,请在运维侧暂停健康循环(停止 RunHealthLoop / 不再调用 Refresh), 或在节点恢复后重新调用 DrainReplica。

func (*Cluster) HealthCheck

func (c *Cluster) HealthCheck(ctx context.Context) ClusterHealthReport

HealthCheck 并行探活所有节点并返回集群健康报告; 该方法只读,不修改任何节点状态。

func (*Cluster) MarkPrimaryDown

func (c *Cluster) MarkPrimaryDown(cause error) error

MarkPrimaryDown 将当前主库标记为 down。 注意:如果后续调用 Refresh() 且主库 Ping 恢复成功,状态会自动回到 Ready。 如果你的目标是长期隔离主库,请在运维侧同时停止健康循环或避免继续触发 Refresh()。

func (*Cluster) Metrics

func (c *Cluster) Metrics() []MetricSample

Metrics 汇总并返回所有节点的连接池指标采样。

func (*Cluster) MustReadDB

func (c *Cluster) MustReadDB() *gorm.DB

MustReadDB 返回副本 *gorm.DB,没有可读节点时 panic。 仅适用于可接受 panic 的场景(如启动期 wiring)。

func (*Cluster) MustWriteDB

func (c *Cluster) MustWriteDB() *gorm.DB

MustWriteDB 返回主库 *gorm.DB,不可用时 panic。 仅适用于可接受 panic 的场景(如启动期 wiring)。

func (*Cluster) Nodes

func (c *Cluster) Nodes() []Node

Nodes 返回主库与所有副本节点的快照,主库(若存在)排在首位。

func (*Cluster) Primary

func (c *Cluster) Primary() *Client

Primary 返回当前主库客户端;主库不存在时返回 nil。

func (*Cluster) PrimaryNode

func (c *Cluster) PrimaryNode() Node

PrimaryNode 返回当前主库节点的快照;主库不存在时返回零值 Node。

func (*Cluster) ReadDB deprecated

func (c *Cluster) ReadDB() *gorm.DB

ReadDB 返回用于读操作的副本 *gorm.DB。

Deprecated: 请改用 ReaderClient() 显式处理错误。 没有可读节点时本方法返回 nil,调用方不检查会引发空指针 panic。

func (*Cluster) ReadDBCtx deprecated

func (c *Cluster) ReadDBCtx(ctx context.Context) *gorm.DB

ReadDBCtx 返回用于读操作的 *gorm.DB;ctx 带写标记(ContextWithWriteFlag)时路由主库。

Deprecated: 请改用 ReaderClientCtx() 显式处理错误。

func (*Cluster) Reader

func (c *Cluster) Reader() *Client

Reader 返回一个读客户端,是 ReaderClient 忽略错误的便捷形式; 没有可读节点时返回 nil。

func (*Cluster) ReaderClient

func (c *Cluster) ReaderClient() (*Client, error)

ReaderClient 按轮询(round-robin)从 ready 状态的副本中选出一个读客户端; 没有可用副本且开启 readFallbackToPrimary 时回退到主库, 否则返回 ErrNoReadableNode。

func (*Cluster) ReaderClientCtx

func (c *Cluster) ReaderClientCtx(ctx context.Context) (*Client, error)

ReaderClientCtx 返回读客户端,并感知 ctx 中的写标记: ctx 带有效写标记(ContextWithWriteFlag)时路由到主库,保证写后读一致性。

func (*Cluster) RecoverReplica

func (c *Cluster) RecoverReplica(ctx context.Context, name string) error

RecoverReplica 对指定名称的副本执行 Ping 探活: 成功则恢复为 ready 重新接收读流量,失败则置为 down 并返回探活错误。 副本不存在或集群已关闭时返回错误。

func (*Cluster) Refresh

func (c *Cluster) Refresh(ctx context.Context) ClusterHealthReport

Refresh 并行探活所有节点并据此更新节点状态: 探活失败的节点置为 down;主库探活成功时恢复为 ready; 开启 autoRecoverReplicas 时,down 状态的副本探活成功后自动恢复为 ready。 返回更新后的集群健康报告。

func (*Cluster) ReplicaNodes

func (c *Cluster) ReplicaNodes() []Node

ReplicaNodes 返回所有副本节点的快照。

func (*Cluster) RunHealthLoop

func (c *Cluster) RunHealthLoop(ctx context.Context, interval time.Duration) error

RunHealthLoop 按 interval 周期性刷新集群健康状态(调用 Refresh),直到 ctx 取消; interval ≤ 0 时返回错误。由调用方自起 goroutine,以掌控退出语义。

func (*Cluster) SwitchPrimary

func (c *Cluster) SwitchPrimary(ctx context.Context, name string) (Node, error)

SwitchPrimary 切换主库节点。 注意:如果后续调用 Refresh() 且主库 Ping 恢复成功,状态会自动回到 Ready。 如果你的目标是长期隔离主库,请在运维侧同时停止健康循环或避免继续触发 Refresh()。

注意:如果目标节点已经是主节点,则只做连通性确认; 如果目标节点是副本节点,则把它提升为主节点。

func (*Cluster) WithReadTx

func (c *Cluster) WithReadTx(ctx context.Context, fn func(tx *gorm.DB) error) error

WithReadTx 在按 ReaderClientCtx 路由选出的读节点上执行只读事务函数 fn; ctx 携带写标记时会路由到主库,没有可读节点时返回错误。

func (*Cluster) WithTx

func (c *Cluster) WithTx(ctx context.Context, fn func(tx *gorm.DB) error, txOpts ...TxOption) error

WithTx 在主库上执行事务函数 fn;主库不可用时返回错误。

func (*Cluster) WriteClient

func (c *Cluster) WriteClient() (*Client, error)

WriteClient 返回用于写操作的主库客户端; 集群已关闭或主库不可用(不存在或处于 down 状态)时返回错误。

func (*Cluster) WriteDB deprecated

func (c *Cluster) WriteDB() *gorm.DB

WriteDB 返回用于写操作的主库 *gorm.DB。

Deprecated: 请改用 WriteClient() 显式处理错误。 主库不可用时本方法返回 nil,调用方不检查会引发空指针 panic。

type ClusterHealthReport

type ClusterHealthReport struct {
	Status    HealthStatus
	CheckedAt time.Time
	Nodes     []HealthReport
}

ClusterHealthReport 描述一次集群健康检查的整体结果, 包含集群级状态、检查时间和各节点的健康报告。

func (ClusterHealthReport) Healthy

func (r ClusterHealthReport) Healthy() bool

Healthy 报告集群整体状态是否为 HealthStatusUp。

type ClusterOption

type ClusterOption func(*clusterOptions)

ClusterOption 用于在构建 Cluster 时定制集群行为的函数式选项。

func WithAutoRecoverReplicas

func WithAutoRecoverReplicas(enabled bool) ClusterOption

WithAutoRecoverReplicas 设置 Refresh 探活成功时是否自动把 down 状态的副本恢复为 ready。 默认开启。

func WithHealthCheckTimeout

func WithHealthCheckTimeout(timeout time.Duration) ClusterOption

WithHealthCheckTimeout 设置健康检查 Ping 的默认超时; 调用方 context 已带更短 deadline 时以后者优先。默认 5s。

func WithReadFallbackToPrimary

func WithReadFallbackToPrimary(enabled bool) ClusterOption

WithReadFallbackToPrimary 设置当没有可用副本时读请求是否回退到主库。 默认开启。

type Config

type Config struct {
	Name                     string
	MySQL                    MySQLConfig
	Pool                     PoolConfig
	GORM                     GORMConfig
	Dialect                  MySQLDialectConfig
	HealthProbe              HealthProbeFunc
	TxRetryObserver          TxRetryObserver
	StartupPing              bool
	StartupPingMaxRetries    int
	StartupPingRetryBaseWait time.Duration
	StartupPingRetryMaxWait  time.Duration
}

Config 汇总建立 MySQL 连接所需的全部配置:驱动连接参数(MySQL)、 连接池(Pool)、GORM 行为(GORM)、方言(Dialect)以及启动期 Ping 重试策略。 Config 为值语义,可安全复制;通过 With 应用 Option 会返回新副本,不修改原值。 字段全部导出以便从配置文件直接映射,但直接修改字段会绕过 Option 的防御逻辑, 合法性由调用方自行保证;优先使用 Option 构建配置。 注意:从配置文件映射时必须以 DefaultConfig()(或 NewConfig)的返回值为基底再覆盖字段; 对零值 Config 直接反序列化会缺少 Pool 各字段的"已设置"标记,连接池配置将被静默忽略。

func DefaultConfig

func DefaultConfig() Config

DefaultConfig 返回带合理默认值的 Config: MySQL 默认通过 tcp 连接 127.0.0.1:3306,时区为 time.Local,启用 ParseTime, 并设置拨号/读/写超时;连接池四项参数均使用包内默认值并标记为已设置; GORM 使用默认命名策略;StartupPing 默认开启,重试基础等待 1 秒、上限 5 秒、 默认不重试(StartupPingMaxRetries 为 0)。

func NewConfig

func NewConfig(opts ...Option) Config

NewConfig 在 DefaultConfig 的基础上依次应用 opts 并返回结果。

Example

用 Functional Options 构建配置,并通过 RedactedDSN 输出密码脱敏后的 DSN(可安全打印到日志)。实际连库使用 cfg.Open(ctx) 或包级 ormx.Open。

package main

import (
	"fmt"

	"github.com/gtkit/ormx"
)

func main() {
	cfg := ormx.NewConfig(
		ormx.WithUser("alice"),
		ormx.WithPassword("secret"),
		ormx.WithDatabase("app"),
	)

	dsn, err := cfg.RedactedDSN()
	if err != nil {
		fmt.Println("err:", err)
		return
	}
	fmt.Println(dsn)
}
Output:
alice:******@tcp(127.0.0.1:3306)/app?loc=Local&parseTime=true&readTimeout=30s&timeout=10s&writeTimeout=30s

func (Config) Clone

func (c Config) Clone() Config

Clone 返回 Config 的深拷贝,其中 MySQL.Params 映射会被复制, 避免副本与原值共享同一底层 map。

func (Config) DriverConfig

func (c Config) DriverConfig() (*mysqldriver.Config, error)

DriverConfig 根据 MySQL 连接配置生成 go-sql-driver/mysql 的 *mysqldriver.Config, 配置非法(如缺少必填项或参数校验失败)时返回错误。

func (Config) GoString

func (c Config) GoString() string

GoString 实现 fmt.GoStringer,使 %#v 输出同样脱敏密码。

func (Config) MustOpen

func (c Config) MustOpen(ctx context.Context) *Client

MustOpen 与 Open 行为一致,但在失败时直接 panic,适用于初始化阶段必须成功的场景。

func (Config) Open

func (c Config) Open(ctx context.Context) (*Client, error)

Open 按当前配置构建 MySQL 连接器并打开 *sql.DB,应用连接池配置后初始化 GORM, 返回拥有该 *sql.DB 所有权的 Client(Close 时会一并关闭)。 若 StartupPing 开启,会先按重试策略 Ping 数据库;任一步骤失败时关闭已打开的连接并返回错误。

func (Config) OpenWithDB

func (c Config) OpenWithDB(ctx context.Context, sqlDB *sql.DB) (*Client, error)

OpenWithDB 包装既有的 *sql.DB:GORM 初始化前会把 Config.Pool 的连接池设置应用到 sqlDB。 无论成败,sqlDB 的所有权始终归调用方(Client.Close 不会关闭它)。

func (Config) RedactedDSN

func (c Config) RedactedDSN() (string, error)

RedactedDSN 返回密码脱敏后的 DSN 字符串:密码非空时替换为 "******", 可安全用于日志输出;底层 DriverConfig 构建失败时返回错误。

func (Config) String

func (c Config) String() string

String 返回密码已脱敏的可读表示, 防止经 fmt.Print / 日志输出意外泄露凭据。

func (Config) With

func (c Config) With(opts ...Option) Config

With 返回应用 opts 后的 Config 副本,原 Config 不受影响;nil Option 会被跳过。

Example

Config 是值语义:With 返回应用新 Option 后的副本,原配置不受影响。

package main

import (
	"fmt"

	"github.com/gtkit/ormx"
)

func main() {
	base := ormx.NewConfig(ormx.WithName("base"))
	derived := base.With(ormx.WithName("derived"))

	fmt.Println(base.Name, derived.Name)
}
Output:
base derived

type DBStatsSnapshot

type DBStatsSnapshot struct {
	MaxOpenConnections int
	OpenConnections    int
	InUse              int
	Idle               int
	WaitCount          int64
	WaitDuration       time.Duration
	MaxIdleClosed      int64
	MaxIdleTimeClosed  int64
	MaxLifetimeClosed  int64
	Utilization        float64
}

DBStatsSnapshot 是 sql.DBStats 的快照,并附带连接利用率 Utilization (InUse / MaxOpenConnections,MaxOpenConnections 为 0 时取 0)。

type GORMConfig

type GORMConfig struct {
	Logger                                   gormlogger.Interface
	NowFunc                                  func() time.Time
	NamingStrategy                           schema.NamingStrategy
	DefaultTransactionTimeout                time.Duration
	DefaultContextTimeout                    time.Duration
	PrepareStmt                              bool
	PrepareStmtMaxSize                       int
	PrepareStmtTTL                           time.Duration
	SkipDefaultTransaction                   bool
	DisableForeignKeyConstraintWhenMigrating bool
	IgnoreRelationshipsWhenMigrating         bool
	DisableNestedTransaction                 bool
	AllowGlobalUpdate                        bool
	QueryFields                              bool
	CreateBatchSize                          int
	TranslateError                           bool
	PropagateUnscoped                        bool
	DryRun                                   bool
}

GORMConfig 描述透传给 gorm.Config 的行为配置, 字段与 gorm.Config 中的同名字段一一对应。

type HealthProbeFunc

type HealthProbeFunc func(ctx context.Context, client *Client, role NodeRole) error

HealthProbeFunc 是自定义健康探测函数,在 Ping 成功后执行额外检查,返回非 nil 错误表示节点不健康。

type HealthReport

type HealthReport struct {
	Name      string
	Role      NodeRole
	State     NodeState
	Status    HealthStatus
	CheckedAt time.Time
	Duration  time.Duration
	Error     error
	Stats     DBStatsSnapshot
}

HealthReport 描述一次健康检查的结果。

func (HealthReport) Healthy

func (r HealthReport) Healthy() bool

Healthy 报告本次检查状态是否为 HealthStatusUp。

type HealthStatus

type HealthStatus string

HealthStatus 表示健康检查结果的状态。

type MetricSample

type MetricSample struct {
	Name   string
	Value  float64
	Labels map[string]string
}

MetricSample 表示一条带标签的指标采样。

type MySQLConfig

type MySQLConfig struct {
	User                 string            `json:"user"     yaml:"user"`
	Password             string            `json:"-"        yaml:"-"`
	Net                  string            `json:"net"      yaml:"net"`
	Host                 string            `json:"host"     yaml:"host"`
	Port                 string            `json:"port"     yaml:"port"`
	Addr                 string            `json:"addr"     yaml:"addr"`
	Database             string            `json:"database" yaml:"database"`
	Params               map[string]string `json:"params"   yaml:"params"`
	ConnectionAttributes string            `json:"connection_attributes" yaml:"connection_attributes"`
	Collation            string            `json:"collation" yaml:"collation"`
	Loc                  *time.Location    `json:"-"        yaml:"-"`
	TLSConfig            string            `json:"tls_config" yaml:"tls_config"`
	Timeout              time.Duration     `json:"timeout"  yaml:"timeout"`
	ReadTimeout          time.Duration     `json:"read_timeout" yaml:"read_timeout"`
	WriteTimeout         time.Duration     `json:"write_timeout" yaml:"write_timeout"`
	ParseTime            bool              `json:"parse_time" yaml:"parse_time"`
}

MySQLConfig 描述驱动层连接设置。 Addr 与 Host/Port 同时设置时 Addr 优先。 建议通过 Option 辅助函数设置,以保证 Addr/Host/Port 的优先级语义一致。

type MySQLDialectConfig

type MySQLDialectConfig struct {
	DriverName                    string
	ServerVersion                 string
	DefaultStringSize             uint
	DefaultDatetimePrecision      *int
	SkipInitializeWithVersion     bool
	DisableWithReturning          bool
	DisableDatetimePrecision      bool
	DontSupportRenameIndex        bool
	DontSupportRenameColumn       bool
	DontSupportForShareClause     bool
	DontSupportNullAsDefaultValue bool
	DontSupportRenameColumnUnique bool
	DontSupportDropConstraint     bool
}

MySQLDialectConfig 描述透传给 GORM MySQL 方言(gorm.io/driver/mysql)的配置, 字段与其 Config 中的同名字段一一对应。

type Node

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

Node 是集群节点在某一时刻的不可变快照, 包含节点名称、角色、客户端、状态、最近错误及状态更新时间。

func (Node) Client

func (n Node) Client() *Client

Client 返回节点对应的数据库客户端。

func (Node) HealthCheck

func (n Node) HealthCheck(ctx context.Context) HealthReport

HealthCheck 对该节点执行一次探活,并结合快照中的节点状态修饰健康报告后返回。

func (Node) Healthy

func (n Node) Healthy() bool

Healthy 报告快照时刻节点状态是否为 NodeStateReady。

func (Node) LastError

func (n Node) LastError() error

LastError 返回节点最近一次记录的错误;无错误时为 nil。

func (Node) Metrics

func (n Node) Metrics() []MetricSample

Metrics 返回该节点的连接池指标采样。

func (Node) Name

func (n Node) Name() string

Name 返回节点名称。

func (Node) Role

func (n Node) Role() NodeRole

Role 返回节点角色(主库或副本)。

func (Node) State

func (n Node) State() NodeState

State 返回快照时刻的节点状态。

func (Node) UpdatedAt

func (n Node) UpdatedAt() time.Time

UpdatedAt 返回节点状态最近一次更新的时间。

type NodeRole

type NodeRole string

NodeRole 表示节点在集群中的角色。

type NodeState

type NodeState string

NodeState 表示节点的运行状态。

type Option

type Option func(*Config)

Option 是修改 Config 的函数式配置项,配合 NewConfig、Open 等入口使用。

func WithAddress

func WithAddress(addr string) Option

WithAddress 设置完整连接地址(如 "127.0.0.1:3306"); Addr 非空时优先于 Host/Port 生效。

func WithCollation

func WithCollation(collation string) Option

WithCollation 设置连接使用的字符集校对规则。

func WithConnMaxIdleTime

func WithConnMaxIdleTime(duration time.Duration) Option

WithConnMaxIdleTime 设置连接最长空闲时间。默认 10 分钟。 取值透传给 sql.DB.SetConnMaxIdleTime:duration ≤ 0 表示空闲连接不因闲置被关闭。

func WithConnMaxLifetime

func WithConnMaxLifetime(duration time.Duration) Option

WithConnMaxLifetime 设置连接可被复用的最长时间。默认 30 分钟。 取值透传给 sql.DB.SetConnMaxLifetime:duration ≤ 0 表示连接不过期。

func WithConnectionAttributes

func WithConnectionAttributes(attrs string) Option

WithConnectionAttributes 设置 MySQL 连接属性(connection attributes)字符串。

func WithCreateBatchSize

func WithCreateBatchSize(size int) Option

WithCreateBatchSize 设置批量插入时的默认分批大小。

func WithDSNParam

func WithDSNParam(key, value string) Option

WithDSNParam 设置单个额外的 DSN 连接参数; Params 为 nil 时自动初始化,同名 key 会被覆盖。

func WithDSNParams

func WithDSNParams(params map[string]string) Option

WithDSNParams 批量合并额外的 DSN 连接参数,同名 key 会被覆盖; 传入 nil 或空 map 时不做任何修改。

func WithDatabase

func WithDatabase(name string) Option

WithDatabase 设置要连接的数据库名。

func WithDefaultContextTimeout

func WithDefaultContextTimeout(timeout time.Duration) Option

WithDefaultContextTimeout 设置 GORM 操作的默认 context 超时时间。

func WithDefaultStringSize

func WithDefaultStringSize(size uint) Option

WithDefaultStringSize 设置 string 类型字段建表时的默认长度。

func WithDefaultTransactionTimeout

func WithDefaultTransactionTimeout(timeout time.Duration) Option

WithDefaultTransactionTimeout 设置 GORM 事务的默认超时时间。

func WithDisableDatetimePrecision

func WithDisableDatetimePrecision(disable bool) Option

WithDisableDatetimePrecision 设置是否禁用 datetime 字段的精度支持。

func WithDisableWithReturning

func WithDisableWithReturning(disable bool) Option

WithDisableWithReturning 设置是否禁用方言的 RETURNING 子句支持。

func WithDriverName

func WithDriverName(name string) Option

WithDriverName 设置 GORM MySQL 方言使用的底层 SQL 驱动名。

func WithDryRun

func WithDryRun(enabled bool) Option

WithDryRun 设置是否启用 DryRun 模式:只生成 SQL 而不真正执行。

func WithGormLogger

func WithGormLogger(log gormlogger.Interface) Option

WithGormLogger 设置 GORM 使用的日志实现。

func WithHealthProbe

func WithHealthProbe(probe HealthProbeFunc) Option

WithHealthProbe 设置自定义健康探针;健康检查在 Ping 成功后调用该探针, 探针返回错误则判定为不健康。

func WithHost

func WithHost(host string) Option

WithHost 设置主机地址,并同时清空 Addr 以保证 Host/Port 生效。默认 "127.0.0.1"。

func WithLocation

func WithLocation(loc *time.Location) Option

WithLocation 设置解析时间值使用的时区。默认 time.Local。

func WithMaxIdleConns

func WithMaxIdleConns(size int) Option

WithMaxIdleConns 设置连接池最大空闲连接数。默认 10。 取值透传给 sql.DB.SetMaxIdleConns:size ≤ 0 表示不保留空闲连接。

func WithMaxOpenConns

func WithMaxOpenConns(size int) Option

WithMaxOpenConns 设置连接池最大打开连接数。默认 50。 取值透传给 sql.DB.SetMaxOpenConns:size ≤ 0 表示不限制。

func WithName

func WithName(name string) Option

WithName 设置数据库实例名称,用于健康检查报告与日志等可观测标识。

func WithNamingStrategy

func WithNamingStrategy(strategy schema.NamingStrategy) Option

WithNamingStrategy 整体替换 GORM 的命名策略,会覆盖之前设置的表前缀等字段。

func WithNetwork

func WithNetwork(network string) Option

WithNetwork 设置连接 MySQL 使用的网络类型(如 "tcp"、"unix")。默认 "tcp"。

func WithNowFunc

func WithNowFunc(now func() time.Time) Option

WithNowFunc 设置 GORM 生成时间戳时使用的当前时间函数。

func WithParseTime

func WithParseTime(enabled bool) Option

WithParseTime 设置是否将 DATE/DATETIME 列解析为 time.Time。默认开启。

func WithPassword

func WithPassword(password string) Option

WithPassword 设置连接密码。

func WithPort

func WithPort(port string) Option

WithPort 设置端口,并同时清空 Addr 以保证 Host/Port 生效。默认 "3306"。

func WithPrepareStmt

func WithPrepareStmt(enabled bool) Option

WithPrepareStmt 设置 GORM 是否缓存预编译语句以提升后续执行性能。

func WithPrepareStmtCache

func WithPrepareStmtCache(maxSize int, ttl time.Duration) Option

WithPrepareStmtCache 设置预编译语句缓存的最大条数 maxSize 与存活时间 ttl。

func WithQueryFields

func WithQueryFields(enabled bool) Option

WithQueryFields 设置查询时是否按模型字段名逐列展开 SELECT,而非 SELECT *。

func WithReadTimeout

func WithReadTimeout(timeout time.Duration) Option

WithReadTimeout 设置 I/O 读超时时间。默认 30s。

func WithServerVersion

func WithServerVersion(version string) Option

WithServerVersion 手动指定 MySQL 服务端版本号,供方言据此调整行为。

func WithSingularTable

func WithSingularTable(enabled bool) Option

WithSingularTable 设置是否使用单数表名(如 User 对应表 user 而非 users)。

func WithSkipDefaultTransaction

func WithSkipDefaultTransaction(skip bool) Option

WithSkipDefaultTransaction 设置是否跳过 GORM 对单条写操作的默认事务包装。

func WithSkipInitializeWithVersion

func WithSkipInitializeWithVersion(skip bool) Option

WithSkipInitializeWithVersion 设置是否跳过初始化时根据服务端版本自动配置方言。

func WithStartupPing

func WithStartupPing(enabled bool) Option

WithStartupPing 设置打开连接时是否先执行 Ping 验证连通性。默认开启。

func WithStartupPingRetry

func WithStartupPingRetry(maxRetries int, baseWait, maxWait time.Duration) Option

WithStartupPingRetry 配置启动 Ping 的重试策略:maxRetries 为最大重试次数, baseWait、maxWait 为退避等待的基准值与上限。maxRetries 为负、baseWait 或 maxWait 非正时,对应项被忽略并保留原值。默认不重试,基准 1s,上限 5s。

func WithTLSConfig

func WithTLSConfig(name string) Option

WithTLSConfig 设置 MySQL 驱动使用的 TLS 配置名称。

func WithTablePrefix

func WithTablePrefix(prefix string) Option

WithTablePrefix 设置命名策略中的表名前缀,仅修改该字段,不影响策略的其他配置。

func WithTimeout

func WithTimeout(timeout time.Duration) Option

WithTimeout 设置建立连接(拨号)超时时间。默认 10s。

func WithTranslateError

func WithTranslateError(enabled bool) Option

WithTranslateError 设置是否将驱动错误翻译为 GORM 统一错误类型(如 gorm.ErrDuplicatedKey)。

func WithTxRetryObserver

func WithTxRetryObserver(observer TxRetryObserver) Option

WithTxRetryObserver 设置事务重试观察者,事务发生重试时回调通知重试事件。

func WithUser

func WithUser(user string) Option

WithUser 设置连接用户名。

func WithWriteTimeout

func WithWriteTimeout(timeout time.Duration) Option

WithWriteTimeout 设置 I/O 写超时时间。默认 30s。

type PoolConfig

type PoolConfig struct {
	MaxOpenConns    int
	MaxIdleConns    int
	ConnMaxLifetime time.Duration
	ConnMaxIdleTime time.Duration
	// contains filtered or unexported fields
}

PoolConfig 描述 *sql.DB 连接池参数。 每个字段仅在通过 DefaultConfig 或对应 Option 显式设置后才会应用到连接池, 未设置的字段保持 database/sql 的原有行为。

type TxOption

type TxOption func(*txOptions)

TxOption 配置事务重试行为。

func WithMaxRetries

func WithMaxRetries(n int) TxOption

WithMaxRetries 设置死锁后的最大重试次数。 设为 0 表示禁用重试。默认值:3。

func WithRetryBaseWait

func WithRetryBaseWait(d time.Duration) TxOption

WithRetryBaseWait 设置指数退避的基础等待时间。 默认值:5ms。

func WithRetryMaxWait

func WithRetryMaxWait(d time.Duration) TxOption

WithRetryMaxWait 设置单次重试退避的最大等待时间。 默认值:50ms。

type TxRetryEvent

type TxRetryEvent struct {
	ClientName string
	Attempt    int
	MaxRetries int
	Wait       time.Duration
	Err        error
}

TxRetryEvent 描述一次事务死锁重试事件。

type TxRetryObserver

type TxRetryObserver func(ctx context.Context, event TxRetryEvent)

TxRetryObserver 在每次事务重试等待前被调用,用于观测重试事件(如记录日志、上报指标)。

Directories

Path Synopsis
Package zlogger 提供基于 zap 的 GORM 日志适配器, 实现 gorm.io/gorm/logger 的 Interface,支持慢查询阈值、 日志级别、忽略 ErrRecordNotFound、参数化 SQL 以及 trace ID 关联等配置。
Package zlogger 提供基于 zap 的 GORM 日志适配器, 实现 gorm.io/gorm/logger 的 Interface,支持慢查询阈值、 日志级别、忽略 ErrRecordNotFound、参数化 SQL 以及 trace ID 关联等配置。

Jump to

Keyboard shortcuts

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