sql.Rows удерживает соединение из пула sql.DB до вызова Close(). Если забыть закрыть rows, соединение "утекает":
// Утечка соединения:
rows, err := db.Query("SELECT id FROM users")
if err != nil { return err }
// забыли defer rows.Close()!
for rows.Next() { ... }
// Правильно:
rows, err := db.Query("SELECT id FROM users")
if err != nil { return err }
defer rows.Close() // обязательно!
for rows.Next() { ... }
if err := rows.Err(); err != nil { return err }
Последствия утечки:
SetMaxOpenConns(25) после 25 утечек все новые запросы зависнут навсегдаДля одной строки используйте db.QueryRow() - не требует Close().