Commit 25d69ea0 authored by Marko Mäkelä's avatar Marko Mäkelä

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.
parent 8d4871a9
DROP TABLE if exists t1;
set global innodb_defragment_stats_accuracy = 80;
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256), KEY SECOND(a, b)) ENGINE=INNODB;
optimize table t1;
......
SET @innodb_defragment_orig=@@GLOBAL.innodb_defragment;
SET GLOBAL innodb_defragment = 1;
CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(256), KEY(a, b)) ENGINE=INNODB;
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
INSERT INTO t1 VALUES (100000, REPEAT('A', 256));
INSERT INTO t1 VALUES (200000, REPEAT('A', 256));
INSERT INTO t1 VALUES (300000, REPEAT('A', 256));
INSERT INTO t1 VALUES (400000, REPEAT('A', 256));
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
DROP TABLE t1;
#
# MDEV-12198 innodb_defragment=1 crashes server on
# OPTIMIZE TABLE when FULLTEXT index exists
#
CREATE TABLE t1 (c TEXT, FULLTEXT KEY (c)) ENGINE=InnoDB;
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
DROP TABLE t1;
SET GLOBAL innodb_defragment = @innodb_defragment_orig;
--innodb_file_per_table
--innodb-defragment=1
\ No newline at end of file
--loose-innodb-buffer-pool-stats
--loose-innodb-buffer-page
--loose-innodb-buffer-page-lru
--innodb-file-per-table
--innodb-defragment=1
\ No newline at end of file
--source include/have_innodb.inc
--source include/big_test.inc
--source include/not_valgrind.inc
--source include/not_embedded.inc
--disable_warnings
DROP TABLE if exists t1;
--enable_warnings
--disable_query_log
let $innodb_defragment_n_pages_orig=`select @@innodb_defragment_n_pages`;
let $innodb_defragment_stats_accuracy_orig=`select @@innodb_defragment_stats_accuracy`;
--enable_query_log
set global innodb_defragment_stats_accuracy = 80;
# Create table.
......@@ -47,12 +37,14 @@ delimiter ;//
# Populate table.
let $i = $data_size;
--disable_query_log
BEGIN;
while ($i)
{
eval
INSERT INTO t1 VALUES ($data_size + 1 - $i, REPEAT('A', 256));
dec $i;
}
COMMIT;
--enable_query_log
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
DROP PROCEDURE defragment;
DROP TABLE t1;
# reset system
--disable_query_log
EVAL SET GLOBAL innodb_defragment_n_pages = $innodb_defragment_n_pages_orig;
EVAL SET GLOBAL innodb_defragment_stats_accuracy = $innodb_defragment_stats_accuracy_orig;
--enable_query_log
--source include/have_innodb.inc
SET @innodb_defragment_orig=@@GLOBAL.innodb_defragment;
SET GLOBAL innodb_defragment = 1;
# Small tests copied from innodb.innodb_defragment
CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(256), KEY(a, b)) ENGINE=INNODB;
OPTIMIZE TABLE t1;
INSERT INTO t1 VALUES (100000, REPEAT('A', 256));
INSERT INTO t1 VALUES (200000, REPEAT('A', 256));
INSERT INTO t1 VALUES (300000, REPEAT('A', 256));
INSERT INTO t1 VALUES (400000, REPEAT('A', 256));
OPTIMIZE TABLE t1;
DROP TABLE t1;
--echo #
--echo # MDEV-12198 innodb_defragment=1 crashes server on
--echo # OPTIMIZE TABLE when FULLTEXT index exists
--echo #
CREATE TABLE t1 (c TEXT, FULLTEXT KEY (c)) ENGINE=InnoDB;
OPTIMIZE TABLE t1;
DROP TABLE t1;
SET GLOBAL innodb_defragment = @innodb_defragment_orig;
......@@ -12599,6 +12599,17 @@ ha_innobase::defragment_table(
for (index = dict_table_get_first_index(table); index;
index = dict_table_get_next_index(index)) {
if (dict_index_is_corrupted(index)) {
continue;
}
if (index->page == FIL_NULL) {
/* Do not defragment auxiliary tables related
to FULLTEXT INDEX. */
ut_ad(index->type & DICT_FTS);
continue;
}
if (one_index && strcasecmp(index_name, index->name) != 0) {
continue;
}
......
......@@ -13272,6 +13272,17 @@ ha_innobase::defragment_table(
for (index = dict_table_get_first_index(table); index;
index = dict_table_get_next_index(index)) {
if (dict_index_is_corrupted(index)) {
continue;
}
if (index->page == FIL_NULL) {
/* Do not defragment auxiliary tables related
to FULLTEXT INDEX. */
ut_ad(index->type & DICT_FTS);
continue;
}
if (one_index && strcasecmp(index_name, index->name) != 0) {
continue;
}
......
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