Go mysql驱动程序挂起连接

时间:2017-11-28 19:38:59

标签: mysql go

我用这么简单的代码遇到了一些奇怪的情况:

func InitDatabase(dataSourceName string) {

    var err error
    DBCon, err = sql.Open("mysql", dataSourceName)

    if err != nil {
        log.Panic(err)
    }

    log.Println("Ping...")

    if err = DBCon.Ping(); err != nil { // <- it hangs here
        log.Println(":(")
    }

    log.Println(":)")
}

我调试并发现它在此行中锁定了goroutine(fd_poll_runtime.go,第85行),看起来甚至没有连接:

res := runtime_pollWait(pd.runtimeCtx, mode)

它可以在这里等待多年,我的mac变得非常热。

我做了一个小改动:

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
if err = DBCon.PingContext(ctx); err != nil {
    log.Println(":(")
}

log.Println(":)")

它仍然挂起,超时不起作用。

问题是,它在昨天工作了(而且,有趣的是,它适用于我朋友的机器,相同的参数),现在它甚至在重新启动后和重新安装mysql之后都没有(在终端/ goland / mysqlworkbench中完美运行)。

转到版本1.9,mysql驱动程序:“github.com/go-sql-driver/mysql”,mysql版本:5.7.20 Homebrew,macos版本:High Sierra 10.13.1,我在localhost上托管mysql,端口3306。

更新

终于奏效了。我将init代码复制到了干净的项目,并在那里工作。我开始注释掉代码,找出问题所在。我发现我在导入的包中有这个代码。即使这个包中的代码在数据库ping之后执行,但init代码之前执行并且以某种方式阻止了db.Ping()

func init() {
    for i := 1; i <= maxWorkers; i++ {
        go func(i int) {
            for {
                select {
                case j, ok := <-jobs:
                    if ok {
                        j.invoke()
                    } else {
                        // loop
                    }
                default:
                    // loop
                }
            }
        }(i)
    }
}

我重写了方法名称,并在数据库ping之后执行它,一切正常。

我不知道为什么会这样,但如果你有答案,可以随意发布。

0 个答案:

没有答案