Я сталкиваюсь со следующей ошибкой MySQL из моего давно запущенного приложения Go: 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 /prepare.html , в котором говорится, что подготовленный оператор связан с одним подключением к базе данных. Я знаю, что настройка db.SetConnMaxLifetime(time.Minute)
закроет соединение после минуты простоя, но это сделано для предотвращения ошибок, когда сервер закрыл соединение (параметр MySQL wait_timeout
), но клиент все еще думает, что соединение живо.
Может кто-нибудь объяснить, что происходит и как я могу предотвратить накопление подготовленных заявлений?