[MDEV-21251] CHECK TABLE fails to check info_bits of records Created: 2019-12-09  Updated: 2020-10-06  Resolved: 2020-08-15

Status: Closed
Project: MariaDB Server
Component/s: Storage Engine - InnoDB
Affects Version/s: 5.5, 10.0, 10.1, 10.2, 10.3, 10.4, 10.5
Fix Version/s: 10.3.26, 10.4.16, 10.5.7

Type: Bug Priority: Critical
Reporter: Marko Mäkelä Assignee: Eugene Kosov (Inactive)
Resolution: Fixed Votes: 0
Labels: check, corruption

Issue Links:
Relates
relates to MDEV-22867 Assertion `instant.n_core_fields == n... Closed
relates to MDEV-19783 Random crashes and corrupt data in IN... Closed
relates to MDEV-19916 Corruption after instant ADD/DROP and... Closed

 Description   

CHECK TABLE fails to validate the info_bits of records. Specifically, if you run it on a table that was corrupted due to MDEV-19916, it would fail to notice that the leaf level of the clustered index starts with a record where the 'minimum record mark' of info_bits is set. This can be repeated by running a debug build of MariaDB 10.3.16 and earlier, and then upgrading to a newer non-debug build in the middle of the test:

--source include/have_innodb.inc
--source include/have_debug.inc
 
--echo #
--echo # MDEV-19916 Corruption after instant ADD/DROP and shrinking the tree
--echo #
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
 
# Create an index tree with 2 levels of node pointer pages.
 
SET @old_limit = @@innodb_limit_optimistic_insert_debug;
SET GLOBAL innodb_limit_optimistic_insert_debug = 2;
INSERT INTO t1 VALUES (1),(5),(4),(3),(2);
SET GLOBAL innodb_limit_optimistic_insert_debug = @old_limit;
 
ALTER TABLE t1 ADD COLUMN b INT, ALGORITHM=INSTANT;
 
SET GLOBAL innodb_defragment = 1;
OPTIMIZE TABLE t1;
--source include/restart_mysqld.inc
# restart with a newer MariaDB 10.3
CHECK TABLE t1;

Note: Please ignore debug assertion failures; we are interested in what the non-debug server does.



 Comments   
Comment by Marko Mäkelä [ 2019-12-09 ]

I believe that we should validate the info_bits of each record in the loop of btr_validate_level(). Only the very first record of a level may carry the ‘minimum record’ flag (0x10). That flag must be set on the first record if and only if !page_is_leaf() or index->is_instant().

The delete-mark flag (0x20) is garbage on non-leaf page records. On leaf-page records on 10.3, it must not be in the metadata record (for which the ‘minimum record’ flag is set).

No other info_bits than the two above mentioned 0x30 may ever be set on any record.

For ROW_FORMAT≠REDUNDANT, we should also validate the status_bits.

Comment by Marko Mäkelä [ 2020-06-12 ]

Related to this, tables that are in the MDEV-11369 format (instant ADD COLUMN) are supposed to be converted to the canonical format (no hidden metadata record) when the table is empied. However, the MDEV-22867 fix will change this: an emptied table will remain in the non-canonical format if a DROP COLUMN…, DROP INDEX operation is running at the same time. So, at least starting with 10.5, CHECK TABLE should tolerate an empty table that contains a MDEV-11369 hidden metadata record.

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