go-sql-driver / mysql

Go MySQL Driver is a MySQL driver for Go's (golang) database/sql package
https://pkg.go.dev/github.com/go-sql-driver/mysql
Mozilla Public License 2.0
14.45k stars 2.3k forks source link

`use of closed network connection` occurs rarely when context is canceled during establishing a connection #1614

Closed yokonao closed 1 month ago

yokonao commented 1 month ago

Issue description

Executing query returns context.Canceled in most cases when context canceled. However, we see use of closed network connection rarely when context canceled during querying or executing.

For error handling purposes, it is preferable to always return context.Canceled.

similar issue: https://github.com/go-sql-driver/mysql/issues/1078

Example code

package main

import (
    "context"
    "errors"
    "log"
    "os"
    "time"

    "github.com/go-sql-driver/mysql"
)

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    dsn := "mysql:" + os.Getenv("DB_PASSWD") + "@tcp(127.0.0.1:3306)/?allowNativePasswords=true&tls=preferred"
    connector, err := mysql.MySQLDriver{}.OpenConnector(dsn)
    if err != nil {
        log.Fatal(err)
    }

    go func() {
        time.Sleep(10 * time.Millisecond) // may be need to adjust the sleep time.
        cancel()
    }()
    conn, err := connector.Connect(ctx)
    if err != nil {
        if errors.Is(err, context.Canceled) {
            log.Println("context canceled. no problem.")
            return
        }
        panic(err) // use of closed network connection
    }
    defer conn.Close()
}

It seems that use of closed network connection occurs when ctx is canceled at a specific timing while the connection is being established.

Error log

panic: read tcp 127.0.0.1:51710->127.0.0.1:3306: use of closed network connection

Configuration

Driver version (or git SHA): v1.7.1 f20b2863636093e5fbf1481b59bdaff3b0fbb779 Go version: go version go1.22.4 darwin/arm64 Server version: Mysql 8.0

Server OS: Debian GNU/Linux 11 (bullseye)