我在长期运行的Go应用程序中遇到以下MySQL错误:
Can't create more than max_prepared_stmt_count statements (current value: 16382)
在我的main.go
文件中,创建一个具有两个sql.Stmt
字段的结构。这样,我打算重用这些准备好的语句。
在factory.go
中,代码看起来像这样:
func NewFactory(db *sql.DB) (*Factory, error) {
insertStmt, err := db.Prepare("INSERT INTO `table` (`a`, `b`, `c`) VALUES (?,?,?);")
// Same for deleteStmt
if err != nil {
return nil, err
}
f := &Factory{
insertStmt: insertStmt,
deleteStmt: deleteStmt,
}
return f, nil
}
在我的main.go
中:
db, err := sql.Open("mysql", "...")
if err != nil {
panic(err)
}
db.SetConnMaxLifetime(time.Minute)
factory, err := NewFactory(db)
// start a web server and handle those calls (basically an endless loop until the app is stopped)
注意:我不打insertStmt.Close()
,因为我想重复使用此准备好的语句。
我已读过http://go-database-sql.org/prepared.html,其中说一条准备好的语句绑定到单个数据库连接。我知道设置db.SetConnMaxLifetime(time.Minute)
会在闲置一分钟后关闭连接,但是这样做是为了防止服务器关闭连接(MySQL wait_timeout
参数)时出现错误,但客户端仍然认为连接仍然有效
任何人都可以解释正在发生的事情以及如何防止准备好的语句的建立吗?