应使用@gorm.io/driver/postgres驱动并正确配置SSL模式(本地disable、生产verify-full),端口为26257,初始化后必须调db.Ping()验证连接,所有写操作需显式事务包裹,主键推荐UUID以避免热点。

直接用 @gorm.io/driver/postgres,别碰 cockroachdb/cockroach-go 这类废弃包 —— CockroachDB 兼容 PostgreSQL wire 协议,GORM 原生支持,只需调对驱动、配对连接串。
连接串必须显式禁用或配置 SSL,否则连不上
CockroachDB 默认强制 TLS(哪怕本地 cockroach start --insecure),而 GORM 的 postgres 驱动默认走 sslmode=require。不改就会卡在 failed to connect to `host=localhost user=root database=defaultdb`: server error (FATAL: SSL is required) 或更隐蔽的 dial tcp [::1]:26257: connect: connection refused。
- 本地开发(
--insecure):连接串末尾加?sslmode=disable,例如postgresql://root@localhost:26257/defaultdb?sslmode=disable - 生产启用 TLS:必须带
sslrootcert=/path/to/ca.crt且设sslmode=verify-full,不能只写require - 端口别错:CockroachDB 默认是
26257,不是 PostgreSQL 的5432
初始化时必须调 db.Ping(),否则首次查询才暴露连接失败
gorm.Open() 只校验 DSN 格式,不真正建连。如果连接串写错、服务没起来、SSL 配置漏了,db.Ping() 才会真实触发错误 —— 否则你可能在第一个 Create() 或 Find() 里才看到 panic。
- 务必在
gorm.Open()后立刻加if err := db.Ping(); err != nil { log.Fatal(err) } - 不要依赖
defer db.Close()就以为万事大吉;Ping()是唯一轻量级探活手段
事务必须手动 Begin/Commit,GORM 自动事务在 CRDB 上不可靠
CockroachDB 不支持隐式单语句事务,也不允许 SAVEPOINT(GORM 某些版本内部会悄悄用)。如果你用 db.Create(&u) 这类方法,它底层可能尝试自动开启事务,结果报 ERROR: SAVEPOINTs are not supported outside of a transaction 或更误导性的 current transaction is aborted。
- 所有写操作(
Create/Save/Delete)都应包裹在显式事务中:tx := db.Begin()→ 操作 →tx.Commit()或tx.Rollback() - CRDB 的自动重试只对显式事务生效;单条语句冲突直接返回 SQLSTATE
40001,需业务层捕获并重试 - 避免混用
db.Exec("INSERT ...")和 GORM 方法,事务上下文容易断裂
主键推荐用 UUID,避免 BIGINT 分布倾斜
CockroachDB 官方建议用 UUID 作主键,因为 gen_random_uuid() 能保证跨节点写入均匀分布;若用自增 BIGINT,所有新记录会集中写入单个 range,成为热点。
- GORM 中声明主键为 UUID:
ID uuid.UUID `gorm:"type:uuid;default:gen_random_uuid();primaryKey"` - 需确保数据库已启用
pgcrypto扩展:CREATE EXTENSION IF NOT EXISTS "pgcrypto" - 别用
int64+autoIncrement,即使能跑,长期看会拖慢写入吞吐
最易被忽略的是事务控制粒度和 SSL 模式绑定 —— 很多人连通了就以为 OK,结果上线后批量写入失败、重试逻辑不触发、连接池耗尽,问题全出在这两处。


















