Skip to content

Commit 6abafdb

Browse files
MDEV-29676 Add query to set lock wait timeout when getting sts crd
Set the lock wait timeout to 1 beforehand, and reset it afterwards, to avoid lock conflict caused by opening the same table twice in case of self-reference.
1 parent 779307d commit 6abafdb

File tree

9 files changed

+188
-3
lines changed

9 files changed

+188
-3
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
wait_timeout : MDEV-26045
2+
mdev_29676 : MDEV-31138
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#
2+
# MDEV-29676 Dual thread hang in 'closing tables' and 'Waiting for table metadata lock' on Spider CREATE OR REPLACE TABLE
3+
#
4+
for master_1
5+
for child2
6+
for child3
7+
CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
8+
9+
# length-0 self-reference
10+
11+
CREATE TABLE t (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t"';
12+
CREATE OR REPLACE TABLE t (c INT);
13+
Warnings:
14+
Error 1205 Lock wait timeout exceeded; try restarting transaction
15+
Error 12722 Table test.t open lock wait timeout. Please check for self-reference.
16+
SHOW CREATE TABLE t;
17+
Table Create Table
18+
t CREATE TABLE `t` (
19+
`c` int(11) DEFAULT NULL
20+
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
21+
DROP TABLE t;
22+
23+
# length-2 self-reference
24+
25+
CREATE TABLE t2 (c int);
26+
CREATE TABLE t1 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"';
27+
CREATE TABLE t0 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"';
28+
ALTER TABLE t2 ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t0"';
29+
CREATE OR REPLACE TABLE t0 (c int);
30+
Warnings:
31+
Error 1205 Lock wait timeout exceeded; try restarting transaction
32+
Error 12722 Table test.t1 open lock wait timeout. Please check for self-reference.
33+
SHOW CREATE TABLE t0;
34+
Table Create Table
35+
t0 CREATE TABLE `t0` (
36+
`c` int(11) DEFAULT NULL
37+
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
38+
CREATE OR REPLACE TABLE t1 (c int);
39+
SHOW CREATE TABLE t1;
40+
Table Create Table
41+
t1 CREATE TABLE `t1` (
42+
`c` int(11) DEFAULT NULL
43+
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
44+
drop TABLE t0, t1, t2;
45+
for master_1
46+
for child2
47+
for child3

storage/spider/mysql-test/spider/bugfix/r/slave_trx_isolation.result

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argum
5050
argument
5151
set session time_zone = '+00:00';set @`spider_lc_./auto_test_remote/tbl_a` = '-xxxxxxxxxxxx-xxxxx-./auto_test_local/tbl_a-'
5252
SET NAMES utf8mb3
53+
set @old_lock_wait_timeout=@@session.lock_wait_timeout;set session lock_wait_timeout=1
54+
set session lock_wait_timeout=@old_lock_wait_timeout
55+
set @old_lock_wait_timeout=@@session.lock_wait_timeout;set session lock_wait_timeout=1
56+
set session lock_wait_timeout=@old_lock_wait_timeout
5357
set session transaction isolation level read committed;set session autocommit = 1;set session wait_timeout = 604800;set session sql_mode = 'strict_trans_tables,error_for_division_by_zero,no_auto_create_user,no_engine_substitution';start transaction
5458
SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%set %'
5559
SELECT pkey FROM tbl_a ORDER BY pkey;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--echo #
2+
--echo # MDEV-29676 Dual thread hang in 'closing tables' and 'Waiting for table metadata lock' on Spider CREATE OR REPLACE TABLE
3+
--echo #
4+
5+
--disable_query_log
6+
--disable_result_log
7+
--source ../../t/test_init.inc
8+
--enable_result_log
9+
--enable_query_log
10+
11+
--replace_regex /SOCKET ".*"/SOCKET "$MASTER_1_MYSOCK"/
12+
eval CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
13+
14+
--echo
15+
--echo # length-0 self-reference
16+
--echo
17+
CREATE TABLE t (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t"';
18+
CREATE OR REPLACE TABLE t (c INT);
19+
SHOW CREATE TABLE t;
20+
DROP TABLE t;
21+
22+
--echo
23+
--echo # length-2 self-reference
24+
--echo
25+
CREATE TABLE t2 (c int);
26+
CREATE TABLE t1 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"';
27+
CREATE TABLE t0 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"';
28+
ALTER TABLE t2 ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t0"';
29+
# warnings
30+
CREATE OR REPLACE TABLE t0 (c int);
31+
SHOW CREATE TABLE t0;
32+
# no warnings
33+
CREATE OR REPLACE TABLE t1 (c int);
34+
SHOW CREATE TABLE t1;
35+
drop TABLE t0, t1, t2;
36+
37+
--disable_query_log
38+
--disable_result_log
39+
--source ../../t/test_deinit.inc
40+
--enable_result_log
41+
--enable_query_log

storage/spider/mysql-test/spider/r/slave_trx_isolation.result

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argum
5353
argument
5454
set session time_zone = '+00:00';set @`spider_lc_./auto_test_remote/tbl_a` = '-xxxxxxxxxxxx-xxxxx-./auto_test_local/tbl_a-'
5555
SET NAMES utf8mb3
56+
set @old_lock_wait_timeout=@@session.lock_wait_timeout;set session lock_wait_timeout=1
57+
set session lock_wait_timeout=@old_lock_wait_timeout
58+
set @old_lock_wait_timeout=@@session.lock_wait_timeout;set session lock_wait_timeout=1
59+
set session lock_wait_timeout=@old_lock_wait_timeout
5660
set session transaction isolation level read committed;set session autocommit = 1;set session wait_timeout = 604800;set session sql_mode = 'strict_trans_tables,error_for_division_by_zero,no_auto_create_user,no_engine_substitution';start transaction
5761
SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%set %'
5862
SELECT pkey FROM tbl_a ORDER BY pkey;

storage/spider/spd_db_mysql.cc

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13443,6 +13443,56 @@ int spider_mbase_handler::sts_mode_exchange(
1344313443
DBUG_RETURN(sts_mode);
1344413444
}
1344513445

13446+
/** Set the session lock wait time out */
13447+
int spider_db_mbase::set_lock_wait_timeout(uint timeout)
13448+
{
13449+
String query(0);
13450+
int error_num;
13451+
DBUG_ENTER("spider_db_set_lock_wait_timeout");
13452+
query.append(STRING_WITH_LEN(
13453+
"set @old_lock_wait_timeout=@@session.lock_wait_timeout;"
13454+
"set session lock_wait_timeout="));
13455+
query.append_ulonglong(timeout);
13456+
query.append(STRING_WITH_LEN(";"));
13457+
if ((error_num = exec_query(query.c_ptr(), query.length(), -1)))
13458+
DBUG_RETURN(error_num);
13459+
spider_db_result *result;
13460+
do {
13461+
st_spider_db_request_key request_key= {1, 1, NULL, 1, NULL};
13462+
if ((result = conn->db_conn->store_result(NULL, &request_key,
13463+
&error_num)))
13464+
{
13465+
result->free_result();
13466+
delete result;
13467+
} else if ((error_num = conn->db_conn->get_errno()))
13468+
break;
13469+
} while (!(error_num = conn->db_conn->next_result()));
13470+
DBUG_RETURN(0);
13471+
}
13472+
13473+
/** Reset the session lock wait time out */
13474+
int spider_db_mbase::reset_lock_wait_timeout()
13475+
{
13476+
const LEX_CSTRING query = {STRING_WITH_LEN(
13477+
"set session lock_wait_timeout=@old_lock_wait_timeout;")};
13478+
int error_num;
13479+
DBUG_ENTER("spider_db_set_lock_wait_timeout");
13480+
if ((error_num = exec_query(query.str, query.length, -1)))
13481+
DBUG_RETURN(error_num);
13482+
spider_db_result *result;
13483+
do {
13484+
st_spider_db_request_key request_key= {1, 1, NULL, 1, NULL};
13485+
if ((result = conn->db_conn->store_result(NULL, &request_key,
13486+
&error_num)))
13487+
{
13488+
result->free_result();
13489+
delete result;
13490+
} else if ((error_num = conn->db_conn->get_errno()))
13491+
break;
13492+
} while (!(error_num= conn->db_conn->next_result()));
13493+
DBUG_RETURN(0);
13494+
}
13495+
1344613496
/** FIXME: refactor more functions to use spider_setup_for_query() and
1344713497
spider_teardown_after_query(). */
1344813498
void spider_setup_for_query(ha_spider *spider, SPIDER_CONN *conn, int link_idx)
@@ -13494,6 +13544,8 @@ int spider_mbase_handler::show_table_status(
1349413544
spider_conn_set_timeout_from_share(
1349513545
conn, link_idx, spider->wide_handler->trx->thd, share);
1349613546
if ((error_num = spider_db_set_names(spider, conn, link_idx)) ||
13547+
(error_num =
13548+
((spider_db_mbase *) conn->db_conn)->set_lock_wait_timeout(1)) ||
1349713549
/* Executes the `show table status` query */
1349813550
(spider_db_query(
1349913551
conn,
@@ -13514,6 +13566,9 @@ int spider_mbase_handler::show_table_status(
1351413566
spider_conn_set_timeout_from_share(conn, link_idx,
1351513567
spider->wide_handler->trx->thd,
1351613568
share);
13569+
if ((error_num =
13570+
((spider_db_mbase *) conn->db_conn)->set_lock_wait_timeout(1)))
13571+
DBUG_RETURN(spider_teardown_after_query(conn, error_num, true));
1351713572
if (spider_db_query(
1351813573
conn,
1351913574
mysql_share->show_table_status[pos].ptr(),
@@ -13590,8 +13645,21 @@ int spider_mbase_handler::show_table_status(
1359013645
}
1359113646
if ((error_num = ((spider_db_mbase *) conn->db_conn)->fetch_and_print_warnings(NULL)))
1359213647
{
13648+
((spider_db_mbase *) conn->db_conn)->reset_lock_wait_timeout();
13649+
if (error_num == ER_LOCK_WAIT_TIMEOUT)
13650+
{
13651+
error_num = ER_SPIDER_TABLE_OPEN_LOCK_WAIT_TIMEOUT_NUM;
13652+
my_printf_error(
13653+
ER_SPIDER_TABLE_OPEN_LOCK_WAIT_TIMEOUT_NUM,
13654+
ER_SPIDER_TABLE_OPEN_LOCK_WAIT_TIMEOUT_STR, MYF(0),
13655+
mysql_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(),
13656+
mysql_share->table_names_str[spider->conn_link_idx[link_idx]].ptr());
13657+
}
1359313658
DBUG_RETURN(error_num);
1359413659
}
13660+
if ((error_num =
13661+
((spider_db_mbase *) conn->db_conn)->reset_lock_wait_timeout()))
13662+
DBUG_RETURN(error_num);
1359513663
if (share->static_records_for_status != -1)
1359613664
share->stat.records = (ha_rows) share->static_records_for_status;
1359713665
if (share->static_mean_rec_length != -1)
@@ -13632,6 +13700,8 @@ int spider_mbase_handler::show_index(
1363213700
spider_conn_set_timeout_from_share(conn, link_idx,
1363313701
spider->wide_handler->trx->thd, share);
1363413702
if ((error_num = spider_db_set_names(spider, conn, link_idx)) ||
13703+
(error_num =
13704+
((spider_db_mbase *) conn->db_conn)->set_lock_wait_timeout(1)) ||
1363513705
(spider_db_query(
1363613706
conn,
1363713707
mysql_share->show_index[pos].ptr(),
@@ -13651,6 +13721,9 @@ int spider_mbase_handler::show_index(
1365113721
spider_conn_set_timeout_from_share(conn, link_idx,
1365213722
spider->wide_handler->trx->thd,
1365313723
share);
13724+
if ((error_num =
13725+
((spider_db_mbase *) conn->db_conn)->set_lock_wait_timeout(1)))
13726+
DBUG_RETURN(spider_teardown_after_query(conn, error_num, true));
1365413727
if (spider_db_query(
1365513728
conn,
1365613729
mysql_share->show_index[pos].ptr(),
@@ -13711,6 +13784,10 @@ int spider_mbase_handler::show_index(
1371113784
default:
1371213785
break;
1371313786
}
13787+
if (!error_num)
13788+
error_num = ((spider_db_mbase *) conn->db_conn)->reset_lock_wait_timeout();
13789+
else
13790+
((spider_db_mbase *) conn->db_conn)->reset_lock_wait_timeout();
1371413791
DBUG_RETURN(error_num);
1371513792
}
1371613793

storage/spider/spd_db_mysql.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,12 @@ class spider_db_mbase: public spider_db_conn
513513
int wait_timeout,
514514
int *need_mon
515515
);
516+
517+
/** Set the global lock wait time out */
518+
int set_lock_wait_timeout(uint timeout);
519+
/** Reset the global lock wait time out */
520+
int reset_lock_wait_timeout();
521+
516522
bool set_sql_mode_in_bulk_sql();
517523
int set_sql_mode(
518524
sql_mode_t sql_mode,

storage/spider/spd_err.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@
134134
#define ER_SPIDER_SAME_SERVER_LINK_STR2 "Host:%s and Port:%ld aim self server. Please change spider_same_server_link parameter if this link is required."
135135
#define ER_SPIDER_CANT_NUM 12721
136136
#define ER_SPIDER_CANT_STR1 "Can't %s%d"
137+
#define ER_SPIDER_TABLE_OPEN_LOCK_WAIT_TIMEOUT_NUM 12722
138+
#define ER_SPIDER_TABLE_OPEN_LOCK_WAIT_TIMEOUT_STR "Table %s.%s open lock wait timeout. Please check for self-reference."
137139
#define ER_SPIDER_COND_SKIP_NUM 12801
138140

139141
#define ER_SPIDER_UNKNOWN_NUM 12500

storage/spider/spd_table.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5002,8 +5002,10 @@ bool spider_share_get_sts_crd(
50025002
(*error_num = spider_get_sts(share, spider->search_link_idx, tmp_time,
50035003
spider, sts_interval, sts_mode, sts_sync,
50045004
1, HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_AUTO))
5005-
) {
5006-
if (*error_num != ER_SPIDER_SYS_TABLE_VERSION_NUM)
5005+
)
5006+
{
5007+
if (*error_num != ER_SPIDER_SYS_TABLE_VERSION_NUM &&
5008+
*error_num != ER_SPIDER_TABLE_OPEN_LOCK_WAIT_TIMEOUT_NUM)
50075009
thd->clear_error();
50085010
else
50095011
{
@@ -5020,7 +5022,8 @@ bool spider_share_get_sts_crd(
50205022
crd_sync,
50215023
1)))
50225024
{
5023-
if (*error_num != ER_SPIDER_SYS_TABLE_VERSION_NUM)
5025+
if (*error_num != ER_SPIDER_SYS_TABLE_VERSION_NUM &&
5026+
*error_num != ER_SPIDER_TABLE_OPEN_LOCK_WAIT_TIMEOUT_NUM)
50245027
thd->clear_error();
50255028
else
50265029
{

0 commit comments

Comments
 (0)