Skip to content

Commit f2f22c3

Browse files
committed
Merge 10.5 into 10.6
2 parents 7aa09af + 20e9e80 commit f2f22c3

21 files changed

+404
-215
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
CREATE TABLE t (a int PRIMARY KEY, b int NOT NULL UNIQUE) engine = InnoDB;
2+
connect prevent_purge,localhost,root,,;
3+
start transaction with consistent snapshot;
4+
connect con_del_1,localhost,root,,;
5+
INSERT INTO t VALUES (20,20);
6+
SET DEBUG_SYNC = 'innodb_row_search_for_mysql_exit SIGNAL first_del_row_search_mvcc_finished WAIT_FOR first_del_cont';
7+
DELETE FROM t WHERE b = 20;
8+
connect con_ins_1,localhost,root,,;
9+
SET DEBUG_SYNC = 'now WAIT_FOR first_del_row_search_mvcc_finished';
10+
SET DEBUG_SYNC = 'lock_wait_suspend_thread_enter SIGNAL first_ins_locked';
11+
SET DEBUG_SYNC = 'ib_after_row_insert SIGNAL first_ins_row_inserted WAIT_FOR first_ins_cont';
12+
INSERT INTO t VALUES(10, 20);
13+
connect con_del_2,localhost,root,,;
14+
SET DEBUG_SYNC = 'now WAIT_FOR first_ins_locked';
15+
SET DEBUG_SYNC = 'lock_wait_suspend_thread_enter SIGNAL second_del_locked';
16+
DELETE FROM t WHERE b = 20;
17+
connection default;
18+
SET DEBUG_SYNC = 'now WAIT_FOR second_del_locked';
19+
SET DEBUG_SYNC = 'now SIGNAL first_del_cont';
20+
SET DEBUG_SYNC = 'now WAIT_FOR first_ins_row_inserted';
21+
connection con_del_1;
22+
connection default;
23+
disconnect prevent_purge;
24+
InnoDB 0 transactions not purged
25+
SET DEBUG_SYNC = 'now SIGNAL first_ins_cont';
26+
connection con_del_2;
27+
connection con_ins_1;
28+
connection default;
29+
INSERT INTO t VALUES(30, 20);
30+
disconnect con_ins_1;
31+
disconnect con_del_1;
32+
disconnect con_del_2;
33+
connection default;
34+
SET DEBUG_SYNC = 'RESET';
35+
DROP TABLE t;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
2+
SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
3+
CREATE TABLE t1 (pk int PRIMARY KEY, c int UNIQUE) ENGINE=InnoDB;
4+
INSERT INTO t1 VALUES (10,10),(20,20),(30,30);
5+
connect prevent_purge,localhost,root,,;
6+
start transaction with consistent snapshot;
7+
UPDATE t1 SET c=300 WHERE pk = 30;
8+
connection default;
9+
DELETE FROM t1 WHERE pk = 10;
10+
INSERT INTO t1 VALUES(5,10);
11+
SET DEBUG_SYNC = "row_search_clust_unlatched SIGNAL unlatched WAIT_FOR cont";
12+
SELECT pk FROM t1 FORCE INDEX (c);
13+
connect con1,localhost,root,,;
14+
SET DEBUG_SYNC = "now WAIT_FOR unlatched";
15+
disconnect prevent_purge;
16+
InnoDB 1 transactions not purged
17+
SET DEBUG_SYNC = 'now SIGNAL cont';
18+
disconnect con1;
19+
connection default;
20+
pk
21+
5
22+
20
23+
30
24+
SET DEBUG_SYNC = 'RESET';
25+
DROP TABLE t1;
26+
SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
--source include/have_innodb.inc
2+
--source include/count_sessions.inc
3+
source include/have_debug.inc;
4+
source include/have_debug_sync.inc;
5+
6+
CREATE TABLE t (a int PRIMARY KEY, b int NOT NULL UNIQUE) engine = InnoDB;
7+
8+
--connect(prevent_purge,localhost,root,,)
9+
start transaction with consistent snapshot;
10+
11+
--connect(con_del_1,localhost,root,,)
12+
INSERT INTO t VALUES (20,20);
13+
SET DEBUG_SYNC = 'innodb_row_search_for_mysql_exit SIGNAL first_del_row_search_mvcc_finished WAIT_FOR first_del_cont';
14+
--send DELETE FROM t WHERE b = 20
15+
16+
--connect(con_ins_1,localhost,root,,)
17+
SET DEBUG_SYNC = 'now WAIT_FOR first_del_row_search_mvcc_finished';
18+
# It's supposed the following INSERT will be suspended just after
19+
# lock_wait_suspend_thread_enter syncpoint, and will be awaken
20+
# after the previous DELETE commits. ib_after_row_insert will be executed
21+
# after the INSERT is woken up. The previous DELETE will wait for
22+
# first_del_cont signal before commit, and this signal will be sent later.
23+
# So it's safe to use two signals in a row here, it's guaranted the first
24+
# signal will be received before the second signal is sent.
25+
SET DEBUG_SYNC = 'lock_wait_suspend_thread_enter SIGNAL first_ins_locked';
26+
SET DEBUG_SYNC = 'ib_after_row_insert SIGNAL first_ins_row_inserted WAIT_FOR first_ins_cont';
27+
--send INSERT INTO t VALUES(10, 20)
28+
29+
--connect(con_del_2,localhost,root,,)
30+
SET DEBUG_SYNC = 'now WAIT_FOR first_ins_locked';
31+
SET DEBUG_SYNC = 'lock_wait_suspend_thread_enter SIGNAL second_del_locked';
32+
###############################################################################
33+
# This DELETE is locked by the previous DELETE, after that DELETE is
34+
# committed, it will still be locked by the next INSERT on delete-marked
35+
# heap_no 2 record. After that INSERT inserted the record with heap_no 3,
36+
# and after heap_no 2 record is purged, this DELETE will be unlocked and
37+
# must restore persistent cursor position at heap_no 3 record, as it has the
38+
# same secondary key value as former heap_no 2 record. Then it must be blocked
39+
# by the previous INSERT, and after the INSERT is committed, it must
40+
# delete the record, inserted by the previous INSERT, and the last INSERT(see
41+
# below) must be finished without error. But instead this DELETE restores
42+
# persistent cursor position to supremum, as a result, it does not delete the
43+
# record, inserted by the previous INSERT, and the last INSERT is finished with
44+
# duplicate key check error.
45+
###############################################################################
46+
--send DELETE FROM t WHERE b = 20
47+
48+
--connection default
49+
SET DEBUG_SYNC = 'now WAIT_FOR second_del_locked';
50+
SET DEBUG_SYNC = 'now SIGNAL first_del_cont';
51+
SET DEBUG_SYNC = 'now WAIT_FOR first_ins_row_inserted';
52+
--connection con_del_1
53+
--reap
54+
55+
--connection default
56+
--disconnect prevent_purge
57+
--source include/wait_all_purged.inc
58+
SET DEBUG_SYNC = 'now SIGNAL first_ins_cont';
59+
60+
--connection con_del_2
61+
--reap
62+
63+
--connection con_ins_1
64+
--reap
65+
66+
--connection default
67+
###############################################################################
68+
# Duplicate key error is expected if the bug is not fixed.
69+
###############################################################################
70+
INSERT INTO t VALUES(30, 20);
71+
72+
--disconnect con_ins_1
73+
--disconnect con_del_1
74+
--disconnect con_del_2
75+
--connection default
76+
77+
SET DEBUG_SYNC = 'RESET';
78+
DROP TABLE t;
79+
--source include/wait_until_count_sessions.inc
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
--source include/have_innodb.inc
2+
--source include/have_debug.inc
3+
--source include/have_debug_sync.inc
4+
--source include/count_sessions.inc
5+
6+
SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
7+
SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
8+
9+
CREATE TABLE t1 (pk int PRIMARY KEY, c int UNIQUE) ENGINE=InnoDB;
10+
11+
INSERT INTO t1 VALUES (10,10),(20,20),(30,30);
12+
13+
--connect(prevent_purge,localhost,root,,)
14+
start transaction with consistent snapshot;
15+
# We need this to update page's transaction id for secondary index.
16+
UPDATE t1 SET c=300 WHERE pk = 30;
17+
18+
--connection default
19+
DELETE FROM t1 WHERE pk = 10;
20+
INSERT INTO t1 VALUES(5,10);
21+
SET DEBUG_SYNC = "row_search_clust_unlatched SIGNAL unlatched WAIT_FOR cont";
22+
# With the above sync point row_search_mvcc() will be blocked on delete-marked
23+
# record (10,10) in secondary index just after all page latches are released.
24+
# After this record is purged, row_searc_mvcc() will be unblocked, and cursor
25+
# will be restored to the secondary index record (10,5). As the unique field is
26+
# the same as in the cursor's stored record, and the bug is not fixed, there
27+
# value 5 will be doubled in the result set.
28+
--send SELECT pk FROM t1 FORCE INDEX (c)
29+
30+
--connect(con1,localhost,root,,)
31+
SET DEBUG_SYNC = "now WAIT_FOR unlatched";
32+
--disconnect prevent_purge
33+
let $wait_all_purged= 1;
34+
--source include/wait_all_purged.inc
35+
SET DEBUG_SYNC = 'now SIGNAL cont';
36+
--disconnect con1
37+
38+
--connection default
39+
--reap
40+
41+
SET DEBUG_SYNC = 'RESET';
42+
DROP TABLE t1;
43+
SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
44+
--source include/wait_until_count_sessions.inc

storage/innobase/btr/btr0cur.cc

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6837,11 +6837,9 @@ struct btr_blob_log_check_t {
68376837
m_pcur->btr_cur.page_cur.block->page.unfix();
68386838
} else {
68396839
ut_ad(m_pcur->rel_pos == BTR_PCUR_ON);
6840-
bool ret = btr_pcur_restore_position(
6841-
BTR_MODIFY_LEAF | BTR_MODIFY_EXTERNAL,
6842-
m_pcur, m_mtr);
6843-
6844-
ut_a(ret);
6840+
ut_a(m_pcur->restore_position(
6841+
BTR_MODIFY_LEAF | BTR_MODIFY_EXTERNAL,
6842+
m_mtr) == btr_pcur_t::SAME_ALL);
68456843
}
68466844

68476845
*m_block = btr_pcur_get_block(m_pcur);

storage/innobase/btr/btr0defragment.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ static void btr_defragment_chunk(void*)
672672
mtr_x_lock_index(index, &mtr);
673673
/* This will acquire index->lock SX-latch, which per WL#6363 is allowed
674674
when we are already holding the X-latch. */
675-
btr_pcur_restore_position(BTR_MODIFY_TREE, item->pcur, &mtr);
675+
item->pcur->restore_position(BTR_MODIFY_TREE, &mtr);
676676
buf_block_t* first_block = btr_pcur_get_block(item->pcur);
677677
if (buf_block_t *last_block =
678678
btr_defragment_n_pages(first_block, index,

0 commit comments

Comments
 (0)