Description
Issue description
MySQL 8.0.24 changed the server-side behaviour when encountering a wait_timeout
. The client now receives an error packet with ER_CLIENT_INTERACTION_TIMEOUT
rather than just finding an EOF.
Another GitHubber previously implemented a connection liveness check in #934. This was implemented with MySQL 5 in mind, and prints a "closing bad idle connection: unexpected read from socket" error when it reads anything from the socket of a connection that it expects to be idle.
With MySQL 8.0.24, this message is now really confusing, because it's no longer totally unexpected for there to be data to read if the idle connection has reached the wait_timeout
. It fails to expose the underlying error that's been sent to the client, and makes it difficult to diagnose.
It would be nice if the driver could check if the data that it's read is an error packet and, if so, log the error message instead of "unexpected read from socket".
Example code
docker run -e MYSQL_ROOT_PASSWORD=test -p 3306:3306 mysql:8.0.24
package main
import (
"database/sql"
"fmt"
"time"
"github.com/go-sql-driver/mysql"
)
func main() {
mysql.SetLogger(logger{})
db, err := sql.Open("mysql", "root:test@tcp(127.0.0.1:3306)/mysql")
if err != nil {
panic(err)
}
defer db.Close()
if _, err := db.Exec("SET GLOBAL wait_timeout = 5"); err != nil {
panic(err)
}
time.Sleep(10 * time.Second)
rows, err := db.Query("SHOW TABLES")
if err != nil {
panic(err)
}
defer rows.Close()
}
type logger struct{}
func (logger) Print(v ...interface{}) {
fmt.Printf("mysql: ")
fmt.Println(v...)
}
Error log
closing bad idle connection: unexpected read from socket
Configuration
Driver version (or git SHA): 1.7.0
Go version: 1.19.5
Server version: MySQL 8.0.24+
Server OS: E.g. Debian 8.1 (Jessie), Windows 10