Skip to content

Commit

Permalink
MDEV-31264 Purge trying to access freed secondary index page
Browse files Browse the repository at this point in the history
- InnoDB purge tries to access aborted secondary index and access
the freed secondary index root page.
  • Loading branch information
Thirunarayanan committed May 31, 2023
1 parent e3b0615 commit 5919f7b
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 0 deletions.
26 changes: 26 additions & 0 deletions mysql-test/suite/parts/r/partition_purge.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
CREATE TABLE t1(f1 INT, f2 INT, INDEX(f1))ENGINE=InnoDB
PARTITION BY LIST(f1) (
PARTITION p1 VALUES in (1, 2, 3),
PARTITION p2 VALUES in (4, 5, 6));
INSERT INTO t1 VALUES(1, 1), (1, 1), (6, 1);
connect con1,localhost,root,,,;
START TRANSACTION WITH CONSISTENT SNAPSHOT;
connect con2,localhost,root,,,;
SET DEBUG_SYNC="innodb_rollback_inplace_alter_table SIGNAL default_resume WAIT_FOR alter_resume";
ALTER TABLE t1 ADD UNIQUE INDEX(f1);
connection default;
set DEBUG_SYNC="now WAIT_FOR default_resume";
SET DEBUG_SYNC="innodb_row_update_for_mysql_begin SIGNAL alter_resume WAIT_FOR alter_finish";
DELETE FROM t1;
connection con2;
ERROR 23000: Duplicate entry '1' for key 'f1_2'
SET DEBUG_SYNC="now SIGNAL alter_finish";
connection default;
connection con1;
commit;
connection default;
disconnect con1;
disconnect con2;
InnoDB 0 transactions not purged
drop table t1;
SET DEBUG_SYNC=reset;
1 change: 1 addition & 0 deletions mysql-test/suite/parts/t/partition_purge.opt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--innodb_purge_threads=1
37 changes: 37 additions & 0 deletions mysql-test/suite/parts/t/partition_purge.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
--source include/have_innodb.inc
--source include/have_partition.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc

CREATE TABLE t1(f1 INT, f2 INT, INDEX(f1))ENGINE=InnoDB
PARTITION BY LIST(f1) (
PARTITION p1 VALUES in (1, 2, 3),
PARTITION p2 VALUES in (4, 5, 6));
INSERT INTO t1 VALUES(1, 1), (1, 1), (6, 1);
connect(con1,localhost,root,,,);
START TRANSACTION WITH CONSISTENT SNAPSHOT;

connect(con2,localhost,root,,,);
SET DEBUG_SYNC="innodb_rollback_inplace_alter_table SIGNAL default_resume WAIT_FOR alter_resume";
send ALTER TABLE t1 ADD UNIQUE INDEX(f1);

connection default;
set DEBUG_SYNC="now WAIT_FOR default_resume";
SET DEBUG_SYNC="innodb_row_update_for_mysql_begin SIGNAL alter_resume WAIT_FOR alter_finish";
send DELETE FROM t1;

connection con2;
--error ER_DUP_ENTRY
reap;
SET DEBUG_SYNC="now SIGNAL alter_finish";

connection default;
reap;
connection con1;
commit;
connection default;
disconnect con1;
disconnect con2;
--source ../../innodb/include/wait_all_purged.inc
drop table t1;
SET DEBUG_SYNC=reset;
7 changes: 7 additions & 0 deletions storage/innobase/row/row0purge.cc
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,8 @@ row_purge_del_mark(
const auto type= node->index->type;
if (type & (DICT_FTS | DICT_CORRUPT))
continue;
if (node->index->online_status > ONLINE_INDEX_CREATION)
continue;
if (UNIV_UNLIKELY(DICT_VIRTUAL & type) && !node->index->is_committed() &&
node->index->has_new_v_col())
continue;
Expand Down Expand Up @@ -767,6 +769,11 @@ row_purge_upd_exist_or_extern_func(
continue;
}

if (node->index->online_status
> ONLINE_INDEX_CREATION) {
continue;
}

if (row_upd_changes_ord_field_binary(node->index, node->update,
thr, NULL, NULL)) {
/* Build the older version of the index entry */
Expand Down

0 comments on commit 5919f7b

Please sign in to comment.