Skip to content

Commit 25d69ea

Browse files
committed
MDEV-12198 innodb_defragment=1 crashes server on OPTIMIZE TABLE when FULLTEXT index exists
ha_innobase::defragment_table(): Skip corrupted indexes and FULLTEXT INDEX. In InnoDB, FULLTEXT INDEX is implemented with auxiliary tables. We will not defragment them on OPTIMIZE TABLE.
1 parent 8d4871a commit 25d69ea

File tree

8 files changed

+77
-20
lines changed

8 files changed

+77
-20
lines changed

mysql-test/suite/innodb/r/innodb_defragment.result

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
DROP TABLE if exists t1;
21
set global innodb_defragment_stats_accuracy = 80;
32
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256), KEY SECOND(a, b)) ENGINE=INNODB;
43
optimize table t1;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
SET @innodb_defragment_orig=@@GLOBAL.innodb_defragment;
2+
SET GLOBAL innodb_defragment = 1;
3+
CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(256), KEY(a, b)) ENGINE=INNODB;
4+
OPTIMIZE TABLE t1;
5+
Table Op Msg_type Msg_text
6+
test.t1 optimize status OK
7+
INSERT INTO t1 VALUES (100000, REPEAT('A', 256));
8+
INSERT INTO t1 VALUES (200000, REPEAT('A', 256));
9+
INSERT INTO t1 VALUES (300000, REPEAT('A', 256));
10+
INSERT INTO t1 VALUES (400000, REPEAT('A', 256));
11+
OPTIMIZE TABLE t1;
12+
Table Op Msg_type Msg_text
13+
test.t1 optimize status OK
14+
DROP TABLE t1;
15+
#
16+
# MDEV-12198 innodb_defragment=1 crashes server on
17+
# OPTIMIZE TABLE when FULLTEXT index exists
18+
#
19+
CREATE TABLE t1 (c TEXT, FULLTEXT KEY (c)) ENGINE=InnoDB;
20+
OPTIMIZE TABLE t1;
21+
Table Op Msg_type Msg_text
22+
test.t1 optimize status OK
23+
DROP TABLE t1;
24+
SET GLOBAL innodb_defragment = @innodb_defragment_orig;

mysql-test/suite/innodb/t/innodb_defragment-master.opt

Lines changed: 0 additions & 2 deletions
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
--loose-innodb-buffer-pool-stats
22
--loose-innodb-buffer-page
33
--loose-innodb-buffer-page-lru
4+
--innodb-file-per-table
45
--innodb-defragment=1

mysql-test/suite/innodb/t/innodb_defragment.test

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,7 @@
11
--source include/have_innodb.inc
22
--source include/big_test.inc
3-
--source include/not_valgrind.inc
43
--source include/not_embedded.inc
54

6-
--disable_warnings
7-
DROP TABLE if exists t1;
8-
--enable_warnings
9-
10-
--disable_query_log
11-
let $innodb_defragment_n_pages_orig=`select @@innodb_defragment_n_pages`;
12-
let $innodb_defragment_stats_accuracy_orig=`select @@innodb_defragment_stats_accuracy`;
13-
--enable_query_log
14-
155
set global innodb_defragment_stats_accuracy = 80;
166

177
# Create table.
@@ -47,12 +37,14 @@ delimiter ;//
4737
# Populate table.
4838
let $i = $data_size;
4939
--disable_query_log
40+
BEGIN;
5041
while ($i)
5142
{
5243
eval
5344
INSERT INTO t1 VALUES ($data_size + 1 - $i, REPEAT('A', 256));
5445
dec $i;
5546
}
47+
COMMIT;
5648
--enable_query_log
5749

5850
select count(stat_value) from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
@@ -161,10 +153,3 @@ select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like
161153

162154
DROP PROCEDURE defragment;
163155
DROP TABLE t1;
164-
165-
# reset system
166-
--disable_query_log
167-
EVAL SET GLOBAL innodb_defragment_n_pages = $innodb_defragment_n_pages_orig;
168-
EVAL SET GLOBAL innodb_defragment_stats_accuracy = $innodb_defragment_stats_accuracy_orig;
169-
--enable_query_log
170-
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--source include/have_innodb.inc
2+
3+
SET @innodb_defragment_orig=@@GLOBAL.innodb_defragment;
4+
SET GLOBAL innodb_defragment = 1;
5+
6+
# Small tests copied from innodb.innodb_defragment
7+
CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(256), KEY(a, b)) ENGINE=INNODB;
8+
OPTIMIZE TABLE t1;
9+
10+
INSERT INTO t1 VALUES (100000, REPEAT('A', 256));
11+
INSERT INTO t1 VALUES (200000, REPEAT('A', 256));
12+
INSERT INTO t1 VALUES (300000, REPEAT('A', 256));
13+
INSERT INTO t1 VALUES (400000, REPEAT('A', 256));
14+
15+
OPTIMIZE TABLE t1;
16+
DROP TABLE t1;
17+
18+
--echo #
19+
--echo # MDEV-12198 innodb_defragment=1 crashes server on
20+
--echo # OPTIMIZE TABLE when FULLTEXT index exists
21+
--echo #
22+
23+
CREATE TABLE t1 (c TEXT, FULLTEXT KEY (c)) ENGINE=InnoDB;
24+
25+
OPTIMIZE TABLE t1;
26+
DROP TABLE t1;
27+
28+
SET GLOBAL innodb_defragment = @innodb_defragment_orig;

storage/innobase/handler/ha_innodb.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12599,6 +12599,17 @@ ha_innobase::defragment_table(
1259912599
for (index = dict_table_get_first_index(table); index;
1260012600
index = dict_table_get_next_index(index)) {
1260112601

12602+
if (dict_index_is_corrupted(index)) {
12603+
continue;
12604+
}
12605+
12606+
if (index->page == FIL_NULL) {
12607+
/* Do not defragment auxiliary tables related
12608+
to FULLTEXT INDEX. */
12609+
ut_ad(index->type & DICT_FTS);
12610+
continue;
12611+
}
12612+
1260212613
if (one_index && strcasecmp(index_name, index->name) != 0) {
1260312614
continue;
1260412615
}

storage/xtradb/handler/ha_innodb.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13272,6 +13272,17 @@ ha_innobase::defragment_table(
1327213272
for (index = dict_table_get_first_index(table); index;
1327313273
index = dict_table_get_next_index(index)) {
1327413274

13275+
if (dict_index_is_corrupted(index)) {
13276+
continue;
13277+
}
13278+
13279+
if (index->page == FIL_NULL) {
13280+
/* Do not defragment auxiliary tables related
13281+
to FULLTEXT INDEX. */
13282+
ut_ad(index->type & DICT_FTS);
13283+
continue;
13284+
}
13285+
1327513286
if (one_index && strcasecmp(index_name, index->name) != 0) {
1327613287
continue;
1327713288
}

0 commit comments

Comments
 (0)