Browse Source

MDEV-37183 Scrubbing empty record breaks recovery

page_delete_rec_list_end(): Do not attempt to scrub the data of
an empty record.

The test case would reproduce a debug assertion failure in branches
where commit 358921ce32 (MDEV-26938)
is present. MariaDB Server 10.6 only supports ascending indexes,
and in those, the empty string would always be sorted first, never
last in a page.

Nevertheless, we fix the bug also in 10.6, in case it would be
reproducible in a slightly different scenario.

Reviewed by: Thirunarayanan Balathandayuthapani
pull/4181/head
Marko Mäkelä 3 months ago
parent
commit
f73ffd1150
  1. 16
      mysql-test/suite/innodb/r/scrub_debug.result
  2. 15
      mysql-test/suite/innodb/t/scrub_debug.test
  3. 5
      storage/innobase/page/page0page.cc

16
mysql-test/suite/innodb/r/scrub_debug.result

@ -15,5 +15,21 @@ FLUSH TABLE t1 FOR EXPORT;
NOT FOUND /repairman/ in t1.ibd
UNLOCK TABLES;
DROP TABLE t1;
#
# MDEV-37183 innodb_immediate_scrub_data_uncompressed=ON may break
# crash recovery
#
SET GLOBAL innodb_limit_optimistic_insert_debug=0;
CREATE TABLE t(a VARCHAR(1) PRIMARY KEY,INDEX(a DESC)) ENGINE=InnoDB;
INSERT INTO t VALUES('2'),('1'),(''),('6'),('4'),('3');
SET GLOBAL innodb_limit_optimistic_insert_debug=3;
INSERT INTO t VALUES('8');
CHECK TABLE t;
Table Op Msg_type Msg_text
test.t check status OK
SELECT COUNT(*) FROM t;
COUNT(*)
7
DROP TABLE t;
SET GLOBAL INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG=@save_debug;
SET GLOBAL INNODB_IMMEDIATE_SCRUB_DATA_UNCOMPRESSED=@save_scrub;

15
mysql-test/suite/innodb/t/scrub_debug.test

@ -24,5 +24,20 @@ FLUSH TABLE t1 FOR EXPORT;
-- source include/search_pattern_in_file.inc
UNLOCK TABLES;
DROP TABLE t1;
--echo #
--echo # MDEV-37183 innodb_immediate_scrub_data_uncompressed=ON may break
--echo # crash recovery
--echo #
SET GLOBAL innodb_limit_optimistic_insert_debug=0;
# Note: MariaDB 10.6 fails to reproduce the crash; it maps DESC to ASC.
CREATE TABLE t(a VARCHAR(1) PRIMARY KEY,INDEX(a DESC)) ENGINE=InnoDB;
INSERT INTO t VALUES('2'),('1'),(''),('6'),('4'),('3');
SET GLOBAL innodb_limit_optimistic_insert_debug=3;
INSERT INTO t VALUES('8');
CHECK TABLE t;
SELECT COUNT(*) FROM t;
DROP TABLE t;
SET GLOBAL INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG=@save_debug;
SET GLOBAL INNODB_IMMEDIATE_SCRUB_DATA_UNCOMPRESSED=@save_scrub;

5
storage/innobase/page/page0page.cc

@ -977,8 +977,9 @@ page_delete_rec_list_end(
size+= s;
n_recs++;
if (scrub)
mtr->memset(block, rec2 - page, rec_offs_data_size(offsets), 0);
if (UNIV_LIKELY(!scrub));
else if (size_t size= rec_offs_data_size(offsets))
mtr->memset(block, rec2 - page, size, 0);
rec2= page_rec_get_next(rec2);
}

Loading…
Cancel
Save