mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
MDEV-29605 Reset queued ping info of all spider connections associated with a closed spider handler
A spider_conn may outlive its associated ha_spider (in the field queued_ping_spider) used for connecting to and pinging the data node (a call to spider_db_ping(), guarded by the boolean field queued_ping). In a call to ha_spider::close() (which is often preceded with the deletion of the ha_spider itself), many cleanups happen, including freeing the associated spider_share, which is used by the spider_conn in spider_db_ping. Therefore it is necessary to reset both the queued_ping_spider and queued_ping fields, so that any further spider interaction with the data node will not trigger the call using the ha_spider including its freed spider_share. Also out of caution added an assert and internal error in case a connection has not been established (the db_conn field of type MYSQL * is NULL), and attempt to connect is skipped because both queued_connect and queued_ping are false. Note that this unlikely (if not impossible) scenario would not be a regression caused by this change, as it strictly falls under the scenario of this bug.
This commit is contained in:
parent
f862fe8b2b
commit
18a44b4298
4 changed files with 71 additions and 0 deletions
|
@ -513,6 +513,28 @@ static void spider_update_current_trx_ha_with_freed_share(SPIDER_SHARE *share)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Given an ha_spider that is being closed, reset the queued ping info
|
||||
of SPIDER_CONN of the current spider trx that has the given
|
||||
ha_spider as the queued_ping_spider.
|
||||
*/
|
||||
static void spider_reset_conn_queued_ping(ha_spider *spider)
|
||||
{
|
||||
SPIDER_TRX *trx= spider_current_trx;
|
||||
if (trx)
|
||||
{
|
||||
for (uint i= 0; i < trx->trx_conn_hash.records; i++)
|
||||
{
|
||||
SPIDER_CONN *conn= (SPIDER_CONN *) my_hash_element(&trx->trx_conn_hash, i);
|
||||
if (conn->queued_ping_spider == spider)
|
||||
{
|
||||
conn->queued_ping= FALSE;
|
||||
conn->queued_ping_spider= NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ha_spider::close()
|
||||
{
|
||||
int error_num = 0, roop_count, error_num2;
|
||||
|
@ -622,6 +644,7 @@ int ha_spider::close()
|
|||
result_list.tmp_sqls = NULL;
|
||||
}
|
||||
|
||||
spider_reset_conn_queued_ping(this);
|
||||
spider_update_current_trx_ha_with_freed_share(share);
|
||||
spider_free_share(share);
|
||||
is_clone = FALSE;
|
||||
|
|
19
storage/spider/mysql-test/spider/bugfix/r/mdev_29605.result
Normal file
19
storage/spider/mysql-test/spider/bugfix/r/mdev_29605.result
Normal file
|
@ -0,0 +1,19 @@
|
|||
for master_1
|
||||
for child2
|
||||
for child3
|
||||
set spider_same_server_link= 1;
|
||||
CREATE USER spider@localhost IDENTIFIED BY 'pwd';
|
||||
GRANT ALL ON test.* TO spider@localhost;
|
||||
CREATE SERVER srv FOREIGN DATA WRAPPER mysql
|
||||
OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'spider', password 'pwd');
|
||||
SET autocommit=0;
|
||||
set @old_init_connect=@@global.init_connect;
|
||||
set global init_connect="dummy";
|
||||
CREATE TABLE t ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"' AS SELECT 1;
|
||||
Got one of the listed errors
|
||||
set global init_connect=@old_init_connect;
|
||||
drop server srv;
|
||||
drop user spider@localhost;
|
||||
for master_1
|
||||
for child2
|
||||
for child3
|
25
storage/spider/mysql-test/spider/bugfix/t/mdev_29605.test
Normal file
25
storage/spider/mysql-test/spider/bugfix/t/mdev_29605.test
Normal file
|
@ -0,0 +1,25 @@
|
|||
--disable_query_log
|
||||
--disable_result_log
|
||||
--source ../../t/test_init.inc
|
||||
--enable_result_log
|
||||
--enable_query_log
|
||||
|
||||
set spider_same_server_link= 1;
|
||||
CREATE USER spider@localhost IDENTIFIED BY 'pwd';
|
||||
GRANT ALL ON test.* TO spider@localhost;
|
||||
evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql
|
||||
OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'spider', password 'pwd');
|
||||
SET autocommit=0;
|
||||
set @old_init_connect=@@global.init_connect;
|
||||
set global init_connect="dummy";
|
||||
--error ER_NET_ERROR_ON_WRITE,12701
|
||||
CREATE TABLE t ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"' AS SELECT 1;
|
||||
set global init_connect=@old_init_connect;
|
||||
drop server srv;
|
||||
drop user spider@localhost;
|
||||
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
--source ../../t/test_deinit.inc
|
||||
--enable_result_log
|
||||
--enable_query_log
|
|
@ -2119,6 +2119,10 @@ int spider_db_mbase::exec_query(
|
|||
general_log_write(current_thd, COM_QUERY, tmp_query_str.ptr(),
|
||||
tmp_query_str.length());
|
||||
}
|
||||
/* There should be a live connection to the data node */
|
||||
DBUG_ASSERT(db_conn);
|
||||
if (!db_conn)
|
||||
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
|
||||
if (!spider_param_dry_access())
|
||||
{
|
||||
error_num = mysql_real_query(db_conn, query, length);
|
||||
|
|
Loading…
Reference in a new issue