[MDEV-25950] InnoDB: Ignoring strange row from mysql.innodb_index_stats after valid DDL. Created: 2021-06-17  Updated: 2021-06-22  Resolved: 2021-06-22

Status: Closed
Project: MariaDB Server
Component/s: Storage Engine - InnoDB
Affects Version/s: 10.6.2
Fix Version/s: 10.6.3

Type: Bug Priority: Major
Reporter: Matthias Leich Assignee: Marko Mäkelä
Resolution: Fixed Votes: 0
Labels: affects-tests, rr-profile

Attachments: File info_to_fatal.diff     File strange_row.opt     File strange_row.test    
Issue Links:
Problem/Incident
is caused by MDEV-25506 Atomic DDL: .frm file is removed and ... Closed

 Description   

TEST                                      RESULT   TIME (ms) or COMMENT
--------------------------------------------------------------------------
 
worker[1] Using MTR_BUILD_THREAD 300, with reserved ports 16000..16019
CREATE TABLE t1 ( col1 INTEGER, col2 INTEGER ) ENGINE = InnoDB;
ALTER TABLE t1 ADD PRIMARY KEY ( col2, col1 ) ;
ALTER TABLE t1 DROP PRIMARY KEY, ADD INDEX ( col2, col1 ) ;
ALTER TABLE t1 ADD PRIMARY KEY ( col2, col1 ) ;
ALTER TABLE t1 ADD PRIMARY KEY ( col2, col1 ) ;
main.strange_row 'innodb'                [ fail ]
        Test ended at 2021-06-17 12:30:27
 
CURRENT_TEST: main.strange_row
mysqltest: At line 8: query 'ALTER TABLE t1 ADD PRIMARY KEY ( col2, col1 ) ' failed: <Unknown> (2013): Lost connection to server during query
     The crash is caused by changing ib::info to ib::fatal in storage/innobase/dict/dict0stats.cc.
 
The server error log shows
2021-06-17 12:30:25 0 [Note] /data/Server_bin/bb-10.6-MDEV-25062H_asan/bin/mariadbd: ready for connections.
Version: '10.6.2-MariaDB-debug-log'  socket: '/data/Server_bin/bb-10.6-MDEV-25062H_asan/mysql-test/var/tmp/mysqld.1.sock'  port: 16000  Source distribution
2021-06-17 12:30:26 4 [ERROR] [FATAL] InnoDB: Ignoring strange row from mysql.innodb_index_stats WHERE database_name = 'test' AND table_name = 't1' AND index_name = 'col2' AND stat_name = 'n_diff_pfx03'; because stat_name is out of range, the index has 2 unique columns
 
bb-10.6-MDEV-25062 commit 3fdd9844f3567f58f60693e4fa8979fa3fefe929
origin/10.6 commit f778a5d5e2aaff7c58000f9e2423a809db14747c



 Comments   
Comment by Matthias Leich [ 2021-06-17 ]

pluto:/data/Results/1623929030/strange_row/dev/shm/vardir/1623929030/18/1/rr
rr trace generated by running a simplified RQG test revealing the problem above.

Comment by Marko Mäkelä [ 2021-06-22 ]

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).

Comment by Marko Mäkelä [ 2021-06-22 ]

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().

Comment by Marko Mäkelä [ 2021-06-22 ]

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.

Generated at Thu Feb 08 09:41:37 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.