From c6d2908d6da6836242b7e211988e2d72c7ca9040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A1=A6=E9=9B=84?= Date: Sat, 8 Feb 2025 18:02:07 +0800 Subject: [PATCH] fix --- mysql-test/include/commit.inc | 4 +- mysql-test/r/alter_table_myisam.result | 4 +- mysql-test/r/bug117416.result | 51 +++++++++++++ mysql-test/r/commit_1innodb.result | 4 +- .../r/generated_invisible_primary_key.result | 2 +- mysql-test/r/wl14965.result | 18 ++--- mysql-test/t/bug117416.test | 75 +++++++++++++++++++ sql/sql_table.cc | 4 +- 8 files changed, 145 insertions(+), 17 deletions(-) create mode 100644 mysql-test/r/bug117416.result create mode 100644 mysql-test/t/bug117416.test diff --git a/mysql-test/include/commit.inc b/mysql-test/include/commit.inc index 43a4af38e3a..32c63ba3c35 100644 --- a/mysql-test/include/commit.inc +++ b/mysql-test/include/commit.inc @@ -961,9 +961,9 @@ if ($have_debug) } alter table t3 rename t4; -call p_verify_status_increment(20, 4, 3, 0); +call p_verify_status_increment(22, 4, 3, 0); rename table t4 to t3; -call p_verify_status_increment(24, 4, 5, 0); +call p_verify_status_increment(26, 4, 5, 0); truncate table t3; if (!$have_debug) diff --git a/mysql-test/r/alter_table_myisam.result b/mysql-test/r/alter_table_myisam.result index 3de24818452..2c4e77a8726 100644 --- a/mysql-test/r/alter_table_myisam.result +++ b/mysql-test/r/alter_table_myisam.result @@ -449,7 +449,7 @@ select index_length into @paked_keys_size from information_schema.tables where table_name='t1'; select (@unpaked_keys_size > @paked_keys_size); (@unpaked_keys_size > @paked_keys_size) -0 +1 select max_data_length into @orig_max_data_length from information_schema.tables where table_name='t1'; alter table t1 max_rows=100; @@ -457,7 +457,7 @@ select max_data_length into @changed_max_data_length from information_schema.tables where table_name='t1'; select (@orig_max_data_length > @changed_max_data_length); (@orig_max_data_length > @changed_max_data_length) -0 +1 drop table t1; CREATE TABLE t1 (f1 TIMESTAMP NULL DEFAULT NULL, f2 INT(11) DEFAULT NULL) ENGINE=MYISAM DEFAULT CHARSET=utf8; diff --git a/mysql-test/r/bug117416.result b/mysql-test/r/bug117416.result new file mode 100644 index 00000000000..77e4b791d65 --- /dev/null +++ b/mysql-test/r/bug117416.result @@ -0,0 +1,51 @@ +# +# 1) Prepare +# +SET DEBUG='+d,skip_dd_table_access_check'; +CREATE DATABASE my_test; +USE my_test; +CREATE TABLE t1 (id INT); +CREATE TABLE t2 LIKE t1; +INSERT INTO t1 VALUES (1); +CREATE PROCEDURE insert_n_times(IN n INT) +BEGIN +DECLARE i INT DEFAULT 1; +WHILE i <= n DO +INSERT INTO t1 SELECT * FROM t1; +SET i = i + 1; +END WHILE; +END$$ +CALL insert_n_times(16); +# +# 2) Get original table status +# +ANALYZE TABLE t1, t2; +Table Op Msg_type Msg_text +my_test.t1 analyze status OK +my_test.t2 analyze status OK +# +# 3) RENAME, old table status should be cleared. +# +RENAME TABLE t1 TO t1_tmp; +SELECT TABLE_NAME FROM mysql.table_stats WHERE SCHEMA_NAME = 'my_test'; +TABLE_NAME +t2 +RENAME TABLE t2 TO t1; +SELECT TABLE_NAME FROM mysql.table_stats WHERE SCHEMA_NAME = 'my_test'; +TABLE_NAME +RENAME TABLE t1_tmp TO t2; +SELECT TABLE_NAME FROM mysql.table_stats WHERE SCHEMA_NAME = 'my_test'; +TABLE_NAME +# +# 4) Check table status +# +ANALYZE TABLE t1, t2; +Table Op Msg_type Msg_text +my_test.t1 analyze status OK +my_test.t2 analyze status OK +include/assert.inc [table status of new t1 is equal to original t2] +include/assert.inc [table status of new_t2 is equal to original t1] +# +# 5) Cleanup +# +DROP DATABASE my_test; diff --git a/mysql-test/r/commit_1innodb.result b/mysql-test/r/commit_1innodb.result index c3fa2664706..057fcbebd39 100644 --- a/mysql-test/r/commit_1innodb.result +++ b/mysql-test/r/commit_1innodb.result @@ -853,11 +853,11 @@ call p_verify_status_increment(X, 4, 2, 0); SUCCESS alter table t3 rename t4; -call p_verify_status_increment(20, 4, 3, 0); +call p_verify_status_increment(22, 4, 3, 0); SUCCESS rename table t4 to t3; -call p_verify_status_increment(24, 4, 5, 0); +call p_verify_status_increment(26, 4, 5, 0); SUCCESS truncate table t3; diff --git a/mysql-test/r/generated_invisible_primary_key.result b/mysql-test/r/generated_invisible_primary_key.result index 2e11f562428..43345401228 100644 --- a/mysql-test/r/generated_invisible_primary_key.result +++ b/mysql-test/r/generated_invisible_primary_key.result @@ -1221,7 +1221,7 @@ f1 int YES NULL f2 int YES UNI NULL Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Visible Expression t1 0 PRIMARY 1 my_row_id A 0 NULL NULL BTREE YES NULL -t1 0 f2 1 f2 A 0 NULL NULL YES BTREE YES NULL +t1 0 f2 1 f2 A NULL NULL NULL YES BTREE YES NULL TABLE_NAME AUTO_INCREMENT t1 1 COLUMN_NAME COLUMN_TYPE IS_NULLABLE EXTRA diff --git a/mysql-test/r/wl14965.result b/mysql-test/r/wl14965.result index f41909a9f67..ef539ab865a 100644 --- a/mysql-test/r/wl14965.result +++ b/mysql-test/r/wl14965.result @@ -35,17 +35,17 @@ procs_priv 1 Grantor 1 Grantor A 0 NULL NULL BTREE YES NULL # restart:--upgrade=force SHOW KEYS FROM mysql.db; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Visible Expression -db 0 PRIMARY 1 Host A 1 NULL NULL BTREE YES NULL -db 0 PRIMARY 2 User A 1 NULL NULL BTREE YES NULL -db 0 PRIMARY 3 Db A 1 NULL NULL BTREE YES NULL -db 1 User 1 User A 1 NULL NULL BTREE YES NULL +db 0 PRIMARY 1 Host A 2 NULL NULL BTREE YES NULL +db 0 PRIMARY 2 User A 3 NULL NULL BTREE YES NULL +db 0 PRIMARY 3 Db A 3 NULL NULL BTREE YES NULL +db 1 User 1 User A 3 NULL NULL BTREE YES NULL SHOW KEYS FROM mysql.tables_priv; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Visible Expression -tables_priv 0 PRIMARY 1 Host A 1 NULL NULL BTREE YES NULL -tables_priv 0 PRIMARY 2 User A 1 NULL NULL BTREE YES NULL -tables_priv 0 PRIMARY 3 Db A 1 NULL NULL BTREE YES NULL -tables_priv 0 PRIMARY 4 Table_name A 1 NULL NULL BTREE YES NULL -tables_priv 1 Grantor 1 Grantor A 1 NULL NULL BTREE YES NULL +tables_priv 0 PRIMARY 1 Host A 2 NULL NULL BTREE YES NULL +tables_priv 0 PRIMARY 2 User A 3 NULL NULL BTREE YES NULL +tables_priv 0 PRIMARY 3 Db A 3 NULL NULL BTREE YES NULL +tables_priv 0 PRIMARY 4 Table_name A 3 NULL NULL BTREE YES NULL +tables_priv 1 Grantor 1 Grantor A 2 NULL NULL BTREE YES NULL SHOW KEYS FROM mysql.columns_priv; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Visible Expression columns_priv 0 PRIMARY 1 Host A 1 NULL NULL BTREE YES NULL diff --git a/mysql-test/t/bug117416.test b/mysql-test/t/bug117416.test new file mode 100644 index 00000000000..cc74267c9d9 --- /dev/null +++ b/mysql-test/t/bug117416.test @@ -0,0 +1,75 @@ +source include/have_debug.inc; + +--echo # +--echo # 1) Prepare +--echo # +SET DEBUG='+d,skip_dd_table_access_check'; +CREATE DATABASE my_test; +USE my_test; + +# table status of t1 and t2 will be significantly different +CREATE TABLE t1 (id INT); +CREATE TABLE t2 LIKE t1; + +INSERT INTO t1 VALUES (1); +DELIMITER $$; + +CREATE PROCEDURE insert_n_times(IN n INT) +BEGIN + DECLARE i INT DEFAULT 1; + + WHILE i <= n DO + INSERT INTO t1 SELECT * FROM t1; + SET i = i + 1; + END WHILE; +END$$ + +DELIMITER ;$$ + +CALL insert_n_times(16); + +--echo # +--echo # 2) Get original table status +--echo # +ANALYZE TABLE t1, t2; +--let $t1_data_length = query_get_value(SELECT DATA_LENGTH FROM information_schema.tables WHERE TABLE_NAME = "t1", DATA_LENGTH, 1) +--let $t2_data_length = query_get_value(SELECT DATA_LENGTH FROM information_schema.tables WHERE TABLE_NAME = "t2", DATA_LENGTH, 1) + + +--echo # +--echo # 3) RENAME, old table status should be cleared. +--echo # +RENAME TABLE t1 TO t1_tmp; +--sorted_result +SELECT TABLE_NAME FROM mysql.table_stats WHERE SCHEMA_NAME = 'my_test'; + +RENAME TABLE t2 TO t1; +--sorted_result +SELECT TABLE_NAME FROM mysql.table_stats WHERE SCHEMA_NAME = 'my_test'; + +RENAME TABLE t1_tmp TO t2; +--sorted_result +SELECT TABLE_NAME FROM mysql.table_stats WHERE SCHEMA_NAME = 'my_test'; + + +--echo # +--echo # 4) Check table status +--echo # +ANALYZE TABLE t1, t2; + +--let $new_t1_data_length = query_get_value(SELECT DATA_LENGTH FROM information_schema.tables WHERE TABLE_NAME = "t1", DATA_LENGTH, 1) +--let $new_t2_data_length = query_get_value(SELECT DATA_LENGTH FROM information_schema.tables WHERE TABLE_NAME = "t2", DATA_LENGTH, 1) + +--let $assert_text = table status of new t1 is equal to original t2 +--let $assert_cond = $new_t1_data_length = $t2_data_length +--source include/assert.inc + +--let $assert_text = table status of new_t2 is equal to original t1 +--let $assert_cond = $new_t2_data_length = $t1_data_length +--source include/assert.inc + + +--echo # +--echo # 5) Cleanup +--echo # +DROP DATABASE my_test; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 28bb81232c6..8141ddccf5e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -10770,7 +10770,9 @@ bool mysql_rename_table(THD *thd, handlerton *base, const char *old_db, supporting atomic DDL. And for engines which can't do atomic DDL in either case there are scenarios in which DD and SE get out of sync. */ - bool result = thd->dd_client()->update(to_table_def); + bool result = + thd->dd_client()->update(to_table_def) || + thd->dd_client()->remove_table_dynamic_statistics(old_db, old_name); /* Only rename histograms when this isn't a rename for temporary names -- 2.32.0.3.g01195cf9f