Skip to content

Commit ab0034a

Browse files
committed
MDEV-20370 Crash after OPTIMIZE TABLE on TEMPORARY TABLE
Temporary tables are typically short-lived, and temporary tables are assumed to be accessed only by the thread that is handling the owning connection. Hence, they must not be subject to defragmenting. ha_innobase::optimize(): Do not add temporary tables to the defragment_table() queue.
1 parent e61b990 commit ab0034a

File tree

3 files changed

+32
-21
lines changed

3 files changed

+32
-21
lines changed

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
DROP TABLE if exists t1;
2-
select @@global.innodb_stats_persistent;
3-
@@global.innodb_stats_persistent
4-
0
1+
SET @n_pages= @@GLOBAL.innodb_defragment_n_pages;
2+
SET @accuracy= @@GLOBAL.innodb_defragment_stats_accuracy;
3+
SET @sp= @@GLOBAL.innodb_stats_persistent;
4+
SET GLOBAL innodb_stats_persistent = 0;
55
set global innodb_defragment_stats_accuracy = 80;
66
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
77
b VARCHAR(256),
@@ -18,6 +18,14 @@ connect con3,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK;
1818
connect con4,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK;
1919
connection default;
2020
SET @@global.innodb_defragment_n_pages = 20;
21+
CREATE TEMPORARY TABLE tt (a INT, KEY(a)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
22+
INSERT INTO tt SELECT 0 FROM seq_1_to_180;
23+
INSERT INTO tt SELECT 5 FROM seq_1_to_160;
24+
INSERT INTO tt SELECT 1 FROM seq_1_to_1000;
25+
OPTIMIZE TABLE tt;
26+
Table Op Msg_type Msg_text
27+
test.tt optimize note Table does not support optimize, doing recreate + analyze instead
28+
test.tt optimize status OK
2129
select count(*) from t1;
2230
count(*)
2331
20000
@@ -89,3 +97,6 @@ select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like
8997
count(stat_value) > 0
9098
1
9199
drop table t1;
100+
SET GLOBAL innodb_defragment_n_pages = @n_pages;
101+
SET GLOBAL innodb_defragment_stats_accuracy = @accuracy;
102+
SET GLOBAL innodb_stats_persistent = @sp;

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

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,13 @@
22
--source include/big_test.inc
33
--source include/not_valgrind.inc
44
--source include/not_embedded.inc
5+
--source include/have_sequence.inc
56

6-
--disable_warnings
7-
DROP TABLE if exists t1;
8-
--enable_warnings
7+
SET @n_pages= @@GLOBAL.innodb_defragment_n_pages;
8+
SET @accuracy= @@GLOBAL.innodb_defragment_stats_accuracy;
9+
SET @sp= @@GLOBAL.innodb_stats_persistent;
910

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-
15-
select @@global.innodb_stats_persistent;
11+
SET GLOBAL innodb_stats_persistent = 0;
1612
set global innodb_defragment_stats_accuracy = 80;
1713

1814
# Create table.
@@ -46,6 +42,12 @@ connection default;
4642

4743
SET @@global.innodb_defragment_n_pages = 20;
4844

45+
CREATE TEMPORARY TABLE tt (a INT, KEY(a)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
46+
INSERT INTO tt SELECT 0 FROM seq_1_to_180;
47+
INSERT INTO tt SELECT 5 FROM seq_1_to_160;
48+
INSERT INTO tt SELECT 1 FROM seq_1_to_1000;
49+
OPTIMIZE TABLE tt;
50+
4951
let $data_size = 20000;
5052
let $delete_size = 2000;
5153

@@ -60,7 +62,7 @@ while ($i)
6062
}
6163
--enable_query_log
6264

63-
select count(*) from t1;
65+
select count(*) from t1;
6466
select count(*) from t1 force index (second);
6567
select count(*) from t1 force index (third);
6668

@@ -75,7 +77,7 @@ while ($size)
7577
}
7678
--enable_query_log
7779

78-
select count(*) from t1;
80+
select count(*) from t1;
7981
select count(*) from t1 force index (second);
8082
select count(*) from t1 force index (third);
8183

@@ -136,7 +138,6 @@ select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like
136138
drop table t1;
137139

138140
# reset system
139-
--disable_query_log
140-
EVAL SET GLOBAL innodb_defragment_n_pages = $innodb_defragment_n_pages_orig;
141-
EVAL SET GLOBAL innodb_defragment_stats_accuracy = $innodb_defragment_stats_accuracy_orig;
142-
--enable_query_log
141+
SET GLOBAL innodb_defragment_n_pages = @n_pages;
142+
SET GLOBAL innodb_defragment_stats_accuracy = @accuracy;
143+
SET GLOBAL innodb_stats_persistent = @sp;

storage/innobase/handler/ha_innodb.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14903,8 +14903,7 @@ ha_innobase::optimize(
1490314903
calls to OPTIMIZE, which is undesirable. */
1490414904
bool try_alter = true;
1490514905

14906-
/* TODO: Defragment is disabled for now */
14907-
if (srv_defragment) {
14906+
if (!m_prebuilt->table->is_temporary() && srv_defragment) {
1490814907
int err;
1490914908

1491014909
err = defragment_table(m_prebuilt->table->name.m_name, NULL, false);

0 commit comments

Comments
 (0)