记一次 gorm 中连接池打满的情况 1131次阅读 golang 2022-05-16 #### 背景 在一次使用 gorm 做数据迁移时,遇到了每次脚本运行一会儿就报错显示连接数超了 ``` {"error": "Error 1040: Too many connections"} ``` #### 排查步骤 1. 查看数据库设置的最大连接数是多少 ``` show variables like '%max_connections%'; ``` 连接数设置的是 6512 基本可以排除数据库设置问题 2. 查看脚本中是否配置了连接池 ``` // 获取通用数据库对象 sql.DB ,然后使用其提供的功能 sqlDB, err := db.DB() // SetMaxIdleConns 用于设置连接池中空闲连接的最大数量。 sqlDB.SetMaxIdleConns(10) // SetMaxOpenConns 设置打开数据库连接的最大数量。 sqlDB.SetMaxOpenConns(100) // SetConnMaxLifetime 设置了连接可复用的最大时间。 sqlDB.SetConnMaxLifetime(time.Hour) ``` 脚本设置的连接池大小为 100,因此也不是脚本连接池的原因 3. 检查是否有连接未释放 导致连接未释放通常是以下 2 个原因: * 事务未关闭 ``` # 开始事务 tx := conn.Begin() if err != nil { # 事务回滚 tx.Rollback() .... } # 提交事务 tx.Commit() ..... ``` **注意: 关闭事务时, *必须将开始的事务保存到变量(tx)中,* 后续也必须使用 tx 来提交或回滚事务, *不可直接使用 conn 来提交事务*, 以下是错误示例:** ``` conn.Begin() if err != nil { conn.Rollback() .... } conn.Commit() ... ``` 我遇到的问题就是事务使用方式错误导致的 * 使用了 rows 方法,未手动 close ``` rows, err := db.rows( # rows请一定要在err==nil的情况下使用,不然会导致空指针panic。 if err != nil { return err } # 使用之手动关闭 defer rows.close() ``` [参考文档](https://wenku.baidu.com/view/4d46901240323968011ca300a6c30c225901f082.html) WechatAlipay手机上阅读 最后一次更新于2022-05-16 golang gorm 连接池