From 7db509e682891f3bc501c7b23e32e02c64893557 Mon Sep 17 00:00:00 2001 From: Daniel Theophanes Date: Sat, 29 Sep 2018 22:10:43 -0700 Subject: [PATCH] database/sql: correctly report MaxIdleClosed stat Previously the MaxIdleClosed counter was incremented when added to the free connection list, rather then when it wasn't added to the free connection list. Flip this logic to correct. Fixes #27792 Change-Id: I405302c14fb985369dab48fbe845e5651afc4ccf Reviewed-on: https://go-review.googlesource.com/c/138578 Run-TryBot: Daniel Theophanes TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/database/sql/sql.go | 10 ++++--- src/database/sql/sql_test.go | 52 ++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go index 7537f87d47cf5..7c8d46b1008dc 100644 --- a/src/database/sql/sql.go +++ b/src/database/sql/sql.go @@ -1322,11 +1322,13 @@ func (db *DB) putConnDBLocked(dc *driverConn, err error) bool { err: err, } return true - } else if err == nil && !db.closed && db.maxIdleConnsLocked() > len(db.freeConn) { - db.freeConn = append(db.freeConn, dc) + } else if err == nil && !db.closed { + if db.maxIdleConnsLocked() > len(db.freeConn) { + db.freeConn = append(db.freeConn, dc) + db.startCleanerLocked() + return true + } db.maxIdleClosed++ - db.startCleanerLocked() - return true } return false } diff --git a/src/database/sql/sql_test.go b/src/database/sql/sql_test.go index f194744aefe72..e52091c3afd0c 100644 --- a/src/database/sql/sql_test.go +++ b/src/database/sql/sql_test.go @@ -3415,6 +3415,58 @@ func TestConnectionLeak(t *testing.T) { wg.Wait() } +func TestStatsMaxIdleClosedZero(t *testing.T) { + db := newTestDB(t, "people") + defer closeDB(t, db) + + db.SetMaxOpenConns(1) + db.SetMaxIdleConns(1) + db.SetConnMaxLifetime(0) + + preMaxIdleClosed := db.Stats().MaxIdleClosed + + for i := 0; i < 10; i++ { + rows, err := db.Query("SELECT|people|name|") + if err != nil { + t.Fatal(err) + } + rows.Close() + } + + st := db.Stats() + maxIdleClosed := st.MaxIdleClosed - preMaxIdleClosed + t.Logf("MaxIdleClosed: %d", maxIdleClosed) + if maxIdleClosed != 0 { + t.Fatal("expected 0 max idle closed conns, got: ", maxIdleClosed) + } +} + +func TestStatsMaxIdleClosedTen(t *testing.T) { + db := newTestDB(t, "people") + defer closeDB(t, db) + + db.SetMaxOpenConns(1) + db.SetMaxIdleConns(0) + db.SetConnMaxLifetime(0) + + preMaxIdleClosed := db.Stats().MaxIdleClosed + + for i := 0; i < 10; i++ { + rows, err := db.Query("SELECT|people|name|") + if err != nil { + t.Fatal(err) + } + rows.Close() + } + + st := db.Stats() + maxIdleClosed := st.MaxIdleClosed - preMaxIdleClosed + t.Logf("MaxIdleClosed: %d", maxIdleClosed) + if maxIdleClosed != 10 { + t.Fatal("expected 0 max idle closed conns, got: ", maxIdleClosed) + } +} + type nvcDriver struct { fakeDriver skipNamedValueCheck bool