From 12579009b3f7eb6d137863d5ca87e295c9d88641 Mon Sep 17 00:00:00 2001 From: Colin Date: Wed, 22 Apr 2020 15:53:52 +0000 Subject: [PATCH] database/sql: count connections expired in foreground with MaxLifetimeClosed Previously the connection pool would only count connections expired in the background connectionCleaner goroutine towards the MaxLifetimeClosed stat. This change increments the stat correctly when checking for expiry in when acquiring and releasing a connection. Fixes #38058 Change-Id: Id707ddd40a42a4c38658d5f2931da131647d6c29 GitHub-Last-Rev: 0f205ede439efa355a628b6112450f2ca9ced005 GitHub-Pull-Request: golang/go#38263 Reviewed-on: https://go-review.googlesource.com/c/go/+/227278 Run-TryBot: Emmanuel Odeke TryBot-Result: Gobot Gobot Reviewed-by: Daniel Theophanes --- src/database/sql/sql.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go index b63d5591f6..6e31714445 100644 --- a/src/database/sql/sql.go +++ b/src/database/sql/sql.go @@ -432,7 +432,7 @@ type DB struct { waitCount int64 // Total number of connections waited for. maxIdleClosed int64 // Total number of connections closed due to idle count. maxIdleTimeClosed int64 // Total number of connections closed due to idle time. - maxLifetimeClosed int64 // Total number of connections closed due to max free limit. + maxLifetimeClosed int64 // Total number of connections closed due to max connection lifetime limit. stop func() // stop cancels the connection opener and the session resetter. } @@ -1208,11 +1208,13 @@ func (db *DB) conn(ctx context.Context, strategy connReuseStrategy) (*driverConn copy(db.freeConn, db.freeConn[1:]) db.freeConn = db.freeConn[:numFree-1] conn.inUse = true - db.mu.Unlock() if conn.expired(lifetime) { + db.maxLifetimeClosed++ + db.mu.Unlock() conn.Close() return nil, driver.ErrBadConn } + db.mu.Unlock() // Reset the session if required. if err := conn.resetSession(ctx); err == driver.ErrBadConn { @@ -1268,6 +1270,9 @@ func (db *DB) conn(ctx context.Context, strategy connReuseStrategy) (*driverConn // This prioritizes giving a valid connection to a client over the exact connection // lifetime, which could expire exactly after this point anyway. if strategy == cachedOrNewConn && ret.err == nil && ret.conn.expired(lifetime) { + db.mu.Lock() + db.maxLifetimeClosed++ + db.mu.Unlock() ret.conn.Close() return nil, driver.ErrBadConn } @@ -1352,6 +1357,7 @@ func (db *DB) putConn(dc *driverConn, err error, resetSession bool) { } if err != driver.ErrBadConn && dc.expired(db.maxLifetime) { + db.maxLifetimeClosed++ err = driver.ErrBadConn } if debugGetPut { -- 2.50.0