[MDEV-21088] Table cannot be loaded after instant ADD/DROP COLUMN Created: 2019-11-19  Updated: 2020-07-08  Resolved: 2019-11-20

Status: Closed
Project: MariaDB Server
Component/s: Storage Engine - InnoDB
Affects Version/s: 10.4.0
Fix Version/s: 10.3.21, 10.4.11

Type: Bug Priority: Critical
Reporter: Marko Mäkelä Assignee: Marko Mäkelä
Resolution: Fixed Votes: 0
Labels: corruption, instant

Issue Links:
Duplicate
duplicates MDEV-21230 Corrupt database with MariaDB 10.4.10... Closed
is duplicated by MDEV-21296 Data corruption after DROP COLUMN on ... Closed
Problem/Incident
is caused by MDEV-15562 Instant DROP COLUMN or changing the o... Closed
Relates
relates to MDEV-21148 mysqld: storage/innobase/btr/btr0cur.... Closed
relates to MDEV-21230 Corrupt database with MariaDB 10.4.10... Closed
relates to MDEV-23119 ERROR 1932 Table doesn't exist in engine Closed

 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.



 Comments   
Comment by Marko Mäkelä [ 2019-11-20 ]

The fix is twofold. In MariaDB 10.3, we can optimize innobase_add_instant_try() so that it avoids unnecessarily reserving space for variable-length-encoded CHAR columns in the metadata record. Tables subjected to instant ALTER TABLE with that fix should be readable by older versions of MariaDB 10.3 and 10.4.

In MariaDB 10.4, we must fix btr_cur_instant_init_low() so that it will decode the actual lengths of the PRIMARY KEY columns in the metadata record. This allows the ‘corrupted’ tables to be opened by MariaDB 10.4 that contains the fix.

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