Subject: | auto_reconnect not matching CR_SERVER_LOST (only CR_SERVER_GONE_ERROR) |
Date: | Wed, 22 Aug 2007 09:46:19 +0200 |
To: | bug-DBD-mysql [...] rt.cpan.org |
From: | Wouter de Jong <wouter [...] widexs.nl> |
Hello,
I'd like to report a 'bug', that's probably not 100% DBD::mysql's fault but it
can be simply worked around in DBD::mysql...
It's about mysql_auto_reconnect.
Let me explain the situation :
When a connection to MySQL is lost, MySQL returns 2 different errors :
If connecting to MySQL via localhost : SERVER_GONE
If connecting to MySQL on a remote server (not on the same host) : SERVER_LOST
The problem I have is that DBD::mysql 3.002 through 4.005+ is not
recognizing the SERVER_LOST error as a valid reason for
mysql_auto_reconnect, which occurs when the connection to a _remote_ server is
lost.
Now when the wait_timeout has been reached on a server (could be because
of various reason, eg. I/O operations taking longer then wait_timeout),
DBD::mysql can't reconnect.
Reason is that in dbdimp.c : mysql_db_reconnect() is only checking
against CR_SERVER_GONE_ERROR (error 2006).
if (mysql_errno(&imp_dbh->mysql) != CR_SERVER_GONE_ERROR)
/* Other error */
return FALSE;
* How to repeat:
MySQL : wait_timeout = 60
#!/usr/bin/perl -w
my $dbh = DBI->connect("DBI:mysql:database=test;host=$h",$u,$p) ||
die("mysql_connect()
failed\n");
$dbh->{'mysql_auto_reconnect'} = 1;
printf("AMOUNT: %d\n",run_q());
sleep(90);
printf("AMOUNT: %d\n",run_q());
$dbh->disconnect();
sub run_q {
my $_sth = $dbh->prepare("SELECT 100 AS amount");
$_sth->execute();
my $_amount = $_sth->fetchrow;
return($_amount);
}
* Expected Result:
AMOUNT: 100
AMOUNT: 100
* Actual Result:
AMOUNT: 100
DBD::mysql::st execute failed: Lost connection to MySQL server during
query at ./test.pl
line 38.
DBD::mysql::st fetchrow failed: fetch() without execute() at ./test.pl
line 39.
Use of uninitialized value in printf at ./test.pl line 26.
AMOUNT: 0
---
The 2nd run_q fails since the wait_timeout on the MySQL-server has been
exceeded, and the server has closed the connection and sent error 2013.
* Suggested fix:
Add a check for CR_SERVER_LOST (error 2013).
--- dbdimp.c Tue Apr 3 14:54:56 2007
+++ dbdimp.c-lost Tue Apr 3 14:47:49 2007
@@ -4434,7 +4434,7 @@
else
imp_dbh= (imp_dbh_t*) imp_xxh;
- if (mysql_errno(&imp_dbh->mysql) != CR_SERVER_GONE_ERROR)
+ if (mysql_errno(&imp_dbh->mysql) != CR_SERVER_GONE_ERROR &&
mysql_errno(&imp_dbh->mysql) != CR_SERVER_LOST)
/* Other error */
return FALSE;
It's quite important for us to have this 'bug' fixed :)
Many thanks for a response.
Kind regards,
Wouter de Jong
--
WideXS http://www.widexs.nl
Wouter de Jong System-Administrator
Tel +31 (0)23 5698070 Fax +31 (0)23 5698099
Bijlmermeerstraat 62, 2131 HG HOOFDDORP, NL