Golang,mysql:错误1040:连接太多

时间:2015-01-25 10:55:06

标签: mysql go

我正在使用github.com/go-sql-driver/mysql驱动程序。

我打开一个数据库:

db, err := sql.Open("mysql", str)

然后我有两个函数,每个函数被调用200次,后面跟着mysql代码:

rows, err := db.Query("select name from beehives")
if err != nil {
    panic(err)
}       
defer rows.Close()

第二个:

    err = db.QueryRow("select id, secret, shortname from beehives where shortname = ?", beehive).Scan(&id, &secre
    switch {
    case err == sql.ErrNoRows:
        err = errors.New("Beehive '"+beehive+"' not found.")
    case err != nil:
        panic("loginBeehive: "+ err.Error())
    default:
        // ... do the work

第一个是慌乱。

当我只打开一次数据库时,怎么会有多个连接?如何关闭它们?

5 个答案:

答案 0 :(得分:22)

sql.Open doesn't really open a connection to your database.

sql.DB维护与数据库的连接池。每次查询数据库时,程序都会尝试从此池中获取连接,否则将创建一个新的连接。一旦你关闭它们,这些连接就会被放回池中。

这是rows.Close()的作用。 当您致电db.QueryRow("...")时,Scan(...)会在内部做同样的事情。

基本问题是您创建了太多查询,其中每个查询都需要连接,但您没有足够快地关闭连接。这样,您的程序必须为每个查询创建一个新连接。

您可以通过调用sql.DB上的SetMaxOpenConns来限制程序使用的最大连接数。

有关详细信息,请参阅http://go-database-sql.org/surprises.html

答案 1 :(得分:6)

您从*DB返回的sql.Open对象与连接不对应。最好将其视为数据库的句柄:它为您管理连接池。

您可以使用`(*DB).SetMaxOpenConnsits pair来控制空闲连接的打开连接数。

所以基本上这里发生的是db.Querydb.QueryRow尝试为自己获取连接,并且DB句柄不会对同时连接的数量施加任何限制,因此您的代码会引起恐慌当它打开超过mysql可以处理的内容时。

答案 2 :(得分:3)

尝试制作准备好的语句db.Prepare(query string) (*Stmt, error)而不是stmt.Querystmt.Exec而不是stmt.Close来重复使用连接。

答案 3 :(得分:0)

我的程序始终连接到数据库。 (出勤的实时面部识别)

因此,打开和关闭数据库连接毫无用处。

因此,它仅在初始化程序的情况下才打开数据库连接。

func GetAllFaces() interface{} {
    OpenDatabaseConnection() ... 
}

但是稍后访问数据库,增加了连接数,并导致程序崩溃。但是关闭rows对象不会使活动连接最少。 (对我来说1)

 func SaveAttendance(faceId int, date time.Time) error {
    sqlQuery := fmt.Sprintf("SELECT ... "))

    rows, err := DB.Query(sqlQuery) ...
    err = rows.Close()
    return err
}

答案 4 :(得分:0)

嗨,您可以在使用后尝试关闭连接

db, err := sql.Open("mysql", str)
defer db.Close() // close after end scope