From a9b61b0029713c3b567ca33be50ad5b2a44045fb Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Mon, 10 Nov 2014 16:21:59 +0530 Subject: [PATCH] Bug#17599258:- ERROR 1160 (08S01): GOT AN ERROR WRITING COMMUNICATION PACKETS; FEDERATED TABLE Description:- Execution of FLUSH TABLES on a federated table which has been idle for wait_timeout (on the remote server) + tcp_keepalive_time, fails with an error, "ERROR 1160 (08S01): Got an error writing communication packets." Analysis:- During FLUSH TABLE execution the federated table is closed which will inturn close the federated connection. While closing the connection, federated server tries to communincate with the remote server. Since the connection was idle for wait_timeout(on the remote server)+ tcp_keepalive_time, the socket gets closed. So this communication fails because of broken pipe and the error is thrown. But federated connections are expected to reconnect silently. And also it cannot reconnect because the "auto_reconnect" variable is set to 0 in "mysql_close()". Fix:- Before closing the federated connection, in "ha_federated_close()", a check is added which will verify wheather the connection is alive or not. If the connection is not alive, then "mysql->net.error" is set to 2 which will indicate that the connetion is broken. Also the setting of "auto_reconnect" variable to 0 is delayed and is done after "COM_QUIT" command. NOTE:- For reproducing this issue, "tcp_keepalive_time" has to be set to a smaller value. This value is set in the "/proc/sys/net/ipv4/tcp_keepalive_time" file in Unix systems. So we need root permission for changing it, which can't be done through mtr test. So submitting the patch without mtr test. --- sql-common/client.c | 4 ++-- storage/federated/ha_federated.cc | 14 +++++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/sql-common/client.c b/sql-common/client.c index 850daa38750..c874086fc9c 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -3808,8 +3808,8 @@ void STDCALL mysql_close(MYSQL *mysql) { free_old_query(mysql); mysql->status=MYSQL_STATUS_READY; /* Force command */ - mysql->reconnect=0; simple_command(mysql,COM_QUIT,(uchar*) 0,0,1); + mysql->reconnect=0; end_server(mysql); /* Sets mysql->net.vio= 0 */ } mysql_close_free_options(mysql); diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index 409b4c40804..541b3327ad4 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1678,9 +1678,17 @@ int ha_federated::close(void) DBUG_ENTER("ha_federated::close"); free_result(); - + delete_dynamic(&results); - + + /* + Check to verify wheather the connection is still alive or not. + FLUSH TABLES will quit the connection and if connection is broken, + it will reconnect again and quit silently. + */ + if (mysql && !vio_is_connected(mysql->net.vio)) + mysql->net.error= 2; + /* Disconnect from mysql */ mysql_close(mysql); mysql= NULL;