go-sql-driver / mysql

Go MySQL Driver is a MySQL driver for Go's (golang) database/sql package
https://pkg.go.dev/github.com/go-sql-driver/mysql
Mozilla Public License 2.0
14.45k stars 2.3k forks source link

closing bad idle connection: EOF #1584

Closed cong08 closed 3 months ago

cong08 commented 3 months ago

Issue description

Occasionally, an error occurs, but it is not consistently reproducible. Sometimes, after a long period of inactivity, the error appears when a query is executed. I have already set ConnMaxLifetime, which makes this issue even more puzzling.

Example code

sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(10)
sqlDB.SetMaxOpenConns(100)
sqlDB.SetConnMaxLifetime(time.Duration(240) * time.Second)

Error log

[mysql] 2024/05/17 09:19:00 packets.go:122: closing bad idle connection: EOF
[mysql] 2024/05/17 09:19:00 connection.go:173: driver: bad connection

Configuration

Driver version (or git SHA): v1.7.1 Go version: go1.21.4 Server version: MySQL 8.0.23 Server OS: debian:stable-slim

cong08 commented 3 months ago

MySQL image

cong08 commented 3 months ago

I found the following log in the service area: 2024-05-16T11:13:29.336399Z 7367834 [Note] [MY-010914] [Server] Aborted connection 7367834 to db: '' user: '' host: '' (Got timeout reading communication packets). (sql_connect.cc:835) 2024-05-16T11:14:10.286303Z 7367835 [Note] [MY-013417] [Server] The wait_timeout period was exceeded, the idle time since last command was too long. (net_serv.cc:1508) However, the MySQL wait_timeout is set to 28800, and I have set ConnMaxLifetime to 240s. It seems that the server is actively closing the connection. Could it be that ConnMaxLifetime is not taking effect? Should I also set SetConnMaxIdleTime? If SetConnMaxIdleTime is set to a time greater than ConnMaxLifetime, will it close the connection?

methane commented 3 months ago

That 4 lines of code is not enought to reproduce. Can you reproduce it with Docker MySQL? And can you write complete, runnable sample code?

Anyway, only I can say is Go received EOF. It means someone close the connection. wait_timeout is common, but not only reason to close connections. Your OS, router, middleware, etc... can close your connection. And as your server says, someone between Go and MySQL closed your connection.

I can not debug your environment. You should debug your environment with Wireshark and tcpdump.