From 5f74bcbcf0550e74cf0ac0170e5dd9f87683a355 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Mon, 9 Oct 2023 18:44:08 +0900 Subject: [PATCH] move stale connection check to ResetSession() (#1496) When ResetSession was added, it was called when the connection is put into the pool. Thet is why we had only set `mc.reset` flag on ResetSession(). In Go 1.15, this behavior was changed. (golang/go@971f8a2) ResetSession is called when the connection is checked out from the pool. So we can call checkConnLiveness() directly from ResetSession. --- connection.go | 27 +++++++++++++++++++++++++-- packets.go | 28 ---------------------------- 2 files changed, 25 insertions(+), 30 deletions(-) diff --git a/connection.go b/connection.go index 631a1dc24..660b2b0e0 100644 --- a/connection.go +++ b/connection.go @@ -34,7 +34,6 @@ type mysqlConn struct { status statusFlag sequence uint8 parseTime bool - reset bool // set when the Go SQL package calls ResetSession // for context support (Go 1.8+) watching bool @@ -646,7 +645,31 @@ func (mc *mysqlConn) ResetSession(ctx context.Context) error { if mc.closed.Load() { return driver.ErrBadConn } - mc.reset = true + + // Perform a stale connection check. We only perform this check for + // the first query on a connection that has been checked out of the + // connection pool: a fresh connection from the pool is more likely + // to be stale, and it has not performed any previous writes that + // could cause data corruption, so it's safe to return ErrBadConn + // if the check fails. + if mc.cfg.CheckConnLiveness { + conn := mc.netConn + if mc.rawConn != nil { + conn = mc.rawConn + } + var err error + if mc.cfg.ReadTimeout != 0 { + err = conn.SetReadDeadline(time.Now().Add(mc.cfg.ReadTimeout)) + } + if err == nil { + err = connCheck(conn) + } + if err != nil { + mc.cfg.Logger.Print("closing bad idle connection: ", err) + return driver.ErrBadConn + } + } + return nil } diff --git a/packets.go b/packets.go index a1aaf20ee..0127232ee 100644 --- a/packets.go +++ b/packets.go @@ -98,34 +98,6 @@ func (mc *mysqlConn) writePacket(data []byte) error { return ErrPktTooLarge } - // Perform a stale connection check. We only perform this check for - // the first query on a connection that has been checked out of the - // connection pool: a fresh connection from the pool is more likely - // to be stale, and it has not performed any previous writes that - // could cause data corruption, so it's safe to return ErrBadConn - // if the check fails. - if mc.reset { - mc.reset = false - conn := mc.netConn - if mc.rawConn != nil { - conn = mc.rawConn - } - var err error - if mc.cfg.CheckConnLiveness { - if mc.cfg.ReadTimeout != 0 { - err = conn.SetReadDeadline(time.Now().Add(mc.cfg.ReadTimeout)) - } - if err == nil { - err = connCheck(conn) - } - } - if err != nil { - mc.cfg.Logger.Print("closing bad idle connection: ", err) - mc.Close() - return driver.ErrBadConn - } - } - for { var size int if pktLen >= maxPacketSize {