Skip to content

duplicate operations cause by maxBadConnRetries #582

Closed
@yanghuashuai

Description

@yanghuashuai

Issue description

duplicate operations cause by maxBadConnRetries cause by read timeout, source code:
github.com/go-sql-driver/mysql/packets.go

  23 // Packets documentation:
  24 // http://dev.mysql.com/doc/internals/en/client-server-protocol.html
  25
  26 // Read packet to buffer 'data'
  27 func (mc *mysqlConn) readPacket() ([]byte, error) {
  28     var prevData []byte
  29     for {
  30         // read packet header
  31         data, err := mc.buf.readNext(4)
  32         if err != nil {
  33             errLog.Print(err)
  34             mc.Close()
  35             return nil, driver.ErrBadConn
  36         }

As define in go/src/database/sql/driver/driver.go:

 65 // ErrBadConn should be returned by a driver to signal to the sql
 66 // package that a driver.Conn is in a bad state (such as the server
 67 // having earlier closed the connection) and the sql package should
 68 // retry on a new connection.
 69 //
 70 // To prevent duplicate operations, ErrBadConn should NOT be returned
 71 // if there's a possibility that the database server might have
 72 // performed the operation. Even if the server sends back an error,
 73 // you shouldn't return ErrBadConn.
 74 var ErrBadConn = errors.New("driver: bad connection")

So, why read timeout return ErrBadConn ?

Example code

package main

import (
    "database/sql"
    "fmt"

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

func main() {
    db, _ := sql.Open("mysql", "root:123456@tcp(10.94.99.247:3306)/mysql?charset=utf8&parseTime=True&loc=Local&timeout=200ms&readTimeout=1s&writeTimeout=200ms")
    _, err := db.Exec("select sleep(?)", 2)
    if err != nil {
        fmt.Println(err.Error())
    }
}

Error log

[mysql] 2017/05/02 17:29:32 packets.go:33: read tcp 10.97.212.42:50230->10.94.99.247:3306: i/o timeout
[mysql] 2017/05/02 17:29:33 packets.go:33: read tcp 10.97.212.42:50231->10.94.99.247:3306: i/o timeout
[mysql] 2017/05/02 17:29:34 packets.go:33: read tcp 10.97.212.42:50232->10.94.99.247:3306: i/o timeout
driver: bad connection

Configuration

Driver git SHA:
147bd02

Go version:
go version go1.8 darwin/amd64

Server version:
mysqld Ver 5.6.28 for Linux on x86_64 (MySQL Community Server (GPL))

Server OS:
Linux kvm36130.sg 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions