File: innodb_bug30113362.test

package info (click to toggle)
mysql-8.0 8.0.43-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,273,924 kB
  • sloc: cpp: 4,684,605; ansic: 412,450; pascal: 108,398; java: 83,641; perl: 30,221; cs: 27,067; sql: 26,594; sh: 24,181; python: 21,816; yacc: 17,169; php: 11,522; xml: 7,388; javascript: 7,076; makefile: 2,194; lex: 1,075; awk: 670; asm: 520; objc: 183; ruby: 97; lisp: 86
file content (207 lines) | stat: -rw-r--r-- 6,706 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#
# Test for Bug#30113362 : BTR_CUR_WILL_MODIFY_TREE() IS INSUFFICIENT FOR HIGHER TREE LEVEL
#

--source include/have_debug.inc
--source include/have_debug_sync.inc
--source include/have_innodb_16k.inc

--disable_query_log
SET @old_innodb_limit_optimistic_insert_debug = @@innodb_limit_optimistic_insert_debug;
SET @old_innodb_adaptive_hash_index = @@innodb_adaptive_hash_index;
SET @old_innodb_stats_persistent = @@innodb_stats_persistent;
SET @old_innodb_flush_log_at_trx_commit = @@innodb_flush_log_at_trx_commit;
--enable_query_log

# Save the initial number of concurrent sessions
--source include/count_sessions.inc

SET GLOBAL innodb_adaptive_hash_index = false;
SET GLOBAL innodb_stats_persistent = false;
SET GLOBAL innodb_flush_log_at_trx_commit = 0;

--connect (con1,localhost,root,,)
--connect (con2,localhost,root,,)

CREATE TABLE t1 (
  a00 CHAR(255) NOT NULL DEFAULT 'a',
  a01 CHAR(255) NOT NULL DEFAULT 'a',
  a02 CHAR(255) NOT NULL DEFAULT 'a',
  b INT NOT NULL DEFAULT 0,
  CONSTRAINT pkey PRIMARY KEY(a00, a01, a02)
) charset latin1 ENGINE = InnoDB COMMENT='MERGE_THRESHOLD=45';

#
# Prepare primary key index tree to be used for this test.
#

SET GLOBAL innodb_limit_optimistic_insert_debug = 3;

DROP PROCEDURE IF EXISTS data_load_t1;
delimiter |;
CREATE PROCEDURE data_load_t1()
BEGIN
  DECLARE c1 INT DEFAULT 97;
  DECLARE c2 INT DEFAULT 97;
  DECLARE c3 INT DEFAULT 97;

  WHILE c1 < 102 DO
    WHILE c2 < 123 DO
      WHILE c3 < 123 DO
        INSERT INTO t1 (a00) VALUES (CHAR(c1,c2,c3));
        SET c3 = c3 + 1;
      END WHILE;
      SET c3 = 97;
      SET c2 = c2 + 1;
    END WHILE;
    SET c2 = 97;
    SET c1 = c1 + 1;
  END WHILE;
END |
delimiter ;|
call data_load_t1();
DROP PROCEDURE data_load_t1;

# all node pages are sparse (max 3 node_ptrs)
ANALYZE TABLE t1;
SELECT CLUST_INDEX_SIZE FROM information_schema.INNODB_TABLESTATS WHERE NAME = 'test/t1';

# causes "domino falling" merges to upper level
SET GLOBAL innodb_limit_optimistic_insert_debug = 0;
DELETE FROM t1 WHERE a00 = 'cnm';
--source suite/innodb/include/force_purge.inc

# at this moment, in the tree,
# ...
# level 4: ...(ast,avw,ayz)(bcc,bff,bii,bll,boo,brr,buu,bxx,cba,ced,cqp,cts)(cwv,czy,ddb)...
# ...

--echo # Test start

# (1) Similar case to the first reported corefile at bug#30113362
#     - Deleting 'bii' causes "domino falling" merges and the node_ptr becomes left_most of level 4.
#       So, the operation needs upper level pages' X-latch, though doesn't cause merge more.
SET DEBUG_SYNC = 'RESET';

SET GLOBAL innodb_purge_stop_now = ON;
SET GLOBAL DEBUG = "+d,pessimistic_row_purge_clust";
DELETE FROM t1 WHERE a00 = 'bii';
SET GLOBAL innodb_purge_run_now = ON;
SET DEBUG_SYNC = "now WAIT_FOR pessimistic_row_purge_clust_pause";

--connection con1
SET DEBUG_SYNC = 'rw_s_lock_waiting SIGNAL lockwait1';
# Blocked
--send
SELECT a00 FROM t1 WHERE a00 = 'bcc';

--connection default
SET DEBUG_SYNC = 'now WAIT_FOR lockwait1';
# bug#30113362 caused deadlock
# signal purge thread to go
SET GLOBAL DEBUG = "-d,pessimistic_row_purge_clust";
SET DEBUG_SYNC = "now SIGNAL pessimistic_row_purge_clust_continue";

--connection con1
--reap

--connection default

--source suite/innodb/include/force_purge.inc
ANALYZE TABLE t1;
SELECT CLUST_INDEX_SIZE FROM information_schema.INNODB_TABLESTATS WHERE NAME = 'test/t1';


# (2) Confirm blocking domain caused by DELETE modify_tree for tall index tree
SET DEBUG_SYNC = 'RESET';

# at this moment, in the tree,
# ...
# level 4: ...(ajk,amn,apq)(ast,avw,ayz,bll,boo,brr,buu,bxx,cba,ced,cqp,cts)(cwv,czy,ddb)(dge,djh,dmk)(dpn,dsq,dvt)(dyw,ebz,efc)...
# ...

# makes >17 records in level4 [(2^(4-1))*2 + 1]. (causes never left_most records)
DELETE FROM t1 WHERE a00 = 'dpn';
--source suite/innodb/include/force_purge.inc
# at this moment, in the tree,
# (* before "]" and after "[" records are treated as left_most possible records)
# ...
# level 4: ...(ajk,amn,apq)(ast,avw,ayz,bll,boo,brr,buu,bxx],cba,ced,[cqp,cts,cwv,czy,ddb,dge,dsq,dvt)(dyw,ebz,efc)...
# level 3: ...(cba,ccb,cdc)(ced,cfe,cgf,chg],cih,cji,[ckj,clk,con,cpo)(cqp,crq,csr)...
# level 2: ...(ckj,cks,clb)(clk,clt],cmc,cml,cmu,cnd,[cnv,coe)(con,cow,cpf)...
# level 1: ...(cmu,cmx,cna)(cnd],cng,cnj,cnp,[cns)(cnv,cny,cob)...
# level 0: ...(cnd,cne,cnf)(cng,cnh,cni)(cnj,cnk,cnl,cnn,cno)(cnp,cnq,cnr)...

# deletes just 'ced' node_ptr only from level 4. doesn't cause merge and never left_most.
# adjusts MERGE_THRESHOLD to do so.
ALTER TABLE t1 COMMENT='MERGE_THRESHOLD=35';
SET GLOBAL innodb_purge_stop_now = ON;
SET GLOBAL DEBUG = "+d,pessimistic_row_purge_clust";
DELETE FROM t1 WHERE a00 = 'cnd';
SET GLOBAL innodb_purge_run_now = ON;
SET DEBUG_SYNC = "now WAIT_FOR pessimistic_row_purge_clust_pause";

# The expectation should be...
# level 0: (#cnd#,cne,cnf): causes merge
# level 1: (#cnd#],cng,cnj,cnp,[cns): left_most
# level 2: (clk,clt],cmc,cml,cmu,#cnd#,[cnv,coe): causes merge
# level 3: (ced,cfe,cgf,chg],cih,cji,[ckj,#clk#,con,cpo): left_most possible (not cause merge)
# level 4: (ast,avw,ayz,bll,boo,brr,buu,bxx],cba,#ced#,[cqp,cts,cwv,czy,ddb,dge,dsq,dvt): no merge, not left_most possible
# So, the top X-latch page is at level4. (ast~dvt)

# blocking domain based on whether its ancestor is latched or not.
# (*[]: ancestor is X-latched)
# level 0: ...(asq,asr,ass) [(ast,asu,asv)...(dyt,dyu,dyv)] (dyw,dyx,dyy)...

# Not blocked searches
SELECT a00 FROM t1 WHERE a00 = 'ass';
SELECT a00 FROM t1 WHERE a00 = 'dyx';

--connection con1
SET DEBUG_SYNC = 'rw_s_lock_waiting SIGNAL lockwait1';
# Blocked
--send
SELECT a00 FROM t1 WHERE a00 = 'ast';

--connection con2
SET DEBUG_SYNC = 'rw_s_lock_waiting SIGNAL lockwait2';
# Blocked
--send
SELECT a00 FROM t1 WHERE a00 = 'dyw';

--connection default
SET DEBUG_SYNC = 'now WAIT_FOR lockwait1';
SET DEBUG_SYNC = 'now WAIT_FOR lockwait2';
# signal purge thread to go
SET GLOBAL DEBUG = "-d,pessimistic_row_purge_clust";
SET DEBUG_SYNC = "now SIGNAL pessimistic_row_purge_clust_continue";

--connection con1
--reap

--connection con2
--reap

--connection default
ANALYZE TABLE t1;
SELECT CLUST_INDEX_SIZE FROM information_schema.INNODB_TABLESTATS WHERE NAME = 'test/t1';


# Cleanup
SET DEBUG_SYNC = 'RESET';

--connection default
--disconnect con1
--disconnect con2

DROP TABLE t1;

--disable_query_log
SET GLOBAL innodb_limit_optimistic_insert_debug = @old_innodb_limit_optimistic_insert_debug;
SET GLOBAL innodb_adaptive_hash_index = @old_innodb_adaptive_hash_index;
SET GLOBAL innodb_stats_persistent = @old_innodb_stats_persistent;
SET GLOBAL innodb_flush_log_at_trx_commit = @old_innodb_flush_log_at_trx_commit;
--enable_query_log

# Wait till all disconnects are completed.
--source include/wait_until_count_sessions.inc