当我终止具有长时间运行的查询的连接时,会得到如下信息:
[MySQL] 2013/12/05 22:17:19 packets.go:30: EOF
[MySQL] 2013/12/05 22:17:19 statement.go:24: Invalid Connection
[MySQL] 2013/12/05 22:17:27 packets.go:30: EOF
[MySQL] 2013/12/05 22:17:27 statement.go:24: Invalid Connection
[MySQL] 2013/12/05 22:17:39 packets.go:30: EOF
[MySQL] 2013/12/05 22:17:39 statement.go:24: Invalid Connection
我习惯于看到此错误:
2013 (HY000) at line 1: Lost connection to MySQL server during query
据我所知,该错误实际上是通过网络连接发送回被杀死的客户端的。 这是在驱动程序或数据库/ sql中被掩盖了,还是我认为不是通过协议传输的错误? 我们能以某种方式更清楚地说明正在发生什么吗?
不,不会传输任何错误。 错误实际上是什么都收不到:wink:
但是打印比EOF
更具描述性的错误消息可能是一个好主意
我猜statement.go:24: Invalid Connection
错误是http://golang.org/issue/5718的结果
在数据库/ sql程序包中修复自动重新连接逻辑后,这些错误应消失。
EOF
只是io.EOF
,我不确定是否应该过滤并替换它。 在这种情况下使用它是一种Go习惯用法(例如,在net程序包中,此错误源于此)。 但至少含义应记录在某处。
你怎么看?
我也想听听@gkristic对此的看法。 他一直在研究它。
我遵循了数据库/ sql中的代码。 statement.go:24: Invalid Connection
错误不是http://golang.org/issue/5718的结果,尽管我同意@julienschmidt的观点,即程序包应尝试重试。 在数据库级别运行Query()
和Exec()
调用最多可进行十次尝试,但在使用Stmt接收器时则没有尝试。
@xaprb看到的“无效连接”是由于在为准备好的语句调用Close()
时,MySQL连接不再可用,即stmt.mc.netConn
在这里为nil。 这是一条无害的消息,因为一旦返回ErrBadConn
,数据库/ sql的连接将被关闭。
但这不是我见过的唯一可能性; database / sql(Go 1.2)可能存在一些并发问题,也可能最终以该消息结尾。 如果在使用驱动程序连接时关闭了(database / sql)语句,则计划在noteUnusedDriverStatement()
的下一个putConn()
处关闭该驱动程序语句。 但是putConn()
可以在调用removeOpenStmt()
之前运行(请参阅(*Stmt) finalClose()
)。 如果在调用挂起的onPut
函数之后,由于空闲连接限制而关闭了连接本身,则程序包将尝试再次关闭该语句,从而产生消息。 这再次是无害的,但是仍然很烦人。
恕我直言Go的数据库/ sql需要仔细重新访问...
@gkristic您是否建议驱动程序进行任何更改?
数据库/ sql软件包有一些缺陷,我希望对Go 1.3进行一些改进。 重新访问依赖性管理是我列表中的一项。
如果您发现此类问题,请通过https://code.google.com/p/go/issues/list报告
鉴于这些情况(即连接丢失或数据库/ sql两次关闭)是无害的,我希望驱动程序以静默方式跳过这些情况,而不是打印“ Invalid Connection”(无效连接)消息。 我认为,后者可能是:吓人,如果您不知道那是无害的; 烦人的,一旦你做; 但如果在其他位置(行号除外)打印了相同的消息,则可能会产生误导,从而隐藏了真正的警告,您可以轻松跳过该警告。 如果stmt.mc
或stmt.mc.netConn
在语句Close()
函数中为零,我希望返回而无需进一步记录。 另外,请注意,在此处返回driver.ErrBadConn
(在4d3764bbcb17c31575642626baeab1bcdc30c301中引入)绝对无效,因为数据库/ sql不会检查语句关闭的返回码。
附带说明一下,我可能会添加一个功能来调整记录器。 当前, errLog
已在包内初始化,并且是私有的。 打印到可能会或可能不会出现的标准错误; 也就是说,进程可能出于其他原因选择关闭描述符。 但是,即使不是这样,用户对于日志记录也可能有不同的想法(考虑文件,syslog等)。 该驱动程序可以提供此默认记录器,但也可以允许用户设置其他记录器。
一旦有空余时间,我将为前面提到的问题准备一个小例子,并写一份报告。
谢谢!
@gkristic关于记录器-您的意思是类似https://github.com/go-sql-driver/mysql/pull/182 (一周前合并为master)?
@arnehormann哦,伙计...就是那个。 我一直在使用v1.1。 我在发布之前也检查了master上的其他内容,但忘了检查日志记录。 对不起,谢谢!
@gkristic根本不是问题:咧嘴笑:
在下一个版本之前应该做的任何更改? 欢迎PRs :)
大家好,这里是go-sql-driver的新用户。 我注意到类似的问题,但想知道是否有人可以帮助我确认原因是否相同? 在使用goroutine的长期运行的cron中,我通常会收到以下内容。
[MySQL] 2014/05/14 20:33:05 packets.go:356: Busy buffer
[MySQL] 2014/05/14 20:33:05 packets.go:73: EOF
[MySQL] 2014/05/14 20:33:05 statement.go:24: Invalid Connection
[MySQL] 2014/05/14 20:33:05 connection.go:206: Invalid Connection
我非常愿意在这里弄脏我的手,只是在寻找有关如何解决该问题的指导。 在某些情况下可以忽略此“无效连接”错误吗? 如果检测到此连接,是否可以自动获取另一个连接?
呃,哦...现在我知道了,我错过了上周五的@julienschmidt发表的评论。 (我向朱利安道歉。) @rmulley ,您似乎遇到了我在上面描述的相同问题。 看这个评论。 statement.go:24上的“无效连接”是无害的。 驱动程序应该通过选择其他连接来做适当的事情。 不过,我不确定“忙缓冲区”; 我不记得曾经看到过。 自从我检查了这段代码已经有一段时间了。 我将抽出一些时间再看一遍,看看是否能帮上忙。 不幸的是,这不可能在下周结束之前发生。 但是到那时我会再给你的。
@rmulley :对我来说,这似乎与这个问题无关。
如果您使用的是go get
安装的版本(这是旧版本),请尝试使用当前的git master版本重现此错误。
请再打开一期新书。 触发此错误的最小代码示例肯定会有所帮助。
似乎(b *buffer) takeBuffer
返回nil
。 这似乎仅在b.length > 0
。 这意味着由于某种原因,缓冲区中有未读的数据。
我以前从未见过此错误,并且仅实施了这些额外的检查以提高安全性。 我永远不会相信这种错误。
根据#206,此错误实际上在从尖端运行go时消失了。 实际上不是这样吗?
首先,对我在度假中的迟到答复感到抱歉,然后忘记跟进。 我确保我拥有最新版本的MySQL驱动程序,并且现在正在使用Go 1.3进行测试。 看来我现在在错误消息中看到了更多详细信息。
[MySQL] 2014/06/23 11:46:04 packets.go:356: Busy buffer
[MySQL] 2014/06/23 11:46:04 packets.go:73: read tcp xxx.xxx.xxx.xx:3306: connection reset by peer
这是我的MySQL问题吗? (关于如何解决此问题,我没有在网上找到任何有用的信息)
还是我可以检查一下然后以某种方式重新连接我的代码的东西?
我遇到了与rmulley描述的问题相同的问题。 不同的是,“忙缓冲区”出现在极短的查询中(短至1 Query + 2 Exec)。
我觉得问题与准备好的陈述有关。 我发现如果我在交易中准备了一份声明,例如
stmt, err = tx.Prepare("SELECT ...")
在准备另一条语句之前,我必须关闭此stmt,否则每次都会遇到“忙缓冲区”。 如果我不使用准备好的语句,例如直接对tx进行操作,例如
tx.Query("...")
或者
tx.Exec("...")
,很好。
并且,如果我准备一条语句然后执行其他Query或Exec其他内容,那也很好...只是在不关闭前一条语句的情况下不要准备另一条语句,而且看起来还不错。
希望这确实是问题所在。
谢谢。
您可以创建一个小型Go程序来重现错误吗?
它似乎绝对是驱动程序中的错误,但与此处报告的原始问题无关。
请创建一个新的问题。
我认为这是问题所在:
package main
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, _ := sql.Open("mysql", "/")
defer db.Close()
tx, err := db.Begin()
if err != nil {
panic(err)
}
defer tx.Commit()
stmt1, err := tx.Prepare("SELECT 1")
if err != nil {
panic(err)
}
rows1, err := stmt1.Query()
if err != nil {
panic(err)
}
stmt2, err := tx.Prepare("SELECT 2")
if err != nil {
// rows1 is not closed -> triggers busy buffer because transaction is on one connection
// and stmt1, stmt2 use the same one.
// Move rows1.Close() in front of tx.Prepare and it disappears
panic(err)
}
rows2, err := stmt2.Query()
if err != nil {
panic(err)
}
rows1.Close()
rows2.Close()
stmt1.Close()
stmt2.Close()
}
我刚遇到类似的繁忙缓冲区问题,可以确认@arnehormann似乎是正确的。 当行对象仍处于打开状态时,尝试对多个查询使用同一事务时,会发生此问题
嗨,大家好,我不知道这个问题是否得到解决。 我在用“ Exec”执行的短插入中看到此问题->
var sql =“插入表(f1,f2 ... f25)值(?,?,...?)中
_,err:= db.Exec(sql,...)
大约4000次后,有时有5000次插入,我得到“意外的EOF”和“繁忙的缓冲区”。
插入是紧密的(在for循环中),但是每个插入之间都有一个REST请求,因此,触发的速度不是那么快。 相同的连接参考。 这是Go 1.3。
谢谢,
萨尔
@Sal-使用go 1.4会发生什么?
在2014年12月31日,星期三,晚上10:11,Sal A. Magnone [email protected]
写道:
嗨,大家好,我不知道这个问题是否得到解决。 我看到了
用“ Exec”执行短插入的问题->var sql =“插入表(f1,f2 ... f25)值(?,?,...?)中
_,err:= db.Exec(sql,...)大约4000次之后,有时插入5000次,我得到“意外的EOF”和“忙碌”
缓冲”。
插入紧密(在for循环中),但是之间存在REST请求
每一个都没有那么快的开火; 相同的连接参考。 这是Go 1.3。谢谢,
萨尔-
直接回复此电子邮件或在GitHub上查看
https://github.com/go-sql-driver/mysql/issues/185#issuecomment -68479413。
感谢您的回复。
1.4 –相同的错误。 在大约20分钟内在4205个插件上死亡(每个插件之间都有网和屏幕I / O)。
我已经对代码进行了重构,可以选择从上次停止的地方开始。 因此,对于此应用程序而言并不重要,但如果这是一个累积请求问题,则对于该项目中的其他应用程序可能至关重要。
萨尔
来自:carbocation [mailto:[email protected]]
发送时间:2015年1月4日,星期日,上午9:50
至:go-sql-driver / mysql
抄送:Sal A. Magnone
主题:Re:[mysql]终止连接时出现奇怪的错误(#185)
@Sal-使用go 1.4会发生什么?
在2014年12月31日星期三晚上10:11,Sal A.Magnone < [email protected] [email protected] >
写道:
嗨,大家好,我不知道这个问题是否得到解决。 我看到了
用“ Exec”执行短插入的问题->var sql =“插入表(f1,f2 ... f25)值(?,?,...?)中
_,err:= db.Exec(sql,...)大约4000次之后,有时插入5000次,我得到“意外的EOF”和“忙碌”
缓冲”。
插入紧密(在for循环中),但是之间存在REST请求
每一个都没有那么快的开火; 相同的连接参考。 这是Go 1.3。谢谢,
萨尔-
直接回复此电子邮件或在GitHub上查看
https://github.com/go-sql-driver/mysql/issues/185#issuecomment -68479413。
-
直接回复此电子邮件,或在GitHub https://github.com/go-sql-driver/mysql/issues/185#issuecomment -68635254上查看。 https://github.com/notifications/beacon/AA4DdvfCFMdiqPlTZITEs9VrxyyJqqFQks5neUqigaJpZM4BSM1b.gif
这个线程现在变成几个线程了吗? 是否应该将最新评论放到新的期刊中,并且此评论已经结束?
@xaprb我同意,我认为现在有一些https://github.com/go-sql-driver/mysql/issues/185#issuecomment -68479413引入新版本。
最有用的评论
我认为这是问题所在: