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

Table cannot be loaded after instant ADD/DROP COLUMN

    XMLWordPrintable

    Details

      Description

      For a table with a variable-length encoded CHAR column in the PRIMARY KEY, the table cannot be loaded to the InnoDB data dictionary cache after instant DROP or reordering of columns (MDEV-15562):

      --source include/have_innodb.inc
      create table t(a char(5) character set utf8 primary key) engine=innodb;
      alter table t add b int first;
      --let $shutdown_timeout=0;
      --source include/restart_mysqld.inc
      check table t;
      drop table t;
      

      This will result in the following errors:

      10.5 a9846f329935faba560387bab8fd897102e17385

      check table t;
      Table	Op	Msg_type	Msg_text
      test.t	check	Error	Table 'test.t' doesn't exist in engine
      test.t	check	status	Operation failed
      drop table t;
      Warnings:
      Warning	1932	Table 'test.t' doesn't exist in engine
      innodb.ia 'innodb'                       [ fail ]  Found warnings/errors in server log file!
              Test ended at 2019-11-19 21:00:04
      line
      2019-11-19 21:00:04 0 [ERROR] InnoDB: Table `test`.`t` contains unrecognizable instant ALTER metadata
      2019-11-19 21:00:04 3 [ERROR] InnoDB: Table `test`.`t` contains unrecognizable instant ALTER metadata
      2019-11-19 21:00:04 3 [ERROR] InnoDB: Table `test`.`t` contains unrecognizable instant ALTER metadata
      2019-11-19 21:00:04 3 [ERROR] InnoDB: Table `test`.`t` does not exist in the InnoDB internal data dictionary though MariaDB is trying to drop it. Have you copied the .frm file of the table to the MariaDB database directory from another database? Please refer to https://mariadb.com/kb/en/innodb-troubleshooting/ for how to resolve the issue.
      

      The cause is that for the metadata record, we are unnecessarily writing a nonempty dummy value for the PRIMARY KEY column, even though it uses variable-length encoding. This breaks the following assumption in btr_cur_instant_init_low():

      		if (!trx_id_offset) {
      			/* The PRIMARY KEY contains variable-length columns.
      			For the metadata record, variable-length columns are
      			always written with zero length. The DB_TRX_ID will
      			start right after any fixed-length columns. */
      			for (uint i = index->n_uniq; i--; ) {
      				trx_id_offset += index->fields[i].fixed_len;
      			}
      		}
      

      The CHAR(5) column uses a variable-length encoding in ROW_FORMAT≠REDUNDANT, occupying 5*mbminlen‥5*mbmaxlen bytes (in this case, repeat(' ',5)).

      We should both stop allocating the unnecessary bytes, and adjust the above code so that the suboptimal metadata records can be parsed.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              marko Marko Mäkelä
              Reporter:
              marko Marko Mäkelä
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: