Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-32190

Index corruption with unique key and nopad collation (without DESC or HASH keys)

Details

    Description

      --source include/have_innodb.inc
       
      CREATE TABLE t (id INT, b TEXT, KEY(id), PRIMARY KEY (b(2),id)) ENGINE=InnoDB COLLATE utf8mb3_general_nopad_ci;
       
      INSERT INTO t VALUES
       (1,''),(2,'x'),(3,'x'),(4,UNHEX('0010')),(5,'x'),(6,'x'),(7,'x'),(8,'x'),
       (9,UNHEX('00')),(10,'x'),(11,''),(12,UNHEX('73')),(13,'+'),(14,'N');
       
      CHECK TABLE t EXTENDED;
      SELECT id FROM t WHERE id IN (4,8);
       
      # Cleanup
      DROP TABLE t;
      

      10.5 cf816263

      CHECK TABLE t EXTENDED;
      Table	Op	Msg_type	Msg_text
      test.t	check	Warning	InnoDB: Index 'id' contains 14 entries, should be 13.
      test.t	check	error	Corrupt
       
      mysqltest: At line 10: query 'SELECT id FROM t WHERE id IN (4,8)' failed: 1712: Index t is corrupted
      

      2023-09-17 19:42:51 4 [ERROR] InnoDB: Flagged corruption of `id` in table `test`.`t` in CHECK TABLE; Wrong count
      2023-09-17 19:42:51 4 [ERROR] Got error 128 when reading table './test/t'
      

      10.6 0f870914

      CHECK TABLE t EXTENDED;
      Table	Op	Msg_type	Msg_text
      test.t	check	Warning	InnoDB: Clustered index record not found for index `id` of table `test`.`t`: COMPACT RECORD(info_bits=0, 2 fields): {[4]    (0x80000004),[2]  (0x0010)}
      test.t	check	Warning	InnoDB: Clustered index record not found for index `id` of table `test`.`t`: COMPACT RECORD(info_bits=0, 2 fields): {[4]    (0x80000009),[1] (0x00)}
      test.t	check	Warning	InnoDB: The B-tree of index id is corrupted.
      test.t	check	Warning	InnoDB: Index 'id' contains 12 entries, should be 14.
      test.t	check	error	Corrupt
       
      mysqltest: At line 10: query 'SELECT id FROM t WHERE id IN (4,8)' failed: ER_INDEX_CORRUPT (1712): Index t is corrupted
       
      Warnings from just before the error:
      Warning 180 InnoDB: Index id for table `test`.`t` is marked as corrupted 
      Error 1712 Index t is corrupted
      

      2023-09-17 19:45:03 4 [ERROR] InnoDB: Clustered index record not found for index `id` of table `test`.`t`: COMPACT RECORD(info_bits=0, 2 fields): {[4]    (0x80000004),[2]  (0x0010)}
      2023-09-17 19:45:03 4 [ERROR] InnoDB: Clustered index record not found for index `id` of table `test`.`t`: COMPACT RECORD(info_bits=0, 2 fields): {[4]    (0x80000009),[1] (0x00)}
      2023-09-17 19:45:03 4 [ERROR] InnoDB: Flagged corruption of `id` in table `test`.`t` in CHECK TABLE-check index
      2023-09-17 19:45:03 4 [ERROR] Got error 128 when reading table './test/t'
      

      Or without CHECK:

      2023-09-17 19:46:17 4 [ERROR] InnoDB: Clustered record for sec rec not found index `id` of table `test`.`t`
      InnoDB: sec index record PHYSICAL RECORD: n_fields 2; compact format; info bits 0
       0: len 4; hex 80000004; asc     ;;
       1: len 2; hex 0010; asc   ;;
       
      InnoDB: clust index record PHYSICAL RECORD: n_fields 5; compact format; info bits 0
       0: len 0; hex ; asc ;;
       1: len 4; hex 80000001; asc     ;;
       2: len 6; hex 000000000014; asc       ;;
       3: len 7; hex 83000001350322; asc     5 ";;
       4: len 0; hex ; asc ;;
      2023-09-17 19:46:17 4 [ERROR] InnoDB: We detected index corruption in an InnoDB type table. You have to dump + drop + reimport the table or, in a case of widespread corruption, dump all InnoDB tables and recreate the whole tablespace. If the mariadbd server crashes after the startup or when you dump the tables. Please refer to https://mariadb.com/kb/en/library/innodb-recovery-modes/ for information about forcing recovery.
      2023-09-17 19:46:17 4 [ERROR] mariadbd: Index for table 't' is corrupt; try to repair it
      2023-09-17 19:46:17 4 [ERROR] mariadbd: Index for table 't' is corrupt; try to repair it
      

      Attachments

        Issue Links

          Activity

            Assigned to InnoDB by tradition, even though it will be likely reassigned to the core. I think there were previous nopad-related issues with the explanation why they aren't an InnoDB problem, but I can't find them.

            elenst Elena Stepanova added a comment - Assigned to InnoDB by tradition, even though it will be likely reassigned to the core. I think there were previous nopad-related issues with the explanation why they aren't an InnoDB problem, but I can't find them.

            This looks like a simpler version of the test case in MDEV-28328, with a shorter column prefix in the PRIMARY KEY, and using a different NOPAD collation.

            marko Marko Mäkelä added a comment - This looks like a simpler version of the test case in MDEV-28328 , with a shorter column prefix in the PRIMARY KEY , and using a different NOPAD collation.

            Thanks, that's the one (or one of) I was thinking of but couldn't find.

            elenst Elena Stepanova added a comment - Thanks, that's the one (or one of) I was thinking of but couldn't find.

            I debugged the test case in 10.6 0f870914d410e8a34ea99b1e0ea7eb71094606f9. At the time row_check_index()} reports the error, both the secondary index and the clustered index comprise of a single page each, each of them containing 14 records.

            The format of the secondary index records (page 4) is (id,b(2)). The records are exactly like in the INSERT statement, in the same order, and using the same length of b(2).

            The format of the clustered index records (page 3) is (b(2),id,DB_TRX_ID,DB_ROLL_PTR,b). All records carry DB_TRX_ID=0x14 and a DB_ROLL_PTR whose most significant bit is set, denoting a fresh insert. They could also be DB_TRX_ID=0, DB_ROLL_PTR=1<<55 in case the purge of committed history had been completed.

            In the clustered index, the order of records starts as follows:
            (b(2),id)=('',1),(unhex(00),9),(unhex(0010),4),('',11).

            It looks wrong to me that the empty string is not being sorted consistently.

            marko Marko Mäkelä added a comment - I debugged the test case in 10.6 0f870914d410e8a34ea99b1e0ea7eb71094606f9. At the time row_check_index() } reports the error, both the secondary index and the clustered index comprise of a single page each, each of them containing 14 records. The format of the secondary index records (page 4) is (id,b(2)). The records are exactly like in the INSERT statement, in the same order, and using the same length of b(2). The format of the clustered index records (page 3) is (b(2),id,DB_TRX_ID,DB_ROLL_PTR,b). All records carry DB_TRX_ID=0x14 and a DB_ROLL_PTR whose most significant bit is set, denoting a fresh insert. They could also be DB_TRX_ID=0, DB_ROLL_PTR=1<<55 in case the purge of committed history had been completed. In the clustered index, the order of records starts as follows: (b(2),id)=('',1),(unhex(00),9),(unhex(0010),4),('',11). It looks wrong to me that the empty string is not being sorted consistently.

            People

              bar Alexander Barkov
              elenst Elena Stepanova
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.