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

Unique index length is able to exceed max key length

Details

    Description

      It appears that unique indexes are able to exceed the max key length in some cases.

      For example, if we tried to add the following primary key, then it would fail:

      CREATE OR REPLACE TABLE tab (
        col1 smallint(6) DEFAULT NULL,
        col2 smallint(6) DEFAULT NULL,
        col3 bigint(20) DEFAULT NULL,
        col4 bigint(20) DEFAULT NULL,
        col5 varchar(64) DEFAULT NULL,
        col6 varchar(64) DEFAULT NULL,
        col7 varchar(128) DEFAULT NULL,
        col8 varchar(20) DEFAULT NULL,
        col9 varchar(128) DEFAULT NULL,
        col10 varchar(128) DEFAULT NULL,
        col11 varchar(2000) DEFAULT NULL,
        col12 double DEFAULT NULL,
        col13 double DEFAULT NULL,
        col14 double DEFAULT NULL,
        col15 double DEFAULT NULL,
        col16 tinyint(4) DEFAULT NULL,
        col17 double DEFAULT NULL,
        col18 double DEFAULT NULL,
        KEY col4_idx (col4)
      ) DEFAULT CHARACTER SET = utf8mb4;
      ALTER TABLE tab
         ADD PRIMARY KEY
         (col1, col2, col3, col4, col5, col6, col7, col8, col9, col10, col11);
      

      And for example, if we tried to add the following non-unique secondary index, then it would also fail:

      CREATE OR REPLACE TABLE tab (
        col1 smallint(6) DEFAULT NULL,
        col2 smallint(6) DEFAULT NULL,
        col3 bigint(20) DEFAULT NULL,
        col4 bigint(20) DEFAULT NULL,
        col5 varchar(64) DEFAULT NULL,
        col6 varchar(64) DEFAULT NULL,
        col7 varchar(128) DEFAULT NULL,
        col8 varchar(20) DEFAULT NULL,
        col9 varchar(128) DEFAULT NULL,
        col10 varchar(128) DEFAULT NULL,
        col11 varchar(2000) DEFAULT NULL,
        col12 double DEFAULT NULL,
        col13 double DEFAULT NULL,
        col14 double DEFAULT NULL,
        col15 double DEFAULT NULL,
        col16 tinyint(4) DEFAULT NULL,
        col17 double DEFAULT NULL,
        col18 double DEFAULT NULL,
        KEY col4_idx (col4)
      ) DEFAULT CHARACTER SET = utf8mb4;
      CREATE INDEX tab_idx
         ON tab
         (col1, col2, col3, col4, col5, col6, col7, col8, col9, col10, col11);
      

      We see the following error in both cases:

      ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes
      

      However, for some reason, if we tried to add the following unique index, then it would succeed:

      CREATE OR REPLACE TABLE tab (
        col1 smallint(6) DEFAULT NULL,
        col2 smallint(6) DEFAULT NULL,
        col3 bigint(20) DEFAULT NULL,
        col4 bigint(20) DEFAULT NULL,
        col5 varchar(64) DEFAULT NULL,
        col6 varchar(64) DEFAULT NULL,
        col7 varchar(128) DEFAULT NULL,
        col8 varchar(20) DEFAULT NULL,
        col9 varchar(128) DEFAULT NULL,
        col10 varchar(128) DEFAULT NULL,
        col11 varchar(2000) DEFAULT NULL,
        col12 double DEFAULT NULL,
        col13 double DEFAULT NULL,
        col14 double DEFAULT NULL,
        col15 double DEFAULT NULL,
        col16 tinyint(4) DEFAULT NULL,
        col17 double DEFAULT NULL,
        col18 double DEFAULT NULL,
        KEY col4_idx (col4)
      ) DEFAULT CHARACTER SET = utf8mb4;
      CREATE UNIQUE INDEX tab_unq_idx
         ON tab
         (col1, col2, col3, col4, col5, col6, col7, col8, col9, col10, col11);
      

      Is it intentional for the unique index to have a different max key length?

      Attachments

        Issue Links

          Activity

            This issue does not affect MariaDB 10.2.31 or MariaDB 10.3.22. It only seems to affect MariaDB 10.4.12.

            GeoffMontee Geoff Montee (Inactive) added a comment - This issue does not affect MariaDB 10.2.31 or MariaDB 10.3.22. It only seems to affect MariaDB 10.4.12.

            There should not be anything special about unique indexes in InnoDB. Even for non-leaf pages, PRIMARY KEY columns are included, as reported in
            MySQL Bug#68546 InnoDB stores PRIMARY KEY fields in unique secondary index non-leaf pages.
            I think that this should be investigated and addressed as part of MDEV-20194.
            I have provided some review comments related to fixing wrong maximum-size calculations.

            marko Marko Mäkelä added a comment - There should not be anything special about unique indexes in InnoDB. Even for non-leaf pages, PRIMARY KEY columns are included, as reported in MySQL Bug#68546 InnoDB stores PRIMARY KEY fields in unique secondary index non-leaf pages . I think that this should be investigated and addressed as part of MDEV-20194 . I have provided some review comments related to fixing wrong maximum-size calculations.
            serg Sergei Golubchik added a comment - MDEV-371 ?

            Yes, this is caused by MDEV-371. I verified it by executing the following query after creating the unique index:

            SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS WHERE NAME LIKE 'DB%';
            

            For the unique index, an index on a hidden virtual column DB_ROW_HASH_1 would be created instead.

            I do not think that there is anything that can be fixed in the storage engine, and I do not know if this can be treated as a bug at all. Maybe this should simply be treated as a documentation issue?

            marko Marko Mäkelä added a comment - Yes, this is caused by MDEV-371 . I verified it by executing the following query after creating the unique index: SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS WHERE NAME LIKE 'DB%' ; For the unique index, an index on a hidden virtual column DB_ROW_HASH_1 would be created instead. I do not think that there is anything that can be fixed in the storage engine, and I do not know if this can be treated as a bug at all. Maybe this should simply be treated as a documentation issue?

            Actually, to work around bugs related to MDEV-371 or indexed virtual columns (MDEV-5800), it might be useful to be able to disable the MDEV-371 logic on DDL, perhaps by an optimizer_switch or sql_mode, or by some magic comment in the DDL statement?

            marko Marko Mäkelä added a comment - Actually, to work around bugs related to MDEV-371 or indexed virtual columns ( MDEV-5800 ), it might be useful to be able to disable the MDEV-371 logic on DDL, perhaps by an optimizer_switch or sql_mode , or by some magic comment in the DDL statement?

            It's not a bug, MariaDB since 10.4 allows creating unique constraints of arbitrary length. A constraint is a logical object in the database and since 10.4 you can specify that "values in these columns should be unique" without thinking about implementation details and limitations of a particular storage engine.

            The second statement failing is a bug, though. Creating non-unique indexes should not fail with "key too long" — the server automatically shortens the index to fit. And for some reason this doesn't happen in your example.

            serg Sergei Golubchik added a comment - It's not a bug, MariaDB since 10.4 allows creating unique constraints of arbitrary length. A constraint is a logical object in the database and since 10.4 you can specify that "values in these columns should be unique" without thinking about implementation details and limitations of a particular storage engine. The second statement failing is a bug, though. Creating non-unique indexes should not fail with "key too long" — the server automatically shortens the index to fit. And for some reason this doesn't happen in your example.

            People

              sachin.setiya.007 Sachin Setiya (Inactive)
              GeoffMontee Geoff Montee (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              5 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.