From 9a815401c6c1972745432ff93cbc8f55cae30d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 23 Aug 2018 13:11:11 +0300 Subject: [PATCH] MDEV-17043 Purge of indexed virtual columns may cause hang on table-rebuilding DDL When a table is renamed to an internal #sql2 or #sql-ib name during a table-rebuilding DDL operation such as OPTIMIZE TABLE or ALTER TABLE, and shortly after that a purge operation in an index on virtual columns is attempted, the operation could fail, but purge would fail to release the table reference. innodb_acquire_mdl(): Release the reference if the table name is not valid for acquiring a meta-data lock (MDL). innodb_find_table_for_vc(): Add a debug assertion if the table name is not valid. This code path is for DML execution. The table should have a valid name for executing DML, and furthermore a MDL will prevent the table from being renamed. row_vers_build_clust_v_col(): Add a debug assertion that both indexes must belong to the same table. --- storage/innobase/handler/ha_innodb.cc | 2 ++ storage/innobase/row/row0vers.cc | 1 + 2 files changed, 3 insertions(+) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index c3a6bd663b3..35e091e0f11 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -21425,6 +21425,7 @@ static TABLE* innodb_acquire_mdl(THD* thd, dict_table_t* table) if (!table_name_parse(table->name, db_buf, tbl_buf, db_buf_len, tbl_buf_len)) { + table->release(); return NULL; } @@ -21507,6 +21508,7 @@ static TABLE* innodb_find_table_for_vc(THD* thd, dict_table_t* table) if (!table_name_parse(table->name, db_buf, tbl_buf, db_buf_len, tbl_buf_len)) { + ut_ad(!"invalid table name"); return NULL; } diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc index 24acd04c84b..811654fdef8 100644 --- a/storage/innobase/row/row0vers.cc +++ b/storage/innobase/row/row0vers.cc @@ -456,6 +456,7 @@ row_vers_build_clust_v_col( byte* record= 0; ut_ad(dict_index_has_virtual(index)); + ut_ad(index->table == clust_index->table); if (vcol_info != NULL) { vcol_info->set_used();