|
I think that we have a problem on table-rebuilding ALTER TABLE. The following patch demonstrates it:
diff --git a/mysql-test/suite/innodb/t/instant_alter_index_rename.test b/mysql-test/suite/innodb/t/instant_alter_index_rename.test
|
index af66c1027cc..0305a252748 100644
|
--- a/mysql-test/suite/innodb/t/instant_alter_index_rename.test
|
+++ b/mysql-test/suite/innodb/t/instant_alter_index_rename.test
|
@@ -225,5 +225,9 @@ ALTER TABLE t1 DROP INDEX ind2, ADD INDEX ind3(b),
|
|
SELECT table_name, index_name, stat_name FROM mysql.innodb_index_stats;
|
|
+ALTER TABLE t1 DROP b, FORCE;
|
+
|
+SELECT table_name, index_name, stat_name FROM mysql.innodb_index_stats;
|
+
|
UPDATE t1 SET a = 1 WHERE c = 'foo';
|
DROP TABLE t1;
|
With this patch applied, we will fail to drop the index ind3 that exists on the column c:
CURRENT_TEST: innodb.instant_alter_index_rename
|
--- /mariadb/10.6-merge/mysql-test/suite/innodb/r/instant_alter_index_rename.result 2021-06-21 12:18:31.402658955 +0300
|
+++ /mariadb/10.6-merge/mysql-test/suite/innodb/r/instant_alter_index_rename.reject 2021-06-22 16:17:17.753503407 +0300
|
@@ -232,5 +232,19 @@
|
t1 ind3 n_diff_pfx02
|
t1 ind3 n_leaf_pages
|
t1 ind3 size
|
+ALTER TABLE t1 DROP b, FORCE;
|
+SELECT table_name, index_name, stat_name FROM mysql.innodb_index_stats;
|
+table_name index_name stat_name
|
+t1 GEN_CLUST_INDEX n_diff_pfx01
|
+t1 GEN_CLUST_INDEX n_leaf_pages
|
+t1 GEN_CLUST_INDEX size
|
+t1 ind2 n_diff_pfx01
|
+t1 ind2 n_diff_pfx02
|
+t1 ind2 n_leaf_pages
|
+t1 ind2 size
|
+t1 ind3 n_diff_pfx01
|
+t1 ind3 n_diff_pfx02
|
+t1 ind3 n_leaf_pages
|
+t1 ind3 size
|
UPDATE t1 SET a = 1 WHERE c = 'foo';
|
DROP TABLE t1;
|
|
mysqltest: Result length mismatch
|
If the , FORCE is omitted from the input (to invoke MDEV-15562), then ind3 will be dropped like it should.
I think that this bug must have been caused by MDEV-25506 part 3, which included a rewrite of DROP operations, and making the dropping of statistics atomic with the rest of the table. We do attempt to drop statistics here, but for the wrong table (the #sql-ib one).
|
|
If the FORCE is replaced with ALGORITHM=COPY, then all statistics will be dropped. I think that we want to do exactly that also for FORCE, ALGORITHM=INPLACE. On instant DROP, we already do the right thing and only drop the affected index.
This requires a small fix in commit_try_rebuild().
|
|
I spent a long time debugging why even after my fix, with FORCE,ALGORITHM=INPLACE we would not lose all statistics. Finally, I found the reason: the statistics for the remaining indexes are being explicitly inserted:
#17 0x00005579b5333f1d in dict_stats_save (table_orig=table_orig@entry=0x7fa3bc0339e0, only_for_index=only_for_index@entry=0x0) at /mariadb/10.6-merge/storage/innobase/dict/dict0stats.cc:2838
|
#18 0x00005579b53364f8 in dict_stats_update (table=table@entry=0x7fa3bc0339e0, stats_upd_option=stats_upd_option@entry=DICT_STATS_RECALC_PERSISTENT)
|
at /mariadb/10.6-merge/storage/innobase/dict/dict0stats.cc:3471
|
#19 0x00005579b505110a in alter_stats_rebuild (table=0x7fa3bc0339e0, table_name=0x7fa3bc0201fd "t1", thd=0x7fa3bc001a38) at /mariadb/10.6-merge/storage/innobase/handler/handler0alter.cc:10654
|
#20 0x00005579b506cd6a in ha_innobase::commit_inplace_alter_table (this=<optimized out>, altered_table=<optimized out>, ha_alter_info=<optimized out>, commit=<optimized out>)
|
at /mariadb/10.6-merge/storage/innobase/handler/handler0alter.cc:11227
|
We also call dict_stats_update() on alter_stats_norebuild(), but not as part of an ALGORITHM=COPY operation.
|