Skip to content

Commit 5d06ddd

Browse files
committed
Bug #56494 Segfault in upgrade_shared_lock_to_exclusive() for
REPAIR of merge table Bug #56422 CHECK TABLE run when the table is locked reports corruption along with timeout The crash happened if a table maintenance statement (ANALYZE TABLE, REPAIR TABLE, etc.) was executed on a MERGE table and opening and locking a child table failed. This could for example happen if a child table did not exist or if a lock timeout happened while waiting for a conflicting metadata lock to disappear. Since opening and locking the MERGE table and its children failed, the tables would be closed and the metadata locks released. However, TABLE_LIST::table for the MERGE table would still be set, with its value invalid since the tables had been closed. This caused the table maintenance statement to try to continue and upgrade the metadata lock on the MERGE table. But since the lock already had been released, this caused a segfault. This patch fixes the problem by setting TABLE_LIST::table to NULL if open_and_lock_tables() fails. This prevents maintenance statements from continuing and trying to upgrade the metadata lock. The patch includes a 5.5 version of the fix for Bug #46339 crash on REPAIR TABLE merge table USE_FRM. This bug caused REPAIR TABLE ... USE_FRM to give an assert when used on merge tables. The patch also enables the CHECK TABLE statement for log tables. Before, CHECK TABLE for log tables gave ER_CANT_LOCK_LOG_TABLE, yet still counted the statement as successfully executed. With the changes to table maintenance statement error handling in this patch, CHECK TABLE would no longer be considered as successful in this case. This would have caused upgrade scripts to mistakenly think that the general and slow logs are corrupted and have to be repaired. Enabling CHECK TABLES for log tables prevents this from happening. Finally, the patch changes the error message from "Corrupt" to "Operation failed" for a number of issues not related to table corruption. For example "Lock wait timeout exceeded" and "Deadlock found trying to get lock". Test cases added to merge.test and check.test.
1 parent 1818165 commit 5d06ddd

10 files changed

+295
-63
lines changed

mysql-test/r/check.result

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,19 @@ REPAIR TABLE t1;
2323
Table Op Msg_type Msg_text
2424
test.t1 repair status OK
2525
DROP TABLE t1;
26+
#
27+
# Bug#56422 CHECK TABLE run when the table is locked reports corruption
28+
# along with timeout
29+
#
30+
DROP TABLE IF EXISTS t1;
31+
CREATE TABLE t1(a INT);
32+
LOCK TABLE t1 WRITE;
33+
# Connection con1
34+
SET lock_wait_timeout= 1;
35+
CHECK TABLE t1;
36+
Table Op Msg_type Msg_text
37+
test.t1 check Error Lock wait timeout exceeded; try restarting transaction
38+
test.t1 check status Operation failed
39+
# Connection default
40+
UNLOCK TABLES;
41+
DROP TABLE t1;

mysql-test/r/log_tables_upgrade.result

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ mysql.columns_priv OK
1717
mysql.db OK
1818
mysql.event OK
1919
mysql.func OK
20-
mysql.general_log
21-
Error : You can't use locks with log tables.
22-
status : OK
20+
mysql.general_log OK
2321
mysql.help_category OK
2422
mysql.help_keyword OK
2523
mysql.help_relation OK
@@ -31,9 +29,7 @@ mysql.proc OK
3129
mysql.procs_priv OK
3230
mysql.renamed_general_log OK
3331
mysql.servers OK
34-
mysql.slow_log
35-
Error : You can't use locks with log tables.
36-
status : OK
32+
mysql.slow_log OK
3733
mysql.tables_priv OK
3834
mysql.time_zone OK
3935
mysql.time_zone_leap_second OK

mysql-test/r/merge.result

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2358,6 +2358,48 @@ t2 WHERE b SOUNDS LIKE e AND d = 1;
23582358
id select_type table type possible_keys key key_len ref rows Extra
23592359
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
23602360
DROP TABLE t2, t1;
2361+
#
2362+
# Bug#46339 - crash on REPAIR TABLE merge table USE_FRM
2363+
#
2364+
DROP TABLE IF EXISTS m1, t1;
2365+
CREATE TABLE t1 (c1 INT) ENGINE=MYISAM;
2366+
CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1) INSERT_METHOD=LAST;
2367+
LOCK TABLE m1 READ;
2368+
REPAIR TABLE m1 USE_FRM;
2369+
Table Op Msg_type Msg_text
2370+
test.m1 repair Error Table 'm1' was locked with a READ lock and can't be updated
2371+
test.m1 repair status Operation failed
2372+
UNLOCK TABLES;
2373+
REPAIR TABLE m1 USE_FRM;
2374+
Table Op Msg_type Msg_text
2375+
test.m1 repair note The storage engine for the table doesn't support repair
2376+
DROP TABLE m1,t1;
2377+
CREATE TABLE m1 (f1 BIGINT) ENGINE=MRG_MyISAM UNION(t1);
2378+
REPAIR TABLE m1 USE_FRM;
2379+
Table Op Msg_type Msg_text
2380+
test.m1 repair Warning Can't open table
2381+
test.m1 repair error Corrupt
2382+
CREATE TABLE t1 (f1 BIGINT) ENGINE = MyISAM;
2383+
REPAIR TABLE m1 USE_FRM;
2384+
Table Op Msg_type Msg_text
2385+
test.m1 repair note The storage engine for the table doesn't support repair
2386+
REPAIR TABLE m1;
2387+
Table Op Msg_type Msg_text
2388+
test.m1 repair note The storage engine for the table doesn't support repair
2389+
DROP TABLE m1, t1;
2390+
CREATE TEMPORARY TABLE m1 (f1 BIGINT) ENGINE=MRG_MyISAM UNION(t1);
2391+
REPAIR TABLE m1 USE_FRM;
2392+
Table Op Msg_type Msg_text
2393+
test.m1 repair Error Table 'test.m1' doesn't exist
2394+
test.m1 repair error Corrupt
2395+
CREATE TEMPORARY TABLE t1 (f1 BIGINT) ENGINE=MyISAM;
2396+
REPAIR TABLE m1 USE_FRM;
2397+
Table Op Msg_type Msg_text
2398+
m1 repair error Cannot repair temporary table from .frm file
2399+
REPAIR TABLE m1;
2400+
Table Op Msg_type Msg_text
2401+
test.m1 repair note The storage engine for the table doesn't support repair
2402+
DROP TABLE m1, t1;
23612403
End of 5.1 tests
23622404
#
23632405
# An additional test case for Bug#27430 Crash in subquery code
@@ -2677,7 +2719,7 @@ OPTIMIZE TABLE t1;
26772719
Table Op Msg_type Msg_text
26782720
test.t1 optimize Error Table 'test.t_not_exists' doesn't exist
26792721
test.t1 optimize Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
2680-
test.t1 optimize note The storage engine for the table doesn't support optimize
2722+
test.t1 optimize error Corrupt
26812723
DROP TABLE t1;
26822724
#
26832725
# Bug#36171 - CREATE TEMPORARY TABLE and MERGE engine
@@ -3575,4 +3617,48 @@ ERROR HY000: The definition of table 'v1' prevents operation DELETE on table 'm1
35753617
drop view v1;
35763618
drop temporary table tmp;
35773619
drop table t1, t2, t3, m1, m2;
3620+
#
3621+
# Bug#56494 Segfault in upgrade_shared_lock_to_exclusive() for
3622+
# REPAIR of merge table
3623+
#
3624+
DROP TABLE IF EXISTS t1, t2, t_not_exists;
3625+
CREATE TABLE t1(a INT);
3626+
ALTER TABLE t1 engine= MERGE UNION (t_not_exists);
3627+
ANALYZE TABLE t1;
3628+
Table Op Msg_type Msg_text
3629+
test.t1 analyze Error Table 'test.t_not_exists' doesn't exist
3630+
test.t1 analyze Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
3631+
test.t1 analyze error Corrupt
3632+
CHECK TABLE t1;
3633+
Table Op Msg_type Msg_text
3634+
test.t1 check Error Table 'test.t_not_exists' doesn't exist
3635+
test.t1 check Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
3636+
test.t1 check error Corrupt
3637+
CHECKSUM TABLE t1;
3638+
Table Checksum
3639+
test.t1 NULL
3640+
Warnings:
3641+
Error 1146 Table 'test.t_not_exists' doesn't exist
3642+
Error 1168 Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
3643+
OPTIMIZE TABLE t1;
3644+
Table Op Msg_type Msg_text
3645+
test.t1 optimize Error Table 'test.t_not_exists' doesn't exist
3646+
test.t1 optimize Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
3647+
test.t1 optimize error Corrupt
3648+
REPAIR TABLE t1;
3649+
Table Op Msg_type Msg_text
3650+
test.t1 repair Error Table 'test.t_not_exists' doesn't exist
3651+
test.t1 repair Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
3652+
test.t1 repair error Corrupt
3653+
REPAIR TABLE t1 USE_FRM;
3654+
Table Op Msg_type Msg_text
3655+
test.t1 repair Warning Can't open table
3656+
test.t1 repair error Corrupt
3657+
DROP TABLE t1;
3658+
CREATE TABLE t1(a INT);
3659+
CREATE TABLE t2(a INT) engine= MERGE UNION (t1);
3660+
REPAIR TABLE t2 USE_FRM;
3661+
Table Op Msg_type Msg_text
3662+
test.t2 repair note The storage engine for the table doesn't support repair
3663+
DROP TABLE t1, t2;
35783664
End of 6.0 tests

mysql-test/r/myisampack.result

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,12 @@ insert into t1 select * from t1;
4646
flush tables;
4747
optimize table t1;
4848
Table Op Msg_type Msg_text
49-
test.t1 optimize error Table 'test.t1' is read only
50-
Warnings:
51-
Error 1036 Table 't1' is read only
49+
test.t1 optimize Error Table 't1' is read only
50+
test.t1 optimize status Operation failed
5251
repair table t1;
5352
Table Op Msg_type Msg_text
54-
test.t1 repair error Table 'test.t1' is read only
55-
Warnings:
56-
Error 1036 Table 't1' is read only
53+
test.t1 repair Error Table 't1' is read only
54+
test.t1 repair status Operation failed
5755
drop table t1;
5856
#
5957
# BUG#41541 - Valgrind warnings on packed MyISAM table

mysql-test/r/mysql_upgrade.result

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ mysql.columns_priv OK
55
mysql.db OK
66
mysql.event OK
77
mysql.func OK
8-
mysql.general_log
9-
Error : You can't use locks with log tables.
10-
status : OK
8+
mysql.general_log OK
119
mysql.help_category OK
1210
mysql.help_keyword OK
1311
mysql.help_relation OK
@@ -18,9 +16,7 @@ mysql.plugin OK
1816
mysql.proc OK
1917
mysql.procs_priv OK
2018
mysql.servers OK
21-
mysql.slow_log
22-
Error : You can't use locks with log tables.
23-
status : OK
19+
mysql.slow_log OK
2420
mysql.tables_priv OK
2521
mysql.time_zone OK
2622
mysql.time_zone_leap_second OK
@@ -37,9 +33,7 @@ mysql.columns_priv OK
3733
mysql.db OK
3834
mysql.event OK
3935
mysql.func OK
40-
mysql.general_log
41-
Error : You can't use locks with log tables.
42-
status : OK
36+
mysql.general_log OK
4337
mysql.help_category OK
4438
mysql.help_keyword OK
4539
mysql.help_relation OK
@@ -50,9 +44,7 @@ mysql.plugin OK
5044
mysql.proc OK
5145
mysql.procs_priv OK
5246
mysql.servers OK
53-
mysql.slow_log
54-
Error : You can't use locks with log tables.
55-
status : OK
47+
mysql.slow_log OK
5648
mysql.tables_priv OK
5749
mysql.time_zone OK
5850
mysql.time_zone_leap_second OK
@@ -69,9 +61,7 @@ mysql.columns_priv OK
6961
mysql.db OK
7062
mysql.event OK
7163
mysql.func OK
72-
mysql.general_log
73-
Error : You can't use locks with log tables.
74-
status : OK
64+
mysql.general_log OK
7565
mysql.help_category OK
7666
mysql.help_keyword OK
7767
mysql.help_relation OK
@@ -82,9 +72,7 @@ mysql.plugin OK
8272
mysql.proc OK
8373
mysql.procs_priv OK
8474
mysql.servers OK
85-
mysql.slow_log
86-
Error : You can't use locks with log tables.
87-
status : OK
75+
mysql.slow_log OK
8876
mysql.tables_priv OK
8977
mysql.time_zone OK
9078
mysql.time_zone_leap_second OK
@@ -103,9 +91,7 @@ mysql.columns_priv OK
10391
mysql.db OK
10492
mysql.event OK
10593
mysql.func OK
106-
mysql.general_log
107-
Error : You can't use locks with log tables.
108-
status : OK
94+
mysql.general_log OK
10995
mysql.help_category OK
11096
mysql.help_keyword OK
11197
mysql.help_relation OK
@@ -116,9 +102,7 @@ mysql.plugin OK
116102
mysql.proc OK
117103
mysql.procs_priv OK
118104
mysql.servers OK
119-
mysql.slow_log
120-
Error : You can't use locks with log tables.
121-
status : OK
105+
mysql.slow_log OK
122106
mysql.tables_priv OK
123107
mysql.time_zone OK
124108
mysql.time_zone_leap_second OK
@@ -141,9 +125,7 @@ mysql.columns_priv OK
141125
mysql.db OK
142126
mysql.event OK
143127
mysql.func OK
144-
mysql.general_log
145-
Error : You can't use locks with log tables.
146-
status : OK
128+
mysql.general_log OK
147129
mysql.help_category OK
148130
mysql.help_keyword OK
149131
mysql.help_relation OK
@@ -154,9 +136,7 @@ mysql.plugin OK
154136
mysql.proc OK
155137
mysql.procs_priv OK
156138
mysql.servers OK
157-
mysql.slow_log
158-
Error : You can't use locks with log tables.
159-
status : OK
139+
mysql.slow_log OK
160140
mysql.tables_priv OK
161141
mysql.time_zone OK
162142
mysql.time_zone_leap_second OK
@@ -182,9 +162,7 @@ mysql.columns_priv OK
182162
mysql.db OK
183163
mysql.event OK
184164
mysql.func OK
185-
mysql.general_log
186-
Error : You can't use locks with log tables.
187-
status : OK
165+
mysql.general_log OK
188166
mysql.help_category OK
189167
mysql.help_keyword OK
190168
mysql.help_relation OK
@@ -195,9 +173,7 @@ mysql.plugin OK
195173
mysql.proc OK
196174
mysql.procs_priv OK
197175
mysql.servers OK
198-
mysql.slow_log
199-
Error : You can't use locks with log tables.
200-
status : OK
176+
mysql.slow_log OK
201177
mysql.tables_priv OK
202178
mysql.time_zone OK
203179
mysql.time_zone_leap_second OK

mysql-test/r/mysql_upgrade_ssl.result

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ mysql.columns_priv OK
77
mysql.db OK
88
mysql.event OK
99
mysql.func OK
10-
mysql.general_log
11-
Error : You can't use locks with log tables.
12-
status : OK
10+
mysql.general_log OK
1311
mysql.help_category OK
1412
mysql.help_keyword OK
1513
mysql.help_relation OK
@@ -20,9 +18,7 @@ mysql.plugin OK
2018
mysql.proc OK
2119
mysql.procs_priv OK
2220
mysql.servers OK
23-
mysql.slow_log
24-
Error : You can't use locks with log tables.
25-
status : OK
21+
mysql.slow_log OK
2622
mysql.tables_priv OK
2723
mysql.time_zone OK
2824
mysql.time_zone_leap_second OK

mysql-test/t/check.test

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,29 @@ REPAIR TABLE t1;
5353
DROP TABLE t1;
5454

5555

56+
--echo #
57+
--echo # Bug#56422 CHECK TABLE run when the table is locked reports corruption
58+
--echo # along with timeout
59+
--echo #
60+
61+
--disable_warnings
62+
DROP TABLE IF EXISTS t1;
63+
--enable_warnings
64+
65+
CREATE TABLE t1(a INT);
66+
LOCK TABLE t1 WRITE;
67+
68+
--echo # Connection con1
69+
connect(con1, localhost, root);
70+
SET lock_wait_timeout= 1;
71+
CHECK TABLE t1;
72+
73+
--echo # Connection default
74+
connection default;
75+
UNLOCK TABLES;
76+
DROP TABLE t1;
77+
disconnect con1;
78+
79+
5680
# Wait till we reached the initial number of concurrent sessions
5781
--source include/wait_until_count_sessions.inc

0 commit comments

Comments
 (0)