From b159f05a63af6e4bbfc5840d77f9265a56db0216 Mon Sep 17 00:00:00 2001 From: Monty Date: Sat, 7 Oct 2023 17:17:15 +0300 Subject: [PATCH] MDEV-31957 Concurrent ALTER and ANALYZE collecting statistics can result in stale statistical data Fixed hang when renaming index to original name --- mysql-test/main/analyze.result | 35 ++++++++++++++++++++++++++++++++++ mysql-test/main/analyze.test | 15 +++++++++++++++ sql/sql_table.cc | 8 ++++++-- 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/analyze.result b/mysql-test/main/analyze.result index 8d345d98b05..aac9ed7b3a2 100644 --- a/mysql-test/main/analyze.result +++ b/mysql-test/main/analyze.result @@ -382,5 +382,40 @@ ALTER TABLE t1 DROP KEY idx; ERROR HY000: Cannot drop index 'idx': needed in a foreign key constraint DROP TABLE t1; # +# Check index rename where name is not changed +# +create or replace table t1 (a int primary key, b int, c int, key b (b,c)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + KEY `b` (`b`,`c`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +select * from mysql.index_stats where table_name= "t1"; +db_name table_name index_name prefix_arity avg_frequency +test t1 PRIMARY 1 1.0000 +test t1 b 1 NULL +test t1 b 2 NULL +alter ignore table t1 rename key `b` to b, LOCK=shared; +select * from mysql.index_stats where table_name= "t1"; +db_name table_name index_name prefix_arity avg_frequency +test t1 PRIMARY 1 1.0000 +test t1 b 1 NULL +test t1 b 2 NULL +alter ignore table t1 rename key `b` to `B`, LOCK=shared; +select * from mysql.index_stats where table_name= "t1"; +db_name table_name index_name prefix_arity avg_frequency +test t1 PRIMARY 1 1.0000 +test t1 B 1 NULL +test t1 B 2 NULL +drop table t1; +# # End of 10.6 tests # diff --git a/mysql-test/main/analyze.test b/mysql-test/main/analyze.test index d89e05b8543..e3b776f11ca 100644 --- a/mysql-test/main/analyze.test +++ b/mysql-test/main/analyze.test @@ -254,6 +254,21 @@ SELECT index_name FROM mysql.index_stats WHERE table_name = 't1' order by index_ --error ER_DROP_INDEX_FK ALTER TABLE t1 DROP KEY idx; DROP TABLE t1; + +--echo # +--echo # Check index rename where name is not changed +--echo # + +create or replace table t1 (a int primary key, b int, c int, key b (b,c)); +show create table t1; +analyze table t1 persistent for all; +select * from mysql.index_stats where table_name= "t1"; +alter ignore table t1 rename key `b` to b, LOCK=shared; +select * from mysql.index_stats where table_name= "t1"; +alter ignore table t1 rename key `b` to `B`, LOCK=shared; +select * from mysql.index_stats where table_name= "t1"; +drop table t1; + --echo # --echo # End of 10.6 tests --echo # diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9e20db8b5e4..bac8b6c4243 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -8298,9 +8298,13 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, } key_name= rename_key->new_name.str; // New name of current key_info + if (cmp(&rename_key->old_name, &rename_key->new_name)) + { + /* Key was renamed */ + alter_info->add_stat_rename_index(key_info, &rename_key->new_name, + thd->mem_root); + } rename_key_it.remove(); - alter_info->add_stat_rename_index(key_info, &rename_key->new_name, - thd->mem_root); /* If the user has explicitly renamed the key, we should no longer