Skip to content

Commit 0e1ba36

Browse files
committed
MDEV-19916 Corruption after instant ADD/DROP and shrinking the tree
btr_lift_page_up(): Correct the incorrect condition. page_validate(): Validate the page type.
1 parent 92bbf4f commit 0e1ba36

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

mysql-test/suite/innodb/r/instant_alter_debug.result

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,4 +236,31 @@ a b c d
236236
1 2 NULL 1
237237
2 3 4 1
238238
DROP TABLE t1;
239+
#
240+
# MDEV-19916 Corruption after instant ADD/DROP and shrinking the tree
241+
#
242+
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
243+
SET @old_limit = @@innodb_limit_optimistic_insert_debug;
244+
SET GLOBAL innodb_limit_optimistic_insert_debug = 2;
245+
INSERT INTO t1 VALUES (1),(5),(4),(3),(2);
246+
SET GLOBAL innodb_limit_optimistic_insert_debug = @old_limit;
247+
ALTER TABLE t1 ADD COLUMN b INT, ALGORITHM=INSTANT;
248+
SET @old_defragment = @@innodb_defragment;
249+
SET GLOBAL innodb_defragment = 1;
250+
OPTIMIZE TABLE t1;
251+
Table Op Msg_type Msg_text
252+
test.t1 optimize status OK
253+
SET GLOBAL innodb_defragment = @old_defragment;
254+
ALTER TABLE t1 ADD vb INT AS (b) VIRTUAL;
255+
CHECK TABLE t1;
256+
Table Op Msg_type Msg_text
257+
test.t1 check status OK
258+
SELECT * FROM t1;
259+
a b vb
260+
1 NULL NULL
261+
2 NULL NULL
262+
3 NULL NULL
263+
4 NULL NULL
264+
5 NULL NULL
265+
DROP TABLE t1;
239266
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;

mysql-test/suite/innodb/t/instant_alter_debug.test

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,4 +267,29 @@ SET DEBUG_SYNC = RESET;
267267
SELECT * FROM t1;
268268
DROP TABLE t1;
269269

270+
--echo #
271+
--echo # MDEV-19916 Corruption after instant ADD/DROP and shrinking the tree
272+
--echo #
273+
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
274+
275+
# Create an index tree with 2 levels of node pointer pages.
276+
277+
SET @old_limit = @@innodb_limit_optimistic_insert_debug;
278+
SET GLOBAL innodb_limit_optimistic_insert_debug = 2;
279+
INSERT INTO t1 VALUES (1),(5),(4),(3),(2);
280+
SET GLOBAL innodb_limit_optimistic_insert_debug = @old_limit;
281+
282+
ALTER TABLE t1 ADD COLUMN b INT, ALGORITHM=INSTANT;
283+
284+
SET @old_defragment = @@innodb_defragment;
285+
SET GLOBAL innodb_defragment = 1;
286+
OPTIMIZE TABLE t1;
287+
SET GLOBAL innodb_defragment = @old_defragment;
288+
289+
# Exploit MDEV-17468 to force the table definition to be reloaded
290+
ALTER TABLE t1 ADD vb INT AS (b) VIRTUAL;
291+
CHECK TABLE t1;
292+
SELECT * FROM t1;
293+
DROP TABLE t1;
294+
270295
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;

storage/innobase/btr/btr0btr.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3453,7 +3453,8 @@ btr_lift_page_up(
34533453
/* btr_page_empty() is supposed to zero-initialize the field. */
34543454
ut_ad(!page_get_instant(father_block->frame));
34553455

3456-
if (page_level == 0 && index->is_instant()) {
3456+
if (index->is_instant()
3457+
&& father_block->page.id.page_no() == root_page_no) {
34573458
ut_ad(!father_page_zip);
34583459
byte* page_type = father_block->frame + FIL_PAGE_TYPE;
34593460
ut_ad(mach_read_from_2(page_type) == FIL_PAGE_INDEX);

0 commit comments

Comments
 (0)