-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EOF error in packets.go readPacket() not propagating #108
Comments
I don't see the problem with the code in |
Thanks for looking into this. Yes, you're right, I misread that method and it looks OK to me. Here are the relevant snippets of code we're using to connect, query, and iterate:
|
Please update your driver version to the current master with |
|
So that's what you meant with release tags in the other PR... 😃 |
Yes, but unfortunately it doesn't work as well as I hoped (and the documentation of the go get tool promised): https://code.google.com/p/go/issues/detail?id=5779 |
I did a simple "rm -fr src/github.com/go-sql-driver", removed pkg/, and then used "git clone" to fetch the latest and I'm still seeing the problem. If it would help, I can possibly provide a packet capture for you guys but I can't share it via github because it will contain proprietary data. |
Let's see if we can get some more debug info. There are several reasons which can cause an |
Is it still the same stacktrace? If I'm reading it right, readPacket can only get an io.EOF from buffer.readNext. That can only happen when the io.Reader in buffer reaches an io.EOF but there's still data missing. |
Please re-run it with the |
I've rebuilt with eof-debug and re-ran. Here's the stack trace:
|
There must be some other reason. The packet header said the packet body is 76 byte long but only 52 byte can be read. My guess is that something is killing the connection. |
Please measure the time from opening the connection / beginning read to the EOF. If it is a suspicious time like a multiple of 30s it is probably some sort of timeout killing the connection. Can you also send me the packet capture and your DSN from db.Open (of course without user/password) via mail to go at julienschmidt dot com |
After analyzing the log we know the following:
To sum up: I'm baffled. Some more things to try:
|
I think it's 46100 rows, not 110 (counted by number of occurences of the regexp |
Currently, we assume that the problem is not related to the driver. |
We observed in the packet trace that the connection is closed prematurely and the driver doesn't propagate that error up to the client. Even if we attribute the premature FIN to a quirk of my environment, isn't the failure to propagate the EOF up to the caller still a bug? |
The
Given that, I don't really know what else we should do. What sensible reaction should the driver provide? |
I'm also getting this error, but on line 69: [MySQL] 2013/08/22 15:45:07 packets.go:69: EOF I have tried to close the statement and the db connection and reopen them again after a certain iteration but the problem still persist. |
Yet another EOF... ok. |
I found another one! This looks great, a StackOverflow answer for a Python connection problem similar to yours. And I just remembered we had the same problem for some large queries once. Gotta love them MySQL easter eggs ❤️ 🎊 ❤️! EDIT one more thing: Please have a look at |
@pengux which server version are you running? I'm on 5.1.63. I'm seeing similar EOF errors: packets.go:31: EOF Unfortunately I haven't had time to dig into it further. @arnehormann: Is there a way to force use_result/store_result with the go-mysql-driver? It would be good to test both cases. |
I hope I'm right here but can't see any way I'm not (concerning PHP): Based on your tcpdump, that's not the case. Another thing to try: please change your failing |
OK, here are my findings: ... LIMIT 999999 Does not work SELECT SQL_NO_CACHE ... Does not work Store in a temporary slice, WORKS! @arnehormann You are correct that my iterations takes some times, up to a few seconds each. I select about 30k of rows in each select. So what's the correlation with this error? Edit: Storing the rows in a temporary array does work better, but not entirely. Before it would stop after about 1000 rows, but now it stops after about 5000 rows. |
@arnehormann Yes, appending the net_write_timeout=600 seems to fix the problem. Is it possible to make it the default value for a connection? |
@pengux Appending it makes it the default for all connections using that DSN. Do you mean the driver should make it the default for all connections? We won't do that. Appending it to the DSN only means this is called after a connection is established - just the query |
@arnehormann No, what I mean is that there is a default value for net_write_timeout which is obviously lower than 600 which cause this error. It would be great if the driver could set a good default value so that those who use it don't stumble upon this problem. Or maybe there is another implementation that could fix this issue? How does the PHP Mysql driver do it, because I've never encountered anything similar there even with same code? |
@pengux sorry, I messed up the markdown for a link above (read this...). I just fixed it, here's a copy for your convenience. And it's exactly what I meant. We can determine the default which is set. But why should the driver do that, that's just another default query most people don't need (two if you factor in the discovery of the current value, the default appears to be one minute btw.). This is a server side issue, caused by the servers configuration and it can be fixed with a little SQL. If you need it, you add it. If you don't, the driver shouldn't assume you do. I'd rather not have this activated by default than provide an option to disable it. The default value of one minute is perfectly fine for most people. I may still add this to the README. About PHP, I have no idea. It's a language I have experience with, but if I don't really have to, I prefer to keep my distance. For me, working with PHP causes an immediate urge to take a shower and cleanse myself. |
Some more patience please, @arnehormann 😉 |
@pengux I'd suggest you put this in your mysql config file instead of setting this for every single connection via the driver. |
Patience granted. You were pretty silent for some time, welcome back! |
I had the same problem. At least the error message should be improved to suggest this is a timeout problem. |
Can anyone still reproduce this with the current git master (not the go get version)? |
Thanks for continuing to investigate this. I am still seeing the EOF messages occasionally with the 'go get' version pulled a few days ago, and they aren't timeout related (see timestamps):
This corresponds to packets.go:
If you think that might be related to what you suspect is fixed, I'll pull master and push new binaries. Thanks. |
Yes, the git master has several changes which should improve this issue. |
OK, pushed. I'll keep you posted. |
Closed until we get new reports of this bug |
I'm running a query that is returning around 250k rows from a MySQL 5.1 server. Occasionally I will get incomplete result sets without an error being returned to my invocation of the API methods. The following is printed:
The relevant snippet of code:
Replacing "Print" with "Panic" shows the following stack trace:
[MySQL] 2013/07/10 11:23:33 packets.go:67: EOF
panic: EOF
goroutine 1 [running]:
log.(_Logger).Panic(0xc2000aa1e0, 0x7fd696a4f460, 0x1, 0x1)
/usr/local/go/src/pkg/log/log.go:193 +0xa7
github.com/go-sql-driver/mysql.(_mysqlConn).readPacket(0xc2000c3770, 0xc200100000, 0x66, 0x1000, 0xc2000ae000, ...)
ROOT/src/github.com/go-sql-driver/mysql/packets.go:67 +0x683
github.com/go-sql-driver/mysql.(_mysqlRows).readBinaryRow(0xc2000fe540, 0xc2000f6680, 0x4, 0x4, 0x0, ...)
ROOT/src/github.com/go-sql-driver/mysql/packets.go:861 +0x4e
github.com/go-sql-driver/mysql.(_mysqlRows).Next(0xc2000fe540, 0xc2000f6680, 0x4, 0x4, 0x0, ...)
ROOT/src/github.com/go-sql-driver/mysql/rows.go:68 +0x120
database/sql.(*Rows).Next(0xc2000c24e0, 0x676020)
/usr/local/go/src/pkg/database/sql/sql.go:1310 +0xc1
main.writeBooks(0xc2000c2120, 0xc2000aa5f0)
ROOT/src/example.com/sitemap/sitemapgenerator.go:152 +0x167
main.main()
ROOT/src/example.com/sitemap/sitemapgenerator.go:280 +0x87e
goroutine 2 [syscall]:
exit status 2
It looks like readBinaryRow is not actually returning the non-nil error, and instead returning early with a nil error:
func (rows *mysqlRows) readBinaryRow(dest []driver.Value) (err error) {
data, err := rows.mc.readPacket()
if err != nil {
return
}
This bug is particularly insidious because it is happening in a call to .Next(), which means that callers will be operating on partial result sets without knowing it.
System:
This happens with both an SSH port forward and when on a proper network connection (rackspace cloud).
The text was updated successfully, but these errors were encountered: