mysql: packets.go:36: unexpected EOF (Invalid Connection)
Issue description
Getting Invalid Connection issues.
Error log
[mysql] 2017/09/26 22:38:16 packets.go:36: unexpected EOF
[HTTP Server] http: panic serving xxx.xxx.xxx.xxx:39727: runtime error: invalid memory address or nil pointer dereference
goroutine 25 [running]:
net/http.(*conn).serve.func1(0x1a83a2a0)
/usr/local/go/src/net/http/server.go:1697 +0x9f
panic(0x84ed320, 0x8849160)
/usr/local/go/src/runtime/panic.go:491 +0x1d0
database/sql.(*Stmt).Close(0x0, 0x0, 0x0)
/usr/local/go/src/database/sql/sql.go:2335 +0x2d
main.postLogin.func1(0x88225e0, 0x1a840a00)
/root/go/src/app/main.go:977 +0x1b8
github.com/kataras/iris/context.Next(0x88225e0, 0x1a840a00)
/root/go/src/github.com/kataras/iris/context/context.go:851 +0xce
github.com/kataras/iris/context.(*context).Next(0x1a840a00)
/root/go/src/github.com/kataras/iris/context/context.go:1063 +0x2b
main.main.func2(0x88225e0, 0x1a840a00)
/root/go/src/app/main.go:57 +0x24f
github.com/kataras/iris/context.Do(0x88225e0, 0x1a840a00, 0x1a827d18, 0x2, 0x2)
/root/go/src/github.com/kataras/iris/context/context.go:864 +0x61
github.com/kataras/iris/context.(*context).Do(0x1a840a00, 0x1a827d18, 0x2, 0x2)
/root/go/src/github.com/kataras/iris/context/context.go:1006 +0x43
github.com/kataras/iris/core/router.(*routerHandler).HandleRequest(0x1a8317f0, 0x88225e0, 0x1a840a00)
/root/go/src/github.com/kataras/iris/core/router/handler.go:216 +0x3f1
github.com/kataras/iris/core/router.(*Router).BuildRouter.func1(0x88198a0, 0x1a578090, 0x1a89a580)
/root/go/src/github.com/kataras/iris/core/router/router.go:70 +0x6d
github.com/kataras/iris/core/router.(*Router).ServeHTTP(0x1a75bb60, 0x88198a0, 0x1a578090, 0x1a89a580)
/root/go/src/github.com/kataras/iris/core/router/router.go:147 +0x37
net/http.serverHandler.ServeHTTP(0x1a59f980, 0x88198a0, 0x1a578090, 0x1a89a580)
/usr/local/go/src/net/http/server.go:2619 +0x8e
net/http.(*conn).serve(0x1a83a2a0, 0x881a0a0, 0x1a8898c0)
/usr/local/go/src/net/http/server.go:1801 +0x5d1
created by net/http.(*Server).Serve
/usr/local/go/src/net/http/server.go:2720 +0x1f6
[mysql] 2017/09/26 22:38:16 connection.go:158: invalid connection
Go version: run go version in your console
=> go1.9 linux/386
Server version: E.g. MySQL 5.6, MariaDB 10.0.20 => 5.5.56-MariaDB
Server OS: E.g. Debian 8.1 (Jessie), Windows 10 => Centos
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 15 (5 by maintainers)
Commits related to this issue
- sci-server: reduce db max connection lifetime Fixes invalid connection errors according to https://github.com/go-sql-driver/mysql/issues/674 — committed to uoregon-libraries/student-course-integrator by jechols 6 years ago
- DBs max idle conns set to 0 Something to do with how golangs sql library functions. https://github.com/go-sql-driver/mysql/issues/674 for reference. — committed to Stachio/go-sqlssx by Stachio 5 years ago
The way to solve is :-
db.SetMaxIdleConns(0)General solution is
DB.SetConnMaxLifetime(time.Second).Root cause is TCP and request-response protocol. HTTP keep-alive has same problem. Client should have shorter timeout than server. Otherwise, client may try to use dead connection. And if the request may not be idempotent, client can’t retry automatically.
For example, AWS’s ELB (load balancer, which is “client” to application) has 60sec keep-alive. And it recommends 120sec keep-alive timeout on application server side. https://aws.amazon.com/jp/premiumsupport/knowledge-center/apache-backend-elb/
We recently ran into a similar issue, frequently seeing
packets.go:36 unexpected EOFandi/o timeouterrors. We found these blog posts very helpful in balancing our connection pool and resolving the issue.Even if server’s wait_timeout is long enough, router or OS may close long idle connection to reduce resource usage. Which cause this error too. So I recommend 1sec ~ 10sec timeout, unless you’re network expert and you know optimal timeout length.
It’s up to your application. In application using hundreds queries/sec, even only 1 second reduce connection overhead less than 1/100. But 1sec may be too defensive for most cases. 1~3 minutes may be better in general.
SetConnMaxIdleTime solves only one problem (someone closes long idle TCP connection). SetConnMaxLifetime solves some other pitfalls too. For example:
SET GLOBAL) doesn’t applied to existing connections. If you setSetConnMaxLifetime(time.Minute), changed system variables are applied in 1 minute.You can imagine many scenarios that forever reused connections make trouble. Limiting max lifetime is the best practice to keep your whole system healthy.
That’s why I recommend SetConnMaxLifetime even for Go 1.15+. SetConnMaxLifetime is useful only when you really need to set different timeout for lifetime and idletime. But it’s very rare. Setting only SetConnMaxLifetime is enough for 99.99% users.
Another way to solve this is to set the tcp keep alive on the connection:
You didn’t read my comments on various places? Use SetConnMaxLifetime().
He didn’t say default configuration. You must use DB.SetConnMaxLifetime to use “e all retry, reconnect, connection pooling, timeout logic.”
Have you read my comments before bloat posting?? I never recommended such settings. In this issue, I recommended 1sec~10sec. I feel it was too defensive. 10sec~1min will be recommended in general.