summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2022-03-16 14:30:36 +0530
committerThirunarayanan Balathandayuthapani <thiru@mariadb.com>2022-03-16 19:20:27 +0530
commit31ad9277fea8b8a9414f9495eeae7e0424275cd6 (patch)
tree2b1554833dbe431636dcb0887471c2a169de4c62
parentb2c81e06b042025663ea01fa98dac0ff536c7706 (diff)
downloadmariadb-git-31ad9277fea8b8a9414f9495eeae7e0424275cd6.tar.gz
MDEV-28079 Shutdown hangs after altering innodb partition fts table
- InnoDB purge waits at resume_FTS() while shutting down. This happens after altering the FTS innodb partition table. stop_FTS() has been called for each partition, but it calls resume_FTS() only once and it leads to hang during shutdown. This issue was introduced by commit 1bd681c8b3c5213ce1f7976940a7dc38b48a0d39(MDEV-25506).
-rw-r--r--mysql-test/suite/parts/r/partition_alter_innodb.result8
-rw-r--r--mysql-test/suite/parts/t/partition_alter_innodb.test8
-rw-r--r--storage/innobase/fts/fts0fts.cc9
-rw-r--r--storage/innobase/handler/handler0alter.cc4
-rw-r--r--storage/innobase/include/trx0purge.h6
5 files changed, 29 insertions, 6 deletions
diff --git a/mysql-test/suite/parts/r/partition_alter_innodb.result b/mysql-test/suite/parts/r/partition_alter_innodb.result
index f3921a1db26..fad8434989f 100644
--- a/mysql-test/suite/parts/r/partition_alter_innodb.result
+++ b/mysql-test/suite/parts/r/partition_alter_innodb.result
@@ -48,3 +48,11 @@ alter table t1 add partition (partition p0 values less than (20));
ERROR HY000: Duplicate partition name p0
alter table t1 add partition (partition p1 values less than (20)) /* comment */;
drop table t1;
+#
+# MDEV-28079 Shutdown hangs after altering innodb partition fts table
+#
+CREATE TABLE t1(f1 INT, f2 CHAR(100))ENGINE=InnoDB PARTITION BY HASH(f1) PARTITIONS 2;
+ALTER TABLE t1 ADD FULLTEXT(f2);
+InnoDB 0 transactions not purged
+DROP TABLE t1;
+# End of 10.6 tests
diff --git a/mysql-test/suite/parts/t/partition_alter_innodb.test b/mysql-test/suite/parts/t/partition_alter_innodb.test
index 4ea3a0da88c..844b2084531 100644
--- a/mysql-test/suite/parts/t/partition_alter_innodb.test
+++ b/mysql-test/suite/parts/t/partition_alter_innodb.test
@@ -9,3 +9,11 @@ SET GLOBAL innodb_read_only_compressed=OFF;
--disable_query_log
SET GLOBAL innodb_read_only_compressed=@save_innodb_read_only_compressed;
--enable_query_log
+--echo #
+--echo # MDEV-28079 Shutdown hangs after altering innodb partition fts table
+--echo #
+CREATE TABLE t1(f1 INT, f2 CHAR(100))ENGINE=InnoDB PARTITION BY HASH(f1) PARTITIONS 2;
+ALTER TABLE t1 ADD FULLTEXT(f2);
+--source ../innodb/include/wait_all_purged.inc
+DROP TABLE t1;
+--echo # End of 10.6 tests
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 7302f436918..c8aa6aab35a 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -1567,10 +1567,13 @@ static void fts_table_no_ref_count(const char *table_name)
/** Stop the purge thread and check n_ref_count of all auxiliary
and common table associated with the fts table.
-@param table parent FTS table */
-void purge_sys_t::stop_FTS(const dict_table_t &table)
+@param table parent FTS table
+@param already_stopped True indicates purge threads were
+ already stopped*/
+void purge_sys_t::stop_FTS(const dict_table_t &table, bool already_stopped)
{
- purge_sys.stop_FTS();
+ if (!already_stopped)
+ purge_sys.stop_FTS();
fts_table_t fts_table;
char table_name[MAX_FULL_NAME_LEN];
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 5a13240249c..ff069777ec4 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -10903,12 +10903,14 @@ ha_innobase::commit_inplace_alter_table(
}
}
+ bool already_stopped= false;
for (inplace_alter_handler_ctx** pctx = ctx_array; *pctx; pctx++) {
auto ctx = static_cast<ha_innobase_inplace_ctx*>(*pctx);
dberr_t error = DB_SUCCESS;
if (fts_exist) {
- purge_sys.stop_FTS(*ctx->old_table);
+ purge_sys.stop_FTS(*ctx->old_table, already_stopped);
+ already_stopped = true;
}
if (new_clustered && ctx->old_table->fts) {
diff --git a/storage/innobase/include/trx0purge.h b/storage/innobase/include/trx0purge.h
index dc032cdf73a..b3f2fbeedf3 100644
--- a/storage/innobase/include/trx0purge.h
+++ b/storage/innobase/include/trx0purge.h
@@ -286,8 +286,10 @@ public:
/** Stop the purge thread and check n_ref_count of all auxiliary
and common table associated with the fts table.
- @param table parent FTS table */
- void stop_FTS(const dict_table_t &table);
+ @param table parent FTS table
+ @param already_stopped True indicates purge threads were
+ already stopped */
+ void stop_FTS(const dict_table_t &table, bool already_stopped=false);
};
/** The global data structure coordinating a purge */