Commit 18954ff2 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-8313 Got an error writing communication packets

Don't let network errors from mysql_close() leak into THD.

* remove incorrect upstream fix
** table->in_use can be NULL, must use ha_thd()
** clear_error() may remove earlier errors, don't use it
* fix the bug properly in federated and federatedx
parent 354e567c
CREATE DATABASE federated;
CREATE DATABASE federated;
connection slave;
create table t1 (foo int, bar int);
connection master;
create server 's1' foreign data wrapper 'mysql' options
(HOST 'localhost',
DATABASE 'test',
USER 'root',
PASSWORD '',
SOCKET 'SLAVE_MYSOCK');
create table t1 (foo integer, bar integer) engine=federated
connection='s1';
select * from t1;
foo bar
connection slave;
connection master;
drop table t1;
drop server s1;
connection slave;
drop table t1;
connection master;
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
connection slave;
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
#
# MDEV-8313 Got an error writing communication packets
#
source include/federated.inc;
enable_connect_log;
connection slave;
create table t1 (foo int, bar int);
connection master;
--replace_result $SLAVE_MYSOCK SLAVE_MYSOCK
eval create server 's1' foreign data wrapper 'mysql' options
(HOST 'localhost',
DATABASE 'test',
USER 'root',
PASSWORD '',
SOCKET '$SLAVE_MYSOCK');
eval create table t1 (foo integer, bar integer) engine=federated
connection='s1';
select * from t1;
connection slave;
source include/restart_mysqld.inc;
connection master;
drop table t1;
drop server s1;
connection slave;
drop table t1;
source include/federated_cleanup.inc;
...@@ -1662,6 +1662,20 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked) ...@@ -1662,6 +1662,20 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
class Net_error_handler : public Internal_error_handler
{
public:
Net_error_handler() {}
public:
bool handle_condition(THD *thd, uint sql_errno, const char* sqlstate,
MYSQL_ERROR::enum_warning_level level,
const char* msg, MYSQL_ERROR ** cond_hdl)
{
return sql_errno >= ER_ABORTING_CONNECTION &&
sql_errno <= ER_NET_WRITE_INTERRUPTED;
}
};
/* /*
Closes a table. We call the free_share() function to free any resources Closes a table. We call the free_share() function to free any resources
...@@ -1683,18 +1697,15 @@ int ha_federated::close(void) ...@@ -1683,18 +1697,15 @@ int ha_federated::close(void)
delete_dynamic(&results); delete_dynamic(&results);
/* Disconnect from mysql */ /* Disconnect from mysql */
THD *thd= ha_thd();
Net_error_handler err_handler;
if (thd)
thd->push_internal_handler(&err_handler);
mysql_close(mysql); mysql_close(mysql);
mysql= NULL; if (thd)
thd->pop_internal_handler();
/* mysql= NULL;
mysql_close() might return an error if a remote server's gone
for some reason. If that happens while removing a table from
the table cache, the error will be propagated to a client even
if the original query was not issued against the FEDERATED table.
So, don't propagate errors from mysql_close().
*/
if (table->in_use)
table->in_use->clear_error();
DBUG_RETURN(free_share(share)); DBUG_RETURN(free_share(share));
} }
......
...@@ -1795,6 +1795,20 @@ int ha_federatedx::open(const char *name, int mode, uint test_if_locked) ...@@ -1795,6 +1795,20 @@ int ha_federatedx::open(const char *name, int mode, uint test_if_locked)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
class Net_error_handler : public Internal_error_handler
{
public:
Net_error_handler() {}
public:
bool handle_condition(THD *thd, uint sql_errno, const char* sqlstate,
MYSQL_ERROR::enum_warning_level level,
const char* msg, MYSQL_ERROR ** cond_hdl)
{
return sql_errno >= ER_ABORTING_CONNECTION &&
sql_errno <= ER_NET_WRITE_INTERRUPTED;
}
};
/* /*
Closes a table. We call the free_share() function to free any resources Closes a table. We call the free_share() function to free any resources
...@@ -1825,7 +1839,12 @@ int ha_federatedx::close(void) ...@@ -1825,7 +1839,12 @@ int ha_federatedx::close(void)
txn->release(&io); txn->release(&io);
DBUG_ASSERT(io == NULL); DBUG_ASSERT(io == NULL);
Net_error_handler err_handler;
if (thd)
thd->push_internal_handler(&err_handler);
free_share(txn, share); free_share(txn, share);
if (thd)
thd->pop_internal_handler();
DBUG_RETURN(retval); DBUG_RETURN(retval);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment