1
0
mirror of https://github.com/golang/go synced 2024-11-18 19:54:44 -07:00

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: 0f205ede43
GitHub-Pull-Request: golang/go#38263
Reviewed-on: https://go-review.googlesource.com/c/go/+/227278
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Daniel Theophanes <kardianos@gmail.com>
This commit is contained in:
Colin 2020-04-22 15:53:52 +00:00 committed by Daniel Theophanes
parent 0a00926481
commit 12579009b3

View File

@ -432,7 +432,7 @@ type DB struct {
waitCount int64 // Total number of connections waited for. waitCount int64 // Total number of connections waited for.
maxIdleClosed int64 // Total number of connections closed due to idle count. maxIdleClosed int64 // Total number of connections closed due to idle count.
maxIdleTimeClosed int64 // Total number of connections closed due to idle time. 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. 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:]) copy(db.freeConn, db.freeConn[1:])
db.freeConn = db.freeConn[:numFree-1] db.freeConn = db.freeConn[:numFree-1]
conn.inUse = true conn.inUse = true
db.mu.Unlock()
if conn.expired(lifetime) { if conn.expired(lifetime) {
db.maxLifetimeClosed++
db.mu.Unlock()
conn.Close() conn.Close()
return nil, driver.ErrBadConn return nil, driver.ErrBadConn
} }
db.mu.Unlock()
// Reset the session if required. // Reset the session if required.
if err := conn.resetSession(ctx); err == driver.ErrBadConn { 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 // This prioritizes giving a valid connection to a client over the exact connection
// lifetime, which could expire exactly after this point anyway. // lifetime, which could expire exactly after this point anyway.
if strategy == cachedOrNewConn && ret.err == nil && ret.conn.expired(lifetime) { if strategy == cachedOrNewConn && ret.err == nil && ret.conn.expired(lifetime) {
db.mu.Lock()
db.maxLifetimeClosed++
db.mu.Unlock()
ret.conn.Close() ret.conn.Close()
return nil, driver.ErrBadConn 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) { if err != driver.ErrBadConn && dc.expired(db.maxLifetime) {
db.maxLifetimeClosed++
err = driver.ErrBadConn err = driver.ErrBadConn
} }
if debugGetPut { if debugGetPut {