Skip to content

Commit 1a5028f

Browse files
committed
Fix the WITH_ASAN clang build of dynamic plugins
1 parent 4c0f43f commit 1a5028f

File tree

3 files changed

+378
-1
lines changed

3 files changed

+378
-1
lines changed

cmake/plugin.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ MACRO(MYSQL_ADD_PLUGIN)
209209
ELSEIF(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
210210
TARGET_LINK_LIBRARIES (${target} mysqld)
211211
ENDIF()
212-
ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
212+
ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT WITH_ASAN)
213213
TARGET_LINK_LIBRARIES (${target} "-Wl,--no-undefined")
214214
ENDIF()
215215

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#
2+
# Bug#20015132 ALTER TABLE FAILS TO CHECK IF TABLE IS CORRUPTED
3+
#
4+
CREATE TABLE t1(c1 INT PRIMARY KEY, c2 CHAR(1), c3 INT UNSIGNED) ENGINE=InnoDB;
5+
SET @saved_debug_dbug = @@SESSION.debug_dbug;
6+
SET DEBUG_DBUG='+d,ib_create_table_fail_too_many_trx';
7+
ALTER TABLE t1 ADD INDEX (c2), ADD INDEX (c3);
8+
ERROR HY000: Too many active concurrent transactions
9+
SET DEBUG_DBUG=@saved_debug_dbug;
10+
ALTER TABLE t1 ADD INDEX (c2), ADD INDEX (c3);
11+
SET DEBUG_DBUG='+d,dict_set_index_corrupted';
12+
CHECK TABLE t1;
13+
Table Op Msg_type Msg_text
14+
test.t1 check Warning InnoDB: Index c2 is marked as corrupted
15+
test.t1 check Warning InnoDB: Index c3 is marked as corrupted
16+
test.t1 check error Corrupt
17+
CHECK TABLE t1;
18+
Table Op Msg_type Msg_text
19+
test.t1 check Warning InnoDB: Index c2 is marked as corrupted
20+
test.t1 check Warning InnoDB: Index c3 is marked as corrupted
21+
test.t1 check error Corrupt
22+
ALTER TABLE t1 DROP INDEX c2;
23+
CHECK TABLE t1;
24+
Table Op Msg_type Msg_text
25+
test.t1 check Warning InnoDB: Index c3 is marked as corrupted
26+
test.t1 check error Corrupt
27+
ALTER TABLE t1 ADD INDEX (c2,c3);
28+
ERROR HY000: Index c3 is corrupted
29+
ALTER TABLE t1 CHANGE c3 c3 INT NOT NULL;
30+
CHECK TABLE t1;
31+
Table Op Msg_type Msg_text
32+
test.t1 check status OK
33+
ALTER TABLE t1 ADD INDEX (c2,c3);
34+
DROP TABLE t1;
35+
#
36+
# Bug #14669848 CRASH DURING ALTER MAKES ORIGINAL TABLE INACCESSIBLE
37+
#
38+
# -- Scenario 1:
39+
# Crash the server in ha_innobase::commit_inplace_alter_table()
40+
# just after committing the dictionary changes.
41+
CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=innodb;
42+
INSERT INTO t1 VALUES (1,2),(3,4);
43+
SET DEBUG_DBUG='+d,innodb_alter_commit_crash_after_commit';
44+
ALTER TABLE t1 ADD PRIMARY KEY (f2, f1);
45+
ERROR HY000: Lost connection to MySQL server during query
46+
# Restart mysqld after the crash and reconnect.
47+
# Manual *.frm recovery begin.
48+
# Manual recovery end
49+
FLUSH TABLES;
50+
# Drop the orphaned original table.
51+
# Files in datadir after manual recovery.
52+
t1.frm
53+
t1.ibd
54+
SHOW TABLES;
55+
Tables_in_test
56+
t1
57+
SHOW CREATE TABLE t1;
58+
Table Create Table
59+
t1 CREATE TABLE `t1` (
60+
`f1` int(11) NOT NULL,
61+
`f2` int(11) NOT NULL,
62+
PRIMARY KEY (`f2`,`f1`)
63+
) ENGINE=InnoDB DEFAULT CHARSET=latin1
64+
INSERT INTO t1 VALUES (5,6),(7,8);
65+
SELECT * FROM t1;
66+
f1 f2
67+
1 2
68+
3 4
69+
5 6
70+
7 8
71+
DROP TABLE t1;
72+
CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=InnoDB;
73+
ALTER TABLE t1 ADD PRIMARY KEY (f2, f1);
74+
DROP TABLE t1;
75+
# -- Scenario 2:
76+
# Crash the server in ha_innobase::commit_inplace_alter_table()
77+
# just before committing the dictionary changes, but after
78+
# writing the MLOG_FILE_RENAME records. As the mini-transaction
79+
# is not committed, the renames will not be replayed.
80+
CREATE TABLE t2 (f1 int not null, f2 int not null) ENGINE=InnoDB;
81+
INSERT INTO t2 VALUES (1,2),(3,4);
82+
SET DEBUG_DBUG='+d,innodb_alter_commit_crash_before_commit';
83+
ALTER TABLE t2 ADD PRIMARY KEY (f2, f1);
84+
ERROR HY000: Lost connection to MySQL server during query
85+
# Startup the server after the crash
86+
# Read and remember the temporary table name
87+
# Manual *.frm recovery begin. The dictionary was not updated
88+
# and the files were not renamed. The rebuilt table
89+
# was left behind on purpose, to faciliate data recovery.
90+
# Manual recovery end
91+
# Drop the orphaned rebuilt table.
92+
SHOW TABLES;
93+
Tables_in_test
94+
t2
95+
INSERT INTO t2 VALUES (5,6),(7,8);
96+
SELECT * from t2;
97+
f1 f2
98+
1 2
99+
3 4
100+
5 6
101+
7 8
102+
SHOW CREATE TABLE t2;
103+
Table Create Table
104+
t2 CREATE TABLE `t2` (
105+
`f1` int(11) NOT NULL,
106+
`f2` int(11) NOT NULL
107+
) ENGINE=InnoDB DEFAULT CHARSET=latin1
108+
DROP TABLE t2;
109+
CREATE TABLE t2 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=InnoDB;
110+
ALTER TABLE t2 ADD PRIMARY KEY (f2, f1);
111+
DROP TABLE t2;
112+
# -------------------------
113+
# End of Testing Scenario 2
114+
# -------------------------
115+
#
116+
# Bug#19330255 WL#7142 - CRASH DURING ALTER TABLE LEADS TO
117+
# DATA DICTIONARY INCONSISTENCY
118+
#
119+
CREATE TABLE t1(a int PRIMARY KEY, b varchar(255), c int NOT NULL)
120+
ENGINE=InnoDB;
121+
INSERT INTO t1 SET a=1,c=2;
122+
SET DEBUG_DBUG='+d,innodb_alter_commit_crash_after_commit';
123+
ALTER TABLE t1 ADD INDEX (b), CHANGE c d int, ALGORITHM=INPLACE;
124+
ERROR HY000: Lost connection to MySQL server during query
125+
# Restart mysqld after the crash and reconnect.
126+
# Manual *.frm recovery begin.
127+
# Manual recovery end
128+
FLUSH TABLES;
129+
# Drop the orphaned original table.
130+
# Files in datadir after manual recovery.
131+
t1.frm
132+
t1.ibd
133+
SHOW TABLES;
134+
Tables_in_test
135+
t1
136+
SHOW CREATE TABLE t1;
137+
Table Create Table
138+
t1 CREATE TABLE `t1` (
139+
`a` int(11) NOT NULL,
140+
`b` varchar(255) DEFAULT NULL,
141+
`d` int(11) DEFAULT NULL,
142+
PRIMARY KEY (`a`),
143+
KEY `b` (`b`)
144+
) ENGINE=InnoDB DEFAULT CHARSET=latin1
145+
UPDATE t1 SET d=NULL;
146+
SELECT * FROM t1;
147+
a b d
148+
1 NULL NULL
149+
DROP TABLE t1;
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
# Crash-safe InnoDB ALTER operations
2+
3+
--source include/not_valgrind.inc
4+
--source include/not_embedded.inc
5+
--source include/have_innodb.inc
6+
--source include/have_debug.inc
7+
--source include/not_crashrep.inc
8+
9+
--disable_query_log
10+
call mtr.add_suppression('InnoDB: cannot find a free slot for an undo log');
11+
call mtr.add_suppression('InnoDB: row_merge_rename_index_to_add failed with error 47');
12+
call mtr.add_suppression('InnoDB: Flagged corruption of `c[23]`');
13+
call mtr.add_suppression('InnoDB: Index `c[23]` .*is corrupted');
14+
--enable_query_log
15+
16+
--echo #
17+
--echo # Bug#20015132 ALTER TABLE FAILS TO CHECK IF TABLE IS CORRUPTED
18+
--echo #
19+
20+
CREATE TABLE t1(c1 INT PRIMARY KEY, c2 CHAR(1), c3 INT UNSIGNED) ENGINE=InnoDB;
21+
SET @saved_debug_dbug = @@SESSION.debug_dbug;
22+
SET DEBUG_DBUG='+d,ib_create_table_fail_too_many_trx';
23+
--error ER_TOO_MANY_CONCURRENT_TRXS
24+
ALTER TABLE t1 ADD INDEX (c2), ADD INDEX (c3);
25+
26+
SET DEBUG_DBUG=@saved_debug_dbug;
27+
ALTER TABLE t1 ADD INDEX (c2), ADD INDEX (c3);
28+
# Flag the secondary indexes corrupted.
29+
SET DEBUG_DBUG='+d,dict_set_index_corrupted';
30+
CHECK TABLE t1;
31+
32+
# Ensure that the corruption is permanent.
33+
--source include/restart_mysqld.inc
34+
CHECK TABLE t1;
35+
ALTER TABLE t1 DROP INDEX c2;
36+
CHECK TABLE t1;
37+
# We refuse an ALTER TABLE that would modify the InnoDB data dictionary
38+
# while leaving some of the table corrupted.
39+
--error ER_INDEX_CORRUPT
40+
ALTER TABLE t1 ADD INDEX (c2,c3);
41+
# This will rebuild the table, uncorrupting all secondary indexes.
42+
ALTER TABLE t1 CHANGE c3 c3 INT NOT NULL;
43+
CHECK TABLE t1;
44+
ALTER TABLE t1 ADD INDEX (c2,c3);
45+
DROP TABLE t1;
46+
47+
let $MYSQLD_DATADIR= `select @@datadir`;
48+
let datadir= `select @@datadir`;
49+
50+
# These are from include/shutdown_mysqld.inc and allow to call start_mysqld.inc
51+
--let $_server_id= `SELECT @@server_id`
52+
--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect
53+
54+
--echo #
55+
--echo # Bug #14669848 CRASH DURING ALTER MAKES ORIGINAL TABLE INACCESSIBLE
56+
--echo #
57+
--echo # -- Scenario 1:
58+
--echo # Crash the server in ha_innobase::commit_inplace_alter_table()
59+
--echo # just after committing the dictionary changes.
60+
61+
CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=innodb;
62+
INSERT INTO t1 VALUES (1,2),(3,4);
63+
SET DEBUG_DBUG='+d,innodb_alter_commit_crash_after_commit';
64+
65+
let $orig_table_id = `SELECT table_id
66+
FROM information_schema.innodb_sys_tables
67+
WHERE name = 'test/t1'`;
68+
69+
# Write file to make mysql-test-run.pl expect crash
70+
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
71+
72+
--error 2013
73+
ALTER TABLE t1 ADD PRIMARY KEY (f2, f1);
74+
75+
--echo # Restart mysqld after the crash and reconnect.
76+
--source include/start_mysqld.inc
77+
78+
let $temp_table_name = `SELECT SUBSTR(name, 6)
79+
FROM information_schema.innodb_sys_tables
80+
WHERE table_id = $orig_table_id`;
81+
82+
--echo # Manual *.frm recovery begin.
83+
84+
--move_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/$temp_table_name.frm
85+
86+
perl;
87+
my @frm_file = glob "$ENV{'datadir'}/test/#sql-*.frm";
88+
my $t1_frm = "$ENV{'datadir'}/test/t1.frm";
89+
rename($frm_file[0], $t1_frm);
90+
EOF
91+
92+
--echo # Manual recovery end
93+
94+
FLUSH TABLES;
95+
96+
--echo # Drop the orphaned original table.
97+
--disable_query_log
98+
eval DROP TABLE `#mysql50#$temp_table_name`;
99+
--enable_query_log
100+
101+
--echo # Files in datadir after manual recovery.
102+
--list_files $MYSQLD_DATADIR/test
103+
104+
SHOW TABLES;
105+
SHOW CREATE TABLE t1;
106+
INSERT INTO t1 VALUES (5,6),(7,8);
107+
SELECT * FROM t1;
108+
DROP TABLE t1;
109+
110+
CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=InnoDB;
111+
ALTER TABLE t1 ADD PRIMARY KEY (f2, f1);
112+
DROP TABLE t1;
113+
114+
--echo # -- Scenario 2:
115+
--echo # Crash the server in ha_innobase::commit_inplace_alter_table()
116+
--echo # just before committing the dictionary changes, but after
117+
--echo # writing the MLOG_FILE_RENAME records. As the mini-transaction
118+
--echo # is not committed, the renames will not be replayed.
119+
120+
CREATE TABLE t2 (f1 int not null, f2 int not null) ENGINE=InnoDB;
121+
INSERT INTO t2 VALUES (1,2),(3,4);
122+
SET DEBUG_DBUG='+d,innodb_alter_commit_crash_before_commit';
123+
124+
let $orig_table_id = `SELECT table_id
125+
FROM information_schema.innodb_sys_tables
126+
WHERE name = 'test/t2'`;
127+
128+
# Write file to make mysql-test-run.pl expect crash
129+
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
130+
131+
--error 2013
132+
ALTER TABLE t2 ADD PRIMARY KEY (f2, f1);
133+
134+
--echo # Startup the server after the crash
135+
--source include/start_mysqld.inc
136+
137+
--echo # Read and remember the temporary table name
138+
let $temp_table_name = `SELECT SUBSTRING(name,6)
139+
FROM information_schema.innodb_sys_tables
140+
WHERE name LIKE "test/#sql-ib$orig_table_id%"`;
141+
# This second copy is an environment variable for the perl script below.
142+
let temp_table_name = $temp_table_name;
143+
144+
--echo # Manual *.frm recovery begin. The dictionary was not updated
145+
--echo # and the files were not renamed. The rebuilt table
146+
--echo # was left behind on purpose, to faciliate data recovery.
147+
148+
perl;
149+
my @frm_file = glob "$ENV{'datadir'}/test/#sql-*.frm";
150+
my $target_frm = "$ENV{'datadir'}/test/$ENV{'temp_table_name'}.frm";
151+
rename($frm_file[0], $target_frm);
152+
EOF
153+
154+
--echo # Manual recovery end
155+
156+
--echo # Drop the orphaned rebuilt table.
157+
--disable_query_log
158+
eval DROP TABLE `#mysql50#$temp_table_name`;
159+
--enable_query_log
160+
161+
SHOW TABLES;
162+
INSERT INTO t2 VALUES (5,6),(7,8);
163+
SELECT * from t2;
164+
SHOW CREATE TABLE t2;
165+
DROP TABLE t2;
166+
167+
CREATE TABLE t2 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=InnoDB;
168+
ALTER TABLE t2 ADD PRIMARY KEY (f2, f1);
169+
DROP TABLE t2;
170+
--list_files $MYSQLD_DATADIR/test
171+
172+
--echo # -------------------------
173+
--echo # End of Testing Scenario 2
174+
--echo # -------------------------
175+
176+
--echo #
177+
--echo # Bug#19330255 WL#7142 - CRASH DURING ALTER TABLE LEADS TO
178+
--echo # DATA DICTIONARY INCONSISTENCY
179+
--echo #
180+
181+
CREATE TABLE t1(a int PRIMARY KEY, b varchar(255), c int NOT NULL)
182+
ENGINE=InnoDB;
183+
INSERT INTO t1 SET a=1,c=2;
184+
SET DEBUG_DBUG='+d,innodb_alter_commit_crash_after_commit';
185+
186+
let $orig_table_id = `select table_id from
187+
information_schema.innodb_sys_tables where name = 'test/t1'`;
188+
189+
# FIXME: MDEV-9469 'Incorrect key file' on ALTER TABLE
190+
# Write file to make mysql-test-run.pl expect crash
191+
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
192+
#
193+
--error 2013
194+
ALTER TABLE t1 ADD INDEX (b), CHANGE c d int, ALGORITHM=INPLACE;
195+
196+
--echo # Restart mysqld after the crash and reconnect.
197+
--source include/start_mysqld.inc
198+
199+
let $temp_table_name = `SELECT SUBSTR(name, 6)
200+
FROM information_schema.innodb_sys_tables
201+
WHERE table_id = $orig_table_id`;
202+
203+
--echo # Manual *.frm recovery begin.
204+
--move_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/$temp_table_name.frm
205+
206+
perl;
207+
my @frm_file = glob "$ENV{'datadir'}/test/#sql-*.frm";
208+
my $t1_frm = "$ENV{'datadir'}/test/t1.frm";
209+
rename($frm_file[0], $t1_frm);
210+
EOF
211+
212+
--echo # Manual recovery end
213+
214+
FLUSH TABLES;
215+
216+
--echo # Drop the orphaned original table.
217+
--disable_query_log
218+
eval DROP TABLE `#mysql50#$temp_table_name`;
219+
--enable_query_log
220+
221+
--echo # Files in datadir after manual recovery.
222+
--list_files $MYSQLD_DATADIR/test
223+
224+
SHOW TABLES;
225+
SHOW CREATE TABLE t1;
226+
UPDATE t1 SET d=NULL;
227+
SELECT * FROM t1;
228+
DROP TABLE t1;

0 commit comments

Comments
 (0)