Gorm适配PgBouncer事务池模式的配置及预编译语句报错问题
适配PgBouncer事务池模式的Gorm配置问题
已耗时4天仍未解决该问题,连ChatGPT也无法提供有效帮助。
概况
- 基于Go语言、Gin-gonic v1.9.0搭建API
- 使用Gorm ORM v1.24.5对接DigitalOcean托管的PostgreSQL 14
- 数据库启用PgBouncer的
pool_mode = transaction模式
核心问题
无法正确配置Gorm适配PgBouncer事务池模式,确保每个API请求执行SQL后将连接归还到PgBouncer连接池。已知Gorm底层依赖jackc/pgx库,该库提供pgxpool及连接的Acquire&Release能力,但未找到Gorm的适配说明。
预编译语句相关问题
在设置PrepareStmt: false和PreferSimpleProtocol: true之前,频繁遇到prepared statement_* already exists错误。事务模式下PgBouncer不支持预编译语句,因此关闭了该功能。但部署仅含一个端点的API测试时,仍有至少1/4的SQL查询报错ERROR: prepared statement_6230 doesn't exists。执行SELECT * FROM pg_prepared_statements;发现预编译语句存活约30分钟(推测至连接断开),执行DEALLOCATE ALL仅能清除当前语句。
代码示例
func main() { ... client := setupPostgresql() ... r.GET("/deploy/:id", func(c *gin.Context) { id := c.Param("id") var deploy Deploy // small model timeoutCtx, cancel := context.WithTimeout(c.Request.Context(), 5*time.Second) defer cancel() if err := client.WithContext(timeoutCtx).Where("id = ?", id).First(&deploy).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"error": "Deploy with id: " + id + " not found"}) return } else { log.Panic(err) // it will be covered by gin recover } } c.AbortWithStatusJSON(http.StatusOK, deploy) }) ... } func setupPostgresql() *gorm.DB { dsn := "host=" + AppConfig.DBHost + " user=" + AppConfig.DBUser + " password=" + AppConfig.DBPass + " dbname=" + AppConfig.DBName + " port=" + AppConfig.Port + " sslmode=" + AppConfig.SSL client, err := gorm.Open(postgres.New(postgres.Config{ DSN: dsn, PreferSimpleProtocol: true, }), &gorm.Config{ SkipDefaultTransaction: false, DisableAutomaticPing: true, PrepareStmt: false, NowFunc: func() time.Time { return time.Now().UTC() }, Logger: logger.Default.LogMode(logger.Silent), }) ... underlyingDB, _ := client.DB() underlyingDB.SetMaxIdleConns(11) underlyingDB.SetMaxOpenConns(11) underlyingDB.SetConnMaxIdleTime(15 * time.Minute) underlyingDB.SetConnMaxLifetime(30 * time.Minute) return client }
架构示例

预期目标
正确配置Gorm ORM以适配PgBouncer事务池模式。
内容的提问来源于stack exchange,提问作者hangofki
相关产品推荐
相关产品推荐

