Skip to content

Commit 5919f7b

Browse files
MDEV-31264 Purge trying to access freed secondary index page
- InnoDB purge tries to access aborted secondary index and access the freed secondary index root page.
1 parent e3b0615 commit 5919f7b

File tree

4 files changed

+71
-0
lines changed

4 files changed

+71
-0
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
CREATE TABLE t1(f1 INT, f2 INT, INDEX(f1))ENGINE=InnoDB
2+
PARTITION BY LIST(f1) (
3+
PARTITION p1 VALUES in (1, 2, 3),
4+
PARTITION p2 VALUES in (4, 5, 6));
5+
INSERT INTO t1 VALUES(1, 1), (1, 1), (6, 1);
6+
connect con1,localhost,root,,,;
7+
START TRANSACTION WITH CONSISTENT SNAPSHOT;
8+
connect con2,localhost,root,,,;
9+
SET DEBUG_SYNC="innodb_rollback_inplace_alter_table SIGNAL default_resume WAIT_FOR alter_resume";
10+
ALTER TABLE t1 ADD UNIQUE INDEX(f1);
11+
connection default;
12+
set DEBUG_SYNC="now WAIT_FOR default_resume";
13+
SET DEBUG_SYNC="innodb_row_update_for_mysql_begin SIGNAL alter_resume WAIT_FOR alter_finish";
14+
DELETE FROM t1;
15+
connection con2;
16+
ERROR 23000: Duplicate entry '1' for key 'f1_2'
17+
SET DEBUG_SYNC="now SIGNAL alter_finish";
18+
connection default;
19+
connection con1;
20+
commit;
21+
connection default;
22+
disconnect con1;
23+
disconnect con2;
24+
InnoDB 0 transactions not purged
25+
drop table t1;
26+
SET DEBUG_SYNC=reset;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--innodb_purge_threads=1
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
--source include/have_innodb.inc
2+
--source include/have_partition.inc
3+
--source include/have_debug.inc
4+
--source include/have_debug_sync.inc
5+
6+
CREATE TABLE t1(f1 INT, f2 INT, INDEX(f1))ENGINE=InnoDB
7+
PARTITION BY LIST(f1) (
8+
PARTITION p1 VALUES in (1, 2, 3),
9+
PARTITION p2 VALUES in (4, 5, 6));
10+
INSERT INTO t1 VALUES(1, 1), (1, 1), (6, 1);
11+
connect(con1,localhost,root,,,);
12+
START TRANSACTION WITH CONSISTENT SNAPSHOT;
13+
14+
connect(con2,localhost,root,,,);
15+
SET DEBUG_SYNC="innodb_rollback_inplace_alter_table SIGNAL default_resume WAIT_FOR alter_resume";
16+
send ALTER TABLE t1 ADD UNIQUE INDEX(f1);
17+
18+
connection default;
19+
set DEBUG_SYNC="now WAIT_FOR default_resume";
20+
SET DEBUG_SYNC="innodb_row_update_for_mysql_begin SIGNAL alter_resume WAIT_FOR alter_finish";
21+
send DELETE FROM t1;
22+
23+
connection con2;
24+
--error ER_DUP_ENTRY
25+
reap;
26+
SET DEBUG_SYNC="now SIGNAL alter_finish";
27+
28+
connection default;
29+
reap;
30+
connection con1;
31+
commit;
32+
connection default;
33+
disconnect con1;
34+
disconnect con2;
35+
--source ../../innodb/include/wait_all_purged.inc
36+
drop table t1;
37+
SET DEBUG_SYNC=reset;

storage/innobase/row/row0purge.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,8 @@ row_purge_del_mark(
615615
const auto type= node->index->type;
616616
if (type & (DICT_FTS | DICT_CORRUPT))
617617
continue;
618+
if (node->index->online_status > ONLINE_INDEX_CREATION)
619+
continue;
618620
if (UNIV_UNLIKELY(DICT_VIRTUAL & type) && !node->index->is_committed() &&
619621
node->index->has_new_v_col())
620622
continue;
@@ -767,6 +769,11 @@ row_purge_upd_exist_or_extern_func(
767769
continue;
768770
}
769771

772+
if (node->index->online_status
773+
> ONLINE_INDEX_CREATION) {
774+
continue;
775+
}
776+
770777
if (row_upd_changes_ord_field_binary(node->index, node->update,
771778
thr, NULL, NULL)) {
772779
/* Build the older version of the index entry */

0 commit comments

Comments
 (0)