Skip to content

Commit

Permalink
PS-9297 Lost a record while scanning in reverse order on cursor
Browse files Browse the repository at this point in the history
https://perconadev.atlassian.net/browse/PS-9297

Problem
========
If the last user record on the prev leaf is pessimistically updated during move_backward_from_page, the record may be deleted from the prev leaf and reinserted into the current page. Scanning in reverse order will miss this record.

Cause
========
Same as PS-9092, move_backward_from_page cannot sense that records are moved from the prev leaf to the current leaf.

Solution
========
If btr_insert_into_right_sibling causes records to move between pages, prevent the next page from being optimistically accessed
  • Loading branch information
zhangruyi.vedb committed Jul 5, 2024
1 parent a195525 commit 91d57ec
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 0 deletions.
42 changes: 42 additions & 0 deletions mysql-test/suite/innodb/r/percona_bug_ps9297.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
create table c(id int primary key, val varchar(8000));
insert into c values (1,repeat('a',3000));
insert into c values (2,repeat('a',3000));
insert into c values (3,repeat('a',3000));
insert into c values (4,repeat('a',3000));
insert into c values (5,repeat('a',3000));
insert into c values (-1,repeat('a',2000));
insert into c values (-2,repeat('a',2000));
insert into c values (-3,repeat('a',2000));
insert into c values (-4,repeat('a',2000));
insert into c values (-5,repeat('a',2000));
select id,length(val) from c order by id desc;
id length(val)
5 3000
4 3000
3 3000
2 3000
1 3000
-1 2000
-2 2000
-3 2000
-4 2000
-5 2000
set DEBUG="+d,desc_scan_debug";
set DEBUG_SYNC="desc_scan_before_restore_position SIGNAL desc_scan_before_restore_position_done WAIT_FOR continue";
select id,length(val) from c order by id desc;
set DEBUG_SYNC="now WAIT_FOR desc_scan_before_restore_position_done";
update c set val=repeat('b',6000) where id=2;
set DEBUG_SYNC="now SIGNAL continue";
id length(val)
5 3000
4 3000
3 3000
2 3000
1 3000
-1 2000
-2 2000
-3 2000
-4 2000
-5 2000
set DEBUG="-d,desc_scan_debug";
drop table c;
31 changes: 31 additions & 0 deletions mysql-test/suite/innodb/t/percona_bug_ps9297.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
--source include/have_debug.inc

connect (con1, localhost, root,,);
--connection default
create table c(id int primary key, val varchar(8000));
insert into c values (1,repeat('a',3000));
insert into c values (2,repeat('a',3000));
insert into c values (3,repeat('a',3000));
insert into c values (4,repeat('a',3000));
insert into c values (5,repeat('a',3000));

insert into c values (-1,repeat('a',2000));
insert into c values (-2,repeat('a',2000));
insert into c values (-3,repeat('a',2000));
insert into c values (-4,repeat('a',2000));
insert into c values (-5,repeat('a',2000));

--connection con1
select id,length(val) from c order by id desc;
set DEBUG="+d,desc_scan_debug";
set DEBUG_SYNC="desc_scan_before_restore_position SIGNAL desc_scan_before_restore_position_done WAIT_FOR continue";
send select id,length(val) from c order by id desc;
--connection default
set DEBUG_SYNC="now WAIT_FOR desc_scan_before_restore_position_done";
update c set val=repeat('b',6000) where id=2;
set DEBUG_SYNC="now SIGNAL continue";
--connection con1
reap;
set DEBUG="-d,desc_scan_debug";
--connection default
drop table c;
5 changes: 5 additions & 0 deletions storage/innobase/btr/btr0btr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2313,6 +2313,11 @@ static rec_t *btr_insert_into_right_sibling(uint32_t flags, btr_cur_t *cursor,
}
}

/** We moved the record from the current page to the next page. Therefore, we
* need to disable optimistic access to the next page to ensure that the
* record will not be mistakenly skipped during reverse scanning on cursor. */
buf_block_modify_clock_inc(next_block);

return (rec);
}

Expand Down
6 changes: 6 additions & 0 deletions storage/innobase/btr/btr0pcur.cc
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,12 @@ void btr_pcur_t::move_backward_from_page(mtr_t *mtr) {

mtr_commit(mtr);

DBUG_EXECUTE_IF("desc_scan_debug", {
if (strcmp(index()->table_name, "test/c") == 0) {
DEBUG_SYNC_C("desc_scan_before_restore_position");
}
});

mtr_start(mtr);

restore_position(latch_mode2, mtr, UT_LOCATION_HERE);
Expand Down

0 comments on commit 91d57ec

Please sign in to comment.