Skip to content

Commit

Permalink
Merge branch '10.7' into 10.8
Browse files Browse the repository at this point in the history
# Conflicts:
#	storage/innobase/btr/btr0pcur.cc
#	storage/innobase/log/log0log.cc
  • Loading branch information
vaintroub committed Feb 17, 2022
2 parents 8251a9f + 38a8ac1 commit eb25f47
Show file tree
Hide file tree
Showing 22 changed files with 366 additions and 228 deletions.
35 changes: 35 additions & 0 deletions mysql-test/suite/innodb/r/cursor-restore-locking.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
CREATE TABLE t (a int PRIMARY KEY, b int NOT NULL UNIQUE) engine = InnoDB;
connect prevent_purge,localhost,root,,;
start transaction with consistent snapshot;
connect con_del_1,localhost,root,,;
INSERT INTO t VALUES (20,20);
SET DEBUG_SYNC = 'innodb_row_search_for_mysql_exit SIGNAL first_del_row_search_mvcc_finished WAIT_FOR first_del_cont';
DELETE FROM t WHERE b = 20;
connect con_ins_1,localhost,root,,;
SET DEBUG_SYNC = 'now WAIT_FOR first_del_row_search_mvcc_finished';
SET DEBUG_SYNC = 'lock_wait_suspend_thread_enter SIGNAL first_ins_locked';
SET DEBUG_SYNC = 'ib_after_row_insert SIGNAL first_ins_row_inserted WAIT_FOR first_ins_cont';
INSERT INTO t VALUES(10, 20);
connect con_del_2,localhost,root,,;
SET DEBUG_SYNC = 'now WAIT_FOR first_ins_locked';
SET DEBUG_SYNC = 'lock_wait_suspend_thread_enter SIGNAL second_del_locked';
DELETE FROM t WHERE b = 20;
connection default;
SET DEBUG_SYNC = 'now WAIT_FOR second_del_locked';
SET DEBUG_SYNC = 'now SIGNAL first_del_cont';
SET DEBUG_SYNC = 'now WAIT_FOR first_ins_row_inserted';
connection con_del_1;
connection default;
disconnect prevent_purge;
InnoDB 0 transactions not purged
SET DEBUG_SYNC = 'now SIGNAL first_ins_cont';
connection con_del_2;
connection con_ins_1;
connection default;
INSERT INTO t VALUES(30, 20);
disconnect con_ins_1;
disconnect con_del_1;
disconnect con_del_2;
connection default;
SET DEBUG_SYNC = 'RESET';
DROP TABLE t;
79 changes: 79 additions & 0 deletions mysql-test/suite/innodb/t/cursor-restore-locking.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
--source include/have_innodb.inc
--source include/count_sessions.inc
source include/have_debug.inc;
source include/have_debug_sync.inc;

CREATE TABLE t (a int PRIMARY KEY, b int NOT NULL UNIQUE) engine = InnoDB;

--connect(prevent_purge,localhost,root,,)
start transaction with consistent snapshot;

--connect(con_del_1,localhost,root,,)
INSERT INTO t VALUES (20,20);
SET DEBUG_SYNC = 'innodb_row_search_for_mysql_exit SIGNAL first_del_row_search_mvcc_finished WAIT_FOR first_del_cont';
--send DELETE FROM t WHERE b = 20

--connect(con_ins_1,localhost,root,,)
SET DEBUG_SYNC = 'now WAIT_FOR first_del_row_search_mvcc_finished';
# It's supposed the following INSERT will be suspended just after
# lock_wait_suspend_thread_enter syncpoint, and will be awaken
# after the previous DELETE commits. ib_after_row_insert will be executed
# after the INSERT is woken up. The previous DELETE will wait for
# first_del_cont signal before commit, and this signal will be sent later.
# So it's safe to use two signals in a row here, it's guaranted the first
# signal will be received before the second signal is sent.
SET DEBUG_SYNC = 'lock_wait_suspend_thread_enter SIGNAL first_ins_locked';
SET DEBUG_SYNC = 'ib_after_row_insert SIGNAL first_ins_row_inserted WAIT_FOR first_ins_cont';
--send INSERT INTO t VALUES(10, 20)

--connect(con_del_2,localhost,root,,)
SET DEBUG_SYNC = 'now WAIT_FOR first_ins_locked';
SET DEBUG_SYNC = 'lock_wait_suspend_thread_enter SIGNAL second_del_locked';
###############################################################################
# This DELETE is locked by the previous DELETE, after that DELETE is
# committed, it will still be locked by the next INSERT on delete-marked
# heap_no 2 record. After that INSERT inserted the record with heap_no 3,
# and after heap_no 2 record is purged, this DELETE will be unlocked and
# must restore persistent cursor position at heap_no 3 record, as it has the
# same secondary key value as former heap_no 2 record. Then it must be blocked
# by the previous INSERT, and after the INSERT is committed, it must
# delete the record, inserted by the previous INSERT, and the last INSERT(see
# below) must be finished without error. But instead this DELETE restores
# persistent cursor position to supremum, as a result, it does not delete the
# record, inserted by the previous INSERT, and the last INSERT is finished with
# duplicate key check error.
###############################################################################
--send DELETE FROM t WHERE b = 20

--connection default
SET DEBUG_SYNC = 'now WAIT_FOR second_del_locked';
SET DEBUG_SYNC = 'now SIGNAL first_del_cont';
SET DEBUG_SYNC = 'now WAIT_FOR first_ins_row_inserted';
--connection con_del_1
--reap

--connection default
--disconnect prevent_purge
--source include/wait_all_purged.inc
SET DEBUG_SYNC = 'now SIGNAL first_ins_cont';

--connection con_del_2
--reap

--connection con_ins_1
--reap

--connection default
###############################################################################
# Duplicate key error is expected if the bug is not fixed.
###############################################################################
INSERT INTO t VALUES(30, 20);

--disconnect con_ins_1
--disconnect con_del_1
--disconnect con_del_2
--connection default

SET DEBUG_SYNC = 'RESET';
DROP TABLE t;
--source include/wait_until_count_sessions.inc
8 changes: 3 additions & 5 deletions storage/innobase/btr/btr0cur.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6834,11 +6834,9 @@ struct btr_blob_log_check_t {
m_pcur->btr_cur.page_cur.block->page.unfix();
} else {
ut_ad(m_pcur->rel_pos == BTR_PCUR_ON);
bool ret = btr_pcur_restore_position(
BTR_MODIFY_LEAF | BTR_MODIFY_EXTERNAL,
m_pcur, m_mtr);

ut_a(ret);
ut_a(m_pcur->restore_position(
BTR_MODIFY_LEAF | BTR_MODIFY_EXTERNAL,
m_mtr) == btr_pcur_t::SAME_ALL);
}

*m_block = btr_pcur_get_block(m_pcur);
Expand Down
2 changes: 1 addition & 1 deletion storage/innobase/btr/btr0defragment.cc
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,7 @@ static void btr_defragment_chunk(void*)
mtr_x_lock_index(index, &mtr);
/* This will acquire index->lock SX-latch, which per WL#6363 is allowed
when we are already holding the X-latch. */
btr_pcur_restore_position(BTR_MODIFY_TREE, item->pcur, &mtr);
item->pcur->restore_position(BTR_MODIFY_TREE, &mtr);
buf_block_t* first_block = btr_pcur_get_block(item->pcur);
if (buf_block_t *last_block =
btr_defragment_n_pages(first_block, index,
Expand Down
Loading

0 comments on commit eb25f47

Please sign in to comment.