[MDEV-21669] InnoDB: Table ... contains <n> indexes inside InnoDB, which is different from the number of indexes <n> defined in the MariaDB Created: 2020-02-05  Updated: 2020-02-13  Resolved: 2020-02-13

Status: Closed
Project: MariaDB Server
Component/s: Storage Engine - InnoDB
Affects Version/s: 10.4.7, 10.5.0, 10.5.1, 10.4.13
Fix Version/s: 10.4.13

Type: Bug Priority: Major
Reporter: Matthias Leich Assignee: Eugene Kosov (Inactive)
Resolution: Fixed Votes: 0
Labels: affects-tests


 Description   

10.4 commit d87b725eebbddb6d319ee99e51924a62635185a1
10.5 commit 42e825dd0a8d25c1d6fa93f5a07115ceed3ee0ff
builds with debug and without debug.
 
Snip of the protocol of my test run on 10.4
CREATE TABLE t1 ( col_int INTEGER, col_string CHAR(20), col_varchar VARCHAR(500) ) ENGINE = InnoDB ROW_FORMAT = Dynamic ;
ALTER TABLE t1 ADD KEY idx3 ( col_varchar(9) ), ADD KEY idX2 ( col_string(9) ) ;
ALTER TABLE t1 DROP KEY idx3, ADD KEY iDx2 ( col_varchar(9) ) ;
ERROR 42000: Duplicate key name 'iDx2'          <=========    There was never some index 'iDx2'  (uppercase D) created before. But maybe its just some case insensitive comparison of the names.
ALTER TABLE t1 DROP KEY iDx3, ADD KEY Idx3 ( col_varchar(9) ) ;
Warnings:
Warning 1082    InnoDB: Table test/t1 contains 2 indexes inside InnoDB, which is different from the number of indexes 2 defined in the MariaDB 
CHECK TABLE t1 EXTENDED ;
Table   Op      Msg_type        Msg_text
test.t1 check   status  OK
SHOW CREATE TABLE t1;
Table   Create Table
t1      CREATE TABLE `t1` (
  `col_int` int(11) DEFAULT NULL,
  `col_string` char(20) DEFAULT NULL,
  `col_varchar` varchar(500) DEFAULT NULL,
  KEY `idX2` (`col_string`(9)),                            
  KEY `Idx3` (`col_varchar`(9))                          <=====  The first character of the indexname is here upper case.
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
SELECT * FROM information_schema . INNODB_SYS_INDEXES WHERE table_id =
(SELECT table_id FROM information_schema . INNODB_SYS_TABLES WHERE Name = 'test/t1');
INDEX_ID        NAME    TABLE_ID        TYPE    N_FIELDS        PAGE_NO SPACE   MERGE_THRESHOLD
25      GEN_CLUST_INDEX 20      1       0       3       5       50
26      idx3    20      0       1       4       5       50          <=====  The first character of the indexname is here lower case.
28      idX2    20      0       1       6       5       50
DROP TABLE t1;
main.ml_weg6 'innodb'                    [ fail ]  Found warnings/errors in server log file!
        Test ended at 2020-02-05 13:25:40
line
2020-02-05 13:25:39 9 [ERROR] Cannot find index Idx3 in InnoDB index dictionary.
2020-02-05 13:25:39 9 [ERROR] InnoDB indexes are inconsistent with what defined in .frm for table ./test/t1
2020-02-05 13:25:39 9 [ERROR] InnoDB could not find key no 1 with name Idx3 from dict cache for table test/t1
2020-02-05 13:25:39 9 [ERROR] InnoDB: Table test/t1 contains 2 indexes inside InnoDB, which is different from the number of indexes 2 defined in the MariaDB 
 
Snip of the protocol of my test run on 10.5 
CREATE TABLE t1 ( col_int INTEGER, col_string CHAR(20), col_varchar VARCHAR(500) ) ENGINE = InnoDB ROW_FORMAT = Dynamic ;
ALTER TABLE t1 ADD KEY idx3 ( col_varchar(9) ), ADD KEY idX2 ( col_string(9) ) ;
ALTER TABLE t1 DROP KEY idx3, ADD KEY iDx2 ( col_varchar(9) ) ;
ERROR 42000: Duplicate key name 'iDx2'
ALTER TABLE t1 DROP KEY iDx3, ADD KEY Idx3 ( col_varchar(9) ) ;
CHECK TABLE t1 EXTENDED ;
Table   Op      Msg_type        Msg_text
test.t1 check   Warning InnoDB: Table test/t1 contains 2 indexes inside InnoDB, which is different from the number of indexes 2 defined in the MariaDB 
test.t1 check   status  OK
SHOW CREATE TABLE t1;
Table   Create Table
t1      CREATE TABLE `t1` (
  `col_int` int(11) DEFAULT NULL,
  `col_string` char(20) DEFAULT NULL,
  `col_varchar` varchar(500) DEFAULT NULL,
  KEY `idX2` (`col_string`(9)),
  KEY `Idx3` (`col_varchar`(9))                      <=====  The first character of the indexname is here upper case.
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
SELECT * FROM information_schema . INNODB_SYS_INDEXES WHERE table_id =
(SELECT table_id FROM information_schema . INNODB_SYS_TABLES WHERE Name = 'test/t1');
INDEX_ID        NAME    TABLE_ID        TYPE    N_FIELDS        PAGE_NO SPACE   MERGE_THRESHOLD
25      GEN_CLUST_INDEX 20      1       0       3       5       50
26      idx3    20      0       1       4       5       50     <=====  The first character of the indexname is here lower case.
28      idX2    20      0       1       6       5       50
CHECK TABLE t1 EXTENDED ;
Table   Op      Msg_type        Msg_text
test.t1 check   status  OK
DROP TABLE t1;
main.ml_weg6a 'innodb'                   [ fail ]  Found warnings/errors in server log file!
        Test ended at 2020-02-05 13:32:03
line
2020-02-05 13:32:03 4 [ERROR] Cannot find index Idx3 in InnoDB index dictionary.
2020-02-05 13:32:03 4 [ERROR] InnoDB indexes are inconsistent with what defined in .frm for table ./test/t1
2020-02-05 13:32:03 4 [ERROR] InnoDB could not find key no 1 with name Idx3 from dict cache for table test/t1
2020-02-05 13:32:03 4 [ERROR] InnoDB: Table test/t1 contains 2 indexes inside InnoDB, which is different from the number of indexes 2 defined in the MariaDB
 
Whereas the results on 10.4 and 10.5 look quite similar there is some interesting difference
10.4 ALTER TABLE t1 DROP KEY iDx3, ADD KEY Idx3 ( col_varchar(9) ) ;      harvests the warning
10.5 The CHECK TABLE t1 EXTENDED after that ALTER harvests the warning.
 
Other strange effect (observed in 10.5)
In case I replace the
         ALTER TABLE t1 ADD KEY idx3 ( col_varchar(9) ), ADD KEY idX2 ( col_string(9) ) ;
by
        ALTER TABLE t1 ADD KEY idx3 ( col_varchar(9) ), ADD KEY idX2 ( col_string ) ;
than the warnings disappears.



 Comments   
Comment by Matthias Leich [ 2020-02-05 ]

I am sure that my MTR based test could be further shrinked.
Per my impression the problem is probably around

  • case sensitive/insensitive names of keys
  • In case we already have some key `X` defined on <spec 1>
    should it be allowed to create some key `Y` defined on <spec 1> too
Comment by Marko Mäkelä [ 2020-02-05 ]

This bug is caused by a refactoring in MariaDB 10.4.7. I used the following test case (which I did not clean up fully):

--source include/have_innodb.inc
 
CREATE TABLE t1 ( col_int INTEGER, col_string CHAR(20), col_varchar VARCHAR(500) ) ENGINE = InnoDB ROW_FORMAT = Dynamic ;
 
ALTER TABLE t1 ADD KEY idx3 ( col_varchar(9) ), ADD KEY idX2 ( col_string(9) ) ;
--error ER_DUP_KEYNAME
ALTER TABLE t1 DROP KEY idx3, ADD KEY iDx2 ( col_varchar(9) ) ;
ALTER TABLE t1 DROP KEY iDx3, ADD KEY Idx3 ( col_varchar(9) ) ;
CHECK TABLE t1 EXTENDED ;
DROP TABLE t1;

Comment by Matthias Leich [ 2020-02-12 ]

Results of RQG testing on actual 10.4 + commit cc5c574c0c026556c5930be4a046a551d7610af5:

  • No replay of the current bug
  • Other bad effects observed are already known and not more frequent than in actual 10.4 or 10.5
Generated at Thu Feb 08 09:08:54 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.