Browse Source
MDEV-35163 InnoDB persistent statistics fail to update after ALTER TABLE...ALGORITHM=COPY
MDEV-35163 InnoDB persistent statistics fail to update after ALTER TABLE...ALGORITHM=COPY
Problem: ======= - InnoDB statistics calculation for the table is done after every 10 seconds by default in background thread dict_stats_thread() - Doing multiple ALTER TABLE..ALGORITHM=COPY causes the dict_stats_thread() to lag behind, therefore calculation of stats for newly created intermediate table gets delayed Fix: ==== - Stats calculation for newly created intermediate table is made independent of background thread. After copying gets completed, stats for new table is calculated as part of ALTER TABLE ... ALGORITHM=COPY. dict_stats_rename_table(): Rename the table statistics from intermediate table to new table alter_stats_rebuild(): Removes the table name from the warning. Because this warning can print for intermediate table as well. Alter table using copy algorithm now calls alter_stats_rebuild() under a shared MDL lock on a temporary #sql-alter- table, differing from its previous use only during ALGORITHM=INPLACE operations on user-visible tables. dict_stats_schema_check(): Added a separate check for table readability before checking for tablespace existence. This could lead to detect of existence of persistent statistics storage eariler and fallback to transient statistics. This is a cherry-pick fix of mysql commit@cfe5f287ae99d004e8532a30003a7e8e77d379e3pull/4088/head
11 changed files with 257 additions and 60 deletions
-
105mysql-test/suite/innodb/r/alter_copy_stats.result
-
5mysql-test/suite/innodb/r/innodb-alter-debug.result
-
2mysql-test/suite/innodb/r/xap_release_locks_on_dict_stats_table.result
-
90mysql-test/suite/innodb/t/alter_copy_stats.test
-
2mysql-test/suite/innodb/t/innodb-alter-debug.test
-
2mysql-test/suite/innodb/t/xap_release_locks_on_dict_stats_table.test
-
3mysql-test/suite/innodb_fts/t/versioning.test
-
15storage/innobase/dict/dict0stats.cc
-
43storage/innobase/handler/ha_innodb.cc
-
7storage/innobase/handler/ha_innodb.h
-
43storage/innobase/handler/handler0alter.cc
@ -0,0 +1,105 @@ |
|||
CREATE TABLE t1 ( |
|||
c1 INT PRIMARY KEY, |
|||
c2 VARCHAR(50), |
|||
c3 VARCHAR(50), |
|||
c4 VARCHAR(50))ENGINE=InnoDB; |
|||
INSERT INTO t1 VALUES(1, 'AAA_2', 'AAA_3', 'AAA_4'), |
|||
(2, 'BBB_2', 'BBB_3', 'BBB_4'), |
|||
(3, 'CCC_2', 'CCC_3', 'CCC_4'), |
|||
(4, 'DDD_2', 'DDD_3', 'DDD_4'), |
|||
(5, 'EEE_2', 'EEE_3', 'EEE_4'); |
|||
ALTER TABLE t1 CONVERT TO CHARACTER SET 'utf8mb4',ALGORITHM=COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); |
|||
n_rows database_name lower(table_name) |
|||
5 test t1 |
|||
ALTER TABLE t1 ADD COLUMN c5 VARCHAR(15), ALGORITHM = COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); |
|||
n_rows database_name lower(table_name) |
|||
5 test t1 |
|||
ALTER TABLE t1 DROP COLUMN c5, ALGORITHM = COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); |
|||
n_rows database_name lower(table_name) |
|||
5 test t1 |
|||
ALTER TABLE t1 ADD COLUMN c5 VARCHAR(15), ALGORITHM = COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); |
|||
n_rows database_name lower(table_name) |
|||
5 test t1 |
|||
ALTER TABLE t1 DROP COLUMN c5, ALGORITHM = COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); |
|||
n_rows database_name lower(table_name) |
|||
5 test t1 |
|||
ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY (c4), ALGORITHM=COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); |
|||
n_rows database_name lower(table_name) |
|||
5 test t1 |
|||
ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY (c1), ALGORITHM = COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); |
|||
n_rows database_name lower(table_name) |
|||
5 test t1 |
|||
ALTER TABLE t1 ADD COLUMN c5 VARCHAR(15), ALGORITHM = INPLACE; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); |
|||
n_rows database_name lower(table_name) |
|||
5 test t1 |
|||
ALTER TABLE t1 DROP COLUMN c5, ALGORITHM = INPLACE; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); |
|||
n_rows database_name lower(table_name) |
|||
5 test t1 |
|||
CREATE TABLE t2 ( |
|||
c1 INT PRIMARY KEY, |
|||
c2 VARCHAR(50), |
|||
c3 VARCHAR(50), |
|||
c4 VARCHAR(50) |
|||
) ENGINE=InnoDB PARTITION BY RANGE (c1) ( |
|||
PARTITION p1 VALUES LESS THAN (6), |
|||
PARTITION p2 VALUES LESS THAN (11), |
|||
PARTITION p3 VALUES LESS THAN (16), |
|||
PARTITION p4 VALUES LESS THAN (21) |
|||
); |
|||
INSERT INTO t2 VALUES(1, 'AAA_2', 'AAA_3', 'AAA_4'), |
|||
(2, 'BBB_2', 'BBB_3', 'BBB_4'), |
|||
(3, 'CCC_2', 'CCC_3', 'CCC_4'), |
|||
(4, 'DDD_2', 'DDD_3', 'DDD_4'), |
|||
(5, 'EEE_2', 'EEE_3', 'EEE_4'), |
|||
(6, 'FFF_2', 'DDD_3', 'DDD_4'), |
|||
(7, 'GGG_2', 'DDD_3', 'DDD_4'), |
|||
(8, 'HHH_2', 'DDD_3', 'DDD_4'), |
|||
(9, 'III_2', 'DDD_3', 'DDD_4'), |
|||
(10, 'JJJ_2', 'DDD_3', 'DDD_4'), |
|||
(13, 'KKK_2', 'DDD_3', 'DDD_4'), |
|||
(20, 'LLL_2', 'DDD_3', 'DDD_4'); |
|||
ALTER TABLE t2 CONVERT TO CHARACTER SET 'utf8mb4',ALGORITHM=COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name LIKE '%t2%'; |
|||
n_rows database_name lower(table_name) |
|||
5 test t2#p#p1 |
|||
5 test t2#p#p2 |
|||
1 test t2#p#p3 |
|||
1 test t2#p#p4 |
|||
ALTER TABLE t2 ADD COLUMN c5 VARCHAR(15), ALGORITHM = COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name LIKE '%t2%'; |
|||
n_rows database_name lower(table_name) |
|||
5 test t2#p#p1 |
|||
5 test t2#p#p2 |
|||
1 test t2#p#p3 |
|||
1 test t2#p#p4 |
|||
ALTER TABLE t2 DROP COLUMN c5, ALGORITHM = COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name LIKE '%t2%'; |
|||
n_rows database_name lower(table_name) |
|||
5 test t2#p#p1 |
|||
5 test t2#p#p2 |
|||
1 test t2#p#p3 |
|||
1 test t2#p#p4 |
|||
# Test Cleanup. |
|||
DROP TABLE t1; |
|||
DROP TABLE t2; |
@ -0,0 +1,90 @@ |
|||
--source include/have_innodb.inc |
|||
--source include/have_partition.inc |
|||
|
|||
CREATE TABLE t1 ( |
|||
c1 INT PRIMARY KEY, |
|||
c2 VARCHAR(50), |
|||
c3 VARCHAR(50), |
|||
c4 VARCHAR(50))ENGINE=InnoDB; |
|||
|
|||
INSERT INTO t1 VALUES(1, 'AAA_2', 'AAA_3', 'AAA_4'), |
|||
(2, 'BBB_2', 'BBB_3', 'BBB_4'), |
|||
(3, 'CCC_2', 'CCC_3', 'CCC_4'), |
|||
(4, 'DDD_2', 'DDD_3', 'DDD_4'), |
|||
(5, 'EEE_2', 'EEE_3', 'EEE_4'); |
|||
|
|||
ALTER TABLE t1 CONVERT TO CHARACTER SET 'utf8mb4',ALGORITHM=COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); |
|||
|
|||
ALTER TABLE t1 ADD COLUMN c5 VARCHAR(15), ALGORITHM = COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); |
|||
|
|||
ALTER TABLE t1 DROP COLUMN c5, ALGORITHM = COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); |
|||
|
|||
ALTER TABLE t1 ADD COLUMN c5 VARCHAR(15), ALGORITHM = COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); |
|||
|
|||
ALTER TABLE t1 DROP COLUMN c5, ALGORITHM = COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); |
|||
|
|||
ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY (c4), ALGORITHM=COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); |
|||
|
|||
ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY (c1), ALGORITHM = COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); |
|||
|
|||
ALTER TABLE t1 ADD COLUMN c5 VARCHAR(15), ALGORITHM = INPLACE; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); |
|||
|
|||
ALTER TABLE t1 DROP COLUMN c5, ALGORITHM = INPLACE; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); |
|||
|
|||
CREATE TABLE t2 ( |
|||
c1 INT PRIMARY KEY, |
|||
c2 VARCHAR(50), |
|||
c3 VARCHAR(50), |
|||
c4 VARCHAR(50) |
|||
) ENGINE=InnoDB PARTITION BY RANGE (c1) ( |
|||
PARTITION p1 VALUES LESS THAN (6), |
|||
PARTITION p2 VALUES LESS THAN (11), |
|||
PARTITION p3 VALUES LESS THAN (16), |
|||
PARTITION p4 VALUES LESS THAN (21) |
|||
); |
|||
INSERT INTO t2 VALUES(1, 'AAA_2', 'AAA_3', 'AAA_4'), |
|||
(2, 'BBB_2', 'BBB_3', 'BBB_4'), |
|||
(3, 'CCC_2', 'CCC_3', 'CCC_4'), |
|||
(4, 'DDD_2', 'DDD_3', 'DDD_4'), |
|||
(5, 'EEE_2', 'EEE_3', 'EEE_4'), |
|||
(6, 'FFF_2', 'DDD_3', 'DDD_4'), |
|||
(7, 'GGG_2', 'DDD_3', 'DDD_4'), |
|||
(8, 'HHH_2', 'DDD_3', 'DDD_4'), |
|||
(9, 'III_2', 'DDD_3', 'DDD_4'), |
|||
(10, 'JJJ_2', 'DDD_3', 'DDD_4'), |
|||
(13, 'KKK_2', 'DDD_3', 'DDD_4'), |
|||
(20, 'LLL_2', 'DDD_3', 'DDD_4'); |
|||
|
|||
ALTER TABLE t2 CONVERT TO CHARACTER SET 'utf8mb4',ALGORITHM=COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name LIKE '%t2%'; |
|||
|
|||
ALTER TABLE t2 ADD COLUMN c5 VARCHAR(15), ALGORITHM = COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name LIKE '%t2%'; |
|||
|
|||
ALTER TABLE t2 DROP COLUMN c5, ALGORITHM = COPY; |
|||
SELECT n_rows, database_name, lower(table_name) |
|||
FROM mysql.innodb_table_stats WHERE table_name LIKE '%t2%'; |
|||
|
|||
--echo # Test Cleanup. |
|||
DROP TABLE t1; |
|||
DROP TABLE t2; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue