mirror of
https://github.com/MariaDB/server.git
synced 2026-04-23 08:45:33 +02:00
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
This commit is contained in:
parent
354e567c23
commit
18954ff25d
4 changed files with 105 additions and 10 deletions
27
mysql-test/suite/federated/error_on_close-8313.result
Normal file
27
mysql-test/suite/federated/error_on_close-8313.result
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
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;
|
||||
38
mysql-test/suite/federated/error_on_close-8313.test
Normal file
38
mysql-test/suite/federated/error_on_close-8313.test
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#
|
||||
# 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)
|
|||
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
|
||||
|
|
@ -1683,18 +1697,15 @@ int ha_federated::close(void)
|
|||
delete_dynamic(&results);
|
||||
|
||||
/* Disconnect from mysql */
|
||||
THD *thd= ha_thd();
|
||||
Net_error_handler err_handler;
|
||||
if (thd)
|
||||
thd->push_internal_handler(&err_handler);
|
||||
mysql_close(mysql);
|
||||
mysql= NULL;
|
||||
if (thd)
|
||||
thd->pop_internal_handler();
|
||||
|
||||
/*
|
||||
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();
|
||||
mysql= NULL;
|
||||
|
||||
DBUG_RETURN(free_share(share));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1795,6 +1795,20 @@ int ha_federatedx::open(const char *name, int mode, uint test_if_locked)
|
|||
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
|
||||
|
|
@ -1825,7 +1839,12 @@ int ha_federatedx::close(void)
|
|||
txn->release(&io);
|
||||
DBUG_ASSERT(io == NULL);
|
||||
|
||||
Net_error_handler err_handler;
|
||||
if (thd)
|
||||
thd->push_internal_handler(&err_handler);
|
||||
free_share(txn, share);
|
||||
if (thd)
|
||||
thd->pop_internal_handler();
|
||||
|
||||
DBUG_RETURN(retval);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue