Subject: | auto_reconnect not matching CR_SERVER_LOST (only CR_SERVER_GONE_ERROR) |
Originally reported by Wouter de Jong at
http://bugs.mysql.com/bug.php?id=27613
Description:
mysql_auto_reconnect is not working for me in DBI 3.002 through 4.004
when the server is sending a CR_SERVER_LOST (error 2013). This happens
in my case when the 'low' wait-timeout on the server has been reached.
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;
My idea is that when the wait_timeout is hit, the connection should also
be restored automatically. Eg. I don't see a big difference in
CR_SERVER_GONE_ERROR and CR_SERVER_LOST.
How to repeat:
What I do to test this :
my $dbh = DBI->connect("DBI:mysql:database=test;host=$h",$u,$p) ||
die("mysql_connect() failed\n");
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);
}
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.
You could opt for doing a disconnect before the sleep() and then make a
connection after the sleep again, but the real code is way more complex
and dynamic in time runs (eg. I/O operation). That would make more and
more connect/disconnect operations that aren't usually necessary
(wait_timeout is only seldom reached).
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;
See original bug report for more details.