Skip to content

Commit 05f9fd3

Browse files
MDEV-37192 Crash recovery reports corrupiton after bulk load
Problem: ======= - InnoDB modifies the PAGE_ROOT_AUTO_INC value on clustered index root page. But before committing the PAGE_ROOT_AUTO_INC changes mini-transaction, InnoDB does bulk insert operation and calculates the page checksum and store as a part of redo log in mini-transaction. During recovery, InnoDB fails to validate the page checksum. Solution: ======== - Avoid writing the persistent auto increment value before doing bulk insert operation. - For bulk insert operation, persistent auto increment value is written via btr_write_autoinc while applying the buffered insert operation.
1 parent c4b76b9 commit 05f9fd3

File tree

3 files changed

+33
-7
lines changed

3 files changed

+33
-7
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ CREATE TABLE t1(f1 INT NOT NULL,f2 INT NOT NULL)ENGINE=InnoDB;
22
INSERT INTO t1 SELECT seq, seq from seq_1_to_131072;
33
INSERT INTO t1 VALUES(131073, 131073), (131074, 131073);
44
SELECT * INTO OUTFILE "VARDIR/tmp/t1.outfile" FROM t1;
5+
SELECT * INTO OUTFILE "VARDIR/tmp/t.outfile" FROM t1 LIMIT 1;
56
# successful load statement using bulk insert
67
CREATE TABLE t2(f1 INT NOT NULL PRIMARY KEY,
78
f2 INT NOT NULL)ENGINE=InnoDB;
@@ -48,3 +49,12 @@ CHECK TABLE t2 EXTENDED;
4849
Table Op Msg_type Msg_text
4950
test.t2 check status OK
5051
DROP TABLE t2, t1;
52+
#
53+
# MDEV-37192 Crash recovery reports corruption after bulk load
54+
#
55+
CREATE TABLE t2(f1 INT AUTO_INCREMENT, f2 INT NOT NULL,
56+
PRIMARY KEY(f1))ENGINE=InnoDB;
57+
BEGIN;
58+
LOAD DATA INFILE 'VARDIR/tmp/t.outfile' INTO TABLE t2;
59+
# restart
60+
DROP TABLE t2;

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
--source include/have_innodb.inc
22
--source include/have_sequence.inc
33
--source include/big_test.inc
4+
--source include/not_embedded.inc
45

56
CREATE TABLE t1(f1 INT NOT NULL,f2 INT NOT NULL)ENGINE=InnoDB;
67
INSERT INTO t1 SELECT seq, seq from seq_1_to_131072;
@@ -9,6 +10,8 @@ INSERT INTO t1 VALUES(131073, 131073), (131074, 131073);
910
--disable_cursor_protocol
1011
--disable_ps2_protocol
1112
eval SELECT * INTO OUTFILE "$MYSQLTEST_VARDIR/tmp/t1.outfile" FROM t1;
13+
--replace_result $MYSQLTEST_VARDIR VARDIR
14+
eval SELECT * INTO OUTFILE "$MYSQLTEST_VARDIR/tmp/t.outfile" FROM t1 LIMIT 1;
1215
--enable_ps2_protocol
1316
--enable_cursor_protocol
1417

@@ -50,3 +53,16 @@ SELECT COUNT(*) FROM t2;
5053
CHECK TABLE t2 EXTENDED;
5154
--remove_file $MYSQLTEST_VARDIR/tmp/t1.outfile
5255
DROP TABLE t2, t1;
56+
57+
--echo #
58+
--echo # MDEV-37192 Crash recovery reports corruption after bulk load
59+
--echo #
60+
CREATE TABLE t2(f1 INT AUTO_INCREMENT, f2 INT NOT NULL,
61+
PRIMARY KEY(f1))ENGINE=InnoDB;
62+
BEGIN;
63+
--replace_result $MYSQLTEST_VARDIR VARDIR
64+
eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/t.outfile' INTO TABLE t2;
65+
--let $shutdown_timeout=0
66+
--source include/restart_mysqld.inc
67+
--remove_file $MYSQLTEST_VARDIR/tmp/t.outfile
68+
DROP TABLE t2;

storage/innobase/row/row0ins.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2729,13 +2729,6 @@ row_ins_clust_index_entry_low(
27292729
goto func_exit;
27302730
}
27312731

2732-
if (auto_inc) {
2733-
buf_block_t* root
2734-
= mtr.at_savepoint(mode != BTR_MODIFY_ROOT_AND_LEAF);
2735-
ut_ad(index->page == root->page.id().page_no());
2736-
page_set_autoinc(root, auto_inc, &mtr, false);
2737-
}
2738-
27392732
btr_pcur_get_btr_cur(&pcur)->thr = thr;
27402733

27412734
#ifdef UNIV_DEBUG
@@ -2854,6 +2847,13 @@ row_ins_clust_index_entry_low(
28542847
}
28552848

28562849
row_level_insert:
2850+
if (auto_inc) {
2851+
buf_block_t* root =
2852+
mtr.at_savepoint(mode != BTR_MODIFY_ROOT_AND_LEAF);
2853+
ut_ad(index->page == root->page.id().page_no());
2854+
page_set_autoinc(root, auto_inc, &mtr, false);
2855+
}
2856+
28572857
if (UNIV_UNLIKELY(entry->info_bits != 0)) {
28582858
const rec_t* rec = btr_pcur_get_rec(&pcur);
28592859

0 commit comments

Comments
 (0)