Commit 14c40509 authored by Yuchen Pei's avatar Yuchen Pei

MDEV-32492 Delete and remove trx_ha on spider share mismatch

A SPIDER_TRX_HA associated with a SPIDER_TRX could have longer
lifetime than its associated SPIDER_SHARE. And it is identified with
the associated table name. When the SPIDER_SHARE no longer valid, e.g.
when the associated spider table has been dropped and recreated, the
SPIDER_TRX_HA should be reset too.

Since spider could create a new SPIDER_SHARE with the exact same
address of a freed SPIDER_SHARE, we try to mark all SPIDER_TRX_HAs
associated with a SPIDER_SHARE invalid when the SPIDER_SHARE is about
to be freed.
parent 653050ac
...@@ -584,6 +584,25 @@ int ha_spider::open( ...@@ -584,6 +584,25 @@ int ha_spider::open(
DBUG_RETURN(error_num); DBUG_RETURN(error_num);
} }
/*
Given a SPIDER_SHARE that will be freed, update all SPIDER_TRX_HAs
of spider_current_trx to point to a NULL share, which will cause the
removal of the SPIDER_TRX_HA in spider_check_trx_ha().
*/
static void spider_update_current_trx_ha_with_freed_share(SPIDER_SHARE *share)
{
SPIDER_TRX *trx= spider_current_trx;
if (trx)
{
for (uint i = 0; i < trx->trx_ha_hash.records; i++)
{
SPIDER_TRX_HA *trx_ha = (SPIDER_TRX_HA *) my_hash_element(&trx->trx_ha_hash, i);
if (trx_ha->share == share)
trx_ha->share= NULL;
}
}
}
int ha_spider::close() int ha_spider::close()
{ {
int error_num = 0, roop_count, error_num2; int error_num = 0, roop_count, error_num2;
...@@ -711,6 +730,7 @@ int ha_spider::close() ...@@ -711,6 +730,7 @@ int ha_spider::close()
result_list.tmp_sqls = NULL; result_list.tmp_sqls = NULL;
} }
spider_update_current_trx_ha_with_freed_share(share);
spider_free_share(share); spider_free_share(share);
is_clone = FALSE; is_clone = FALSE;
pt_clone_source_handler = NULL; pt_clone_source_handler = NULL;
......
#
# MDEV-32492 SIGSEGV in spider_conn_first_link_idx on DELETE
#
for master_1
for child2
for child3
set spider_same_server_link= 1;
CREATE SERVER srv FOREIGN DATA WRAPPER mysql
OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
CREATE TABLE t (c INT, PRIMARY KEY(c)) ENGINE=Spider;
SHOW CREATE TABLE t;
Table Create Table
t CREATE TABLE `t` (
`c` int(11) NOT NULL,
PRIMARY KEY (`c`)
) ENGINE=SPIDER DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
Warnings:
Error 1429 Unable to connect to foreign data source: localhost
Error 1429 Unable to connect to foreign data source: localhost
DROP TABLE t;
CREATE TABLE t (c INT) ENGINE=Spider COMMENT='port "1 1"';
DELETE FROM t;
ERROR HY000: Unable to connect to foreign data source: localhost
drop table t;
CREATE TABLE t1 (a INT,b VARCHAR(255),PRIMARY KEY(a)) ENGINE=Spider comment="srv 'srv', table 't1', read_only_mode '1'";
INSERT INTO t1 VALUES (1,'aaa'),(2,'bbb'),(3,'ccc'),(4,'ddd');
ERROR HY000: Table 'test.t1' is read only
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
`b` varchar(255) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=SPIDER DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci COMMENT='srv ''srv'', table ''t1'', read_only_mode ''1'''
Warnings:
Error 12719 An infinite loop is detected when opening table test.t1
DROP TABLE t1;
CREATE TABLE t1 (a INT) ENGINE=Spider comment="port '123 456'";
INSERT IGNORE INTO t1 VALUES (42),(42);
ERROR HY000: Unable to connect to foreign data source: localhost
drop table t1;
CREATE TABLE t1 (c INT, KEY(c)) ENGINE=Spider COMMENT='WRAPPER "mysql", SRV "srv",TABLE "t2", PK_NAME "f"';
SET GLOBAL general_log=1;
INSERT INTO t1 VALUES (1, "aaa"),(2, "bbb"),(3, "ccc"),(4, "ddd");
ERROR 21S01: Column count doesn't match value count at row 1
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` int(11) DEFAULT NULL,
KEY `c` (`c`)
) ENGINE=SPIDER DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci COMMENT='WRAPPER "mysql", SRV "srv",TABLE "t2", PK_NAME "f"'
Warnings:
Error 12702 Remote table 'test.t2' is not found
DROP TABLE t1;
CREATE TABLE t1 (a INT) ENGINE=Spider comment='port "123 456"';
SELECT * FROM t1;
ERROR HY000: Unable to connect to foreign data source: localhost
INSERT IGNORE INTO t1 VALUES (42),(42);
ERROR HY000: Unable to connect to foreign data source: localhost
drop table t1;
drop server srv;
for master_1
for child2
for child3
#
# end of test mdev_32492
#
--echo #
--echo # MDEV-32492 SIGSEGV in spider_conn_first_link_idx on DELETE
--echo #
--disable_query_log
--disable_result_log
--source ../../t/test_init.inc
--enable_result_log
--enable_query_log
set spider_same_server_link= 1;
evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql
OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
CREATE TABLE t (c INT, PRIMARY KEY(c)) ENGINE=Spider;
--disable_ps_protocol
SHOW CREATE TABLE t;
--enable_ps_protocol
DROP TABLE t;
CREATE TABLE t (c INT) ENGINE=Spider COMMENT='port "1 1"';
--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
DELETE FROM t;
drop table t;
CREATE TABLE t1 (a INT,b VARCHAR(255),PRIMARY KEY(a)) ENGINE=Spider comment="srv 'srv', table 't1', read_only_mode '1'";
--error 12518
INSERT INTO t1 VALUES (1,'aaa'),(2,'bbb'),(3,'ccc'),(4,'ddd');
--disable_ps_protocol
SHOW CREATE TABLE t1;
--enable_ps_protocol
DROP TABLE t1;
CREATE TABLE t1 (a INT) ENGINE=Spider comment="port '123 456'";
# bug crash site
--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
INSERT IGNORE INTO t1 VALUES (42),(42);
drop table t1;
CREATE TABLE t1 (c INT, KEY(c)) ENGINE=Spider COMMENT='WRAPPER "mysql", SRV "srv",TABLE "t2", PK_NAME "f"';
SET GLOBAL general_log=1;
--error ER_WRONG_VALUE_COUNT_ON_ROW
INSERT INTO t1 VALUES (1, "aaa"),(2, "bbb"),(3, "ccc"),(4, "ddd");
--disable_ps_protocol
SHOW CREATE TABLE t1;
--enable_ps_protocol
DROP TABLE t1;
CREATE TABLE t1 (a INT) ENGINE=Spider comment='port "123 456"';
# bug crash site
--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
SELECT * FROM t1;
--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
INSERT IGNORE INTO t1 VALUES (42),(42);
drop table t1;
drop server srv;
--disable_query_log
--disable_result_log
--source ../../t/test_deinit.inc
--enable_result_log
--enable_query_log
--echo #
--echo # end of test mdev_32492
--echo #
...@@ -1092,6 +1092,7 @@ int spider_free_trx_alloc( ...@@ -1092,6 +1092,7 @@ int spider_free_trx_alloc(
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/* Get or create a trx associated with the given THD. */
SPIDER_TRX *spider_get_trx( SPIDER_TRX *spider_get_trx(
THD *thd, THD *thd,
bool regist_allocated_thds, bool regist_allocated_thds,
...@@ -3863,6 +3864,11 @@ SPIDER_TRX_HA *spider_check_trx_ha( ...@@ -3863,6 +3864,11 @@ SPIDER_TRX_HA *spider_check_trx_ha(
SPIDER_TRX_HA *trx_ha; SPIDER_TRX_HA *trx_ha;
SPIDER_SHARE *share = spider->share; SPIDER_SHARE *share = spider->share;
DBUG_ENTER("spider_check_trx_ha"); DBUG_ENTER("spider_check_trx_ha");
/*
Check for mismatch in trx_ha->share, link_count and
link_bitmap_size, which is an indication of a share that has been
freed. Delete the trx_ha and return NULL on mismatch.
*/
#ifdef SPIDER_HAS_HASH_VALUE_TYPE #ifdef SPIDER_HAS_HASH_VALUE_TYPE
if ((trx_ha = (SPIDER_TRX_HA *) my_hash_search_using_hash_value( if ((trx_ha = (SPIDER_TRX_HA *) my_hash_search_using_hash_value(
&trx->trx_ha_hash, share->table_name_hash_value, &trx->trx_ha_hash, share->table_name_hash_value,
...@@ -3871,6 +3877,9 @@ SPIDER_TRX_HA *spider_check_trx_ha( ...@@ -3871,6 +3877,9 @@ SPIDER_TRX_HA *spider_check_trx_ha(
if ((trx_ha = (SPIDER_TRX_HA *) my_hash_search(&trx->trx_ha_hash, if ((trx_ha = (SPIDER_TRX_HA *) my_hash_search(&trx->trx_ha_hash,
(uchar*) share->table_name, share->table_name_length))) (uchar*) share->table_name, share->table_name_length)))
#endif #endif
{
if (trx_ha->share == share && trx_ha->link_count == share->link_count &&
trx_ha->link_bitmap_size == share->link_bitmap_size)
{ {
memcpy(spider->conn_link_idx, trx_ha->conn_link_idx, memcpy(spider->conn_link_idx, trx_ha->conn_link_idx,
sizeof(uint) * share->link_count); sizeof(uint) * share->link_count);
...@@ -3878,6 +3887,12 @@ SPIDER_TRX_HA *spider_check_trx_ha( ...@@ -3878,6 +3887,12 @@ SPIDER_TRX_HA *spider_check_trx_ha(
sizeof(uint) * share->link_bitmap_size); sizeof(uint) * share->link_bitmap_size);
DBUG_RETURN(trx_ha); DBUG_RETURN(trx_ha);
} }
else
{
my_hash_delete(&trx->trx_ha_hash, (uchar*) trx_ha);
spider_free(trx, trx_ha, MYF(0));
}
}
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
......
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