From 6efa4a59d84babadb132a867be5f4db4dd7dbdde Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Thu, 4 Jul 2024 13:27:33 +0200 Subject: [PATCH] Ensure FTS auxiliary tables are cleaned up properly The issue here is that when multiple FTS indexes are dropped in a single `ALTER TABLE` statement, we don't clean up the auxiliary index tables from the data dictionary. They are still referenced and when MySQL restarts the next time, it prints a number of warnings: 2024-07-04T10:07:26.207208Z 1 [Warning] [MY-012351] [InnoDB] Tablespace 12, name 'test/fts_000000000000042d_00000000000000a7_index_1', file './test/fts_000000000000042d_00000000000000a7_index_1.ibd' is missing! 2024-07-04T10:07:26.207251Z 1 [Warning] [MY-012351] [InnoDB] Tablespace 13, name 'test/fts_000000000000042d_00000000000000a7_index_2', file './test/fts_000000000000042d_00000000000000a7_index_2.ibd' is missing! 2024-07-04T10:07:26.207285Z 1 [Warning] [MY-012351] [InnoDB] Tablespace 14, name 'test/fts_000000000000042d_00000000000000a7_index_3', file './test/fts_000000000000042d_00000000000000a7_index_3.ibd' is missing! 2024-07-04T10:07:26.207303Z 1 [Warning] [MY-012351] [InnoDB] Tablespace 15, name 'test/fts_000000000000042d_00000000000000a7_index_4', file './test/fts_000000000000042d_00000000000000a7_index_4.ibd' is missing! 2024-07-04T10:07:26.207319Z 1 [Warning] [MY-012351] [InnoDB] Tablespace 16, name 'test/fts_000000000000042d_00000000000000a7_index_5', file './test/fts_000000000000042d_00000000000000a7_index_5.ibd' is missing! 2024-07-04T10:07:26.207335Z 1 [Warning] [MY-012351] [InnoDB] Tablespace 17, name 'test/fts_000000000000042d_00000000000000a7_index_6', file './test/fts_000000000000042d_00000000000000a7_index_6.ibd' is missing! The problem is that when multiple indexes are dropped at once, we end up looping through and overwriting ctx->fts_drop_aux_vec on the next iteration. This means that this both leaks memory as the old vector is not de-allocated but also that the initial set of aux tables is not removed from the data dictionary later on. The fix is simple, only allocate ctx->fts_drop_aux_vec if it's not allocated yet. This way all aux tables are gathered for all indexes and cleaned up correctly. A test is added that reproduces the above warning and this test passes with the fixes here. Signed-off-by: Dirkjan Bussink --- .../suite/innodb_fts/r/drop_multiple.result | 14 ++++++++++++++ .../suite/innodb_fts/t/drop_multiple.test | 18 ++++++++++++++++++ storage/innobase/handler/handler0alter.cc | 4 +++- 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/innodb_fts/r/drop_multiple.result create mode 100644 mysql-test/suite/innodb_fts/t/drop_multiple.test diff --git a/mysql-test/suite/innodb_fts/r/drop_multiple.result b/mysql-test/suite/innodb_fts/r/drop_multiple.result new file mode 100644 index 000000000000..23c60de18fa6 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/drop_multiple.result @@ -0,0 +1,14 @@ +# +# Test for having lingering FTS index in data dictionary +# after dropping multiple FTS indexes. +# +CREATE TABLE fts_test ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT idx_title (title), +FULLTEXT idx_body (body) +) ENGINE=InnoDB; +ALTER TABLE fts_test DROP INDEX idx_title, DROP INDEX idx_body; +# restart +DROP TABLE fts_test; diff --git a/mysql-test/suite/innodb_fts/t/drop_multiple.test b/mysql-test/suite/innodb_fts/t/drop_multiple.test new file mode 100644 index 000000000000..55bf3cf60ce3 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/drop_multiple.test @@ -0,0 +1,18 @@ +--echo # +--echo # Test for having lingering FTS index in data dictionary +--echo # after dropping multiple FTS indexes. +--echo # + +CREATE TABLE fts_test ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT idx_title (title), + FULLTEXT idx_body (body) + ) ENGINE=InnoDB; + +ALTER TABLE fts_test DROP INDEX idx_title, DROP INDEX idx_body; + +--source include/restart_mysqld.inc + +DROP TABLE fts_test; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 23af83f7df8c..5c60cb83a80c 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -7224,7 +7224,9 @@ after a successful commit_try_norebuild() call. if (index->type & DICT_FTS) { assert(index->type == DICT_FTS || index->is_corrupted()); assert(index->table->fts); - ctx->fts_drop_aux_vec = new aux_name_vec_t; + if (ctx->fts_drop_aux_vec == nullptr) { + ctx->fts_drop_aux_vec = new aux_name_vec_t; + } fts_drop_index(index->table, index, trx, ctx->fts_drop_aux_vec); }