Skip to content

Commit cb42733

Browse files
AliSQLAliSQL
authored andcommitted
[perf] Issue#12 OPTIMIZE INNODB READ VIEW CREATION
read_view_open_now() and read_cursor_view_create_for_mysql() do a scan of the list of all open transactions (trx_sys->trx_list) with the kernel_mutex locked. On high-concurrency workloads (i.e. sysbench read-only with number of threads >= 512) the cost of this scan is huge. The patch is ported from Percona Server, and contains 2 optimizations to reduce the cost during read view creating. 1. Pre-allocate a read view structure for every transaction No need to allocate a read view struct for each read_view_open_now() call in a transaction, which is too expensive, allocate once and reused it aterwards when need. 2. Maintain a trx_id array. While creating a read view, simply copy the array without traversing the transaction rw_list. Introduces a concept of "trx descriptors" which is a global ordered array containing IDs of transactions in either TRX_ACTIVE or TRX_PREPARED state. It allows to replace the trx_list scan in read_view_open_now() and read_cursor_view_create_for_mysql() with a binary search on the descriptors array and two memcpy()s. The initial size of the descriptors array is 1000 slots (i.e. 8000 bytes). It is resized whenever we need more descriptors. Since there is no transaction serialization numbers (i.e. trx->no) in the descriptors array, this check was replaced by keeping a separate, trx->no ordered list (trx_sys->trx_serial_list). Getting the current minimum for the current read view is then simply a matter of getting trx->no of the first element from trx_serial_list.
1 parent 1474bc0 commit cb42733

18 files changed

Lines changed: 983 additions & 232 deletions
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
# Create table to test.
2+
CREATE table t1 (c1 INT PRIMARY KEY, c2 INT, c3 INT, key(c2)) ENGINE=INNODB;
3+
CREATE TABLE t2 (c1 INT, c2 INT, c3 INT) ENGINE=INNODB;
4+
SET SESSION tx_isolation = 'READ-COMMITTED';
5+
SET SESSION tx_isolation = 'READ-COMMITTED';
6+
SET SESSION tx_isolation = 'READ-COMMITTED';
7+
SET SESSION tx_isolation = 'READ-COMMITTED';
8+
# Test transaction visibility
9+
BEGIN;
10+
INSERT INTO t1 VALUES (1,2,3);
11+
INSERT INTO t1 VALUES (2,3,4);
12+
INSERT INTO t1 VALUES (3,4,5);
13+
BEGIN;
14+
# Shouldn't see (2,3,4)
15+
SELECT * FROM t1 WHERE c1 = 2;
16+
c1 c2 c3
17+
INSERT INTO t1 VALUES (4,5,6);
18+
BEGIN;
19+
# Shouldn't see (4,5,6) or (2,3,4)
20+
SELECT * FROM t1 WHERE c1 = 4;
21+
c1 c2 c3
22+
SELECT * FROM t1 WHERE c1 = 2;
23+
c1 c2 c3
24+
INSERT INTO t1 VALUES (5,6,7);
25+
BEGIN;
26+
INSERT INTO t2 VALUES (1,2,3);
27+
SELECT * FROM t2;
28+
c1 c2 c3
29+
1 2 3
30+
BEGIN;
31+
INSERT INTO t2 VALUES (2,3,4);
32+
COMMIT;
33+
# Can see (4,5,6) because con2 is commited
34+
SELECT * FROM t1 WHERE c1 = 4;
35+
c1 c2 c3
36+
4 5 6
37+
# Shouldn't see (5,6,7)
38+
SELECT * FROM t1 WHERE c1 = 5;
39+
c1 c2 c3
40+
COMMIT;
41+
# Can see (5,6,7) because con3 is commited
42+
SELECT * FROM t1 WHERE c1 = 5;
43+
c1 c2 c3
44+
5 6 7
45+
COMMIT;
46+
START TRANSACTION READ ONLY;
47+
INSERT INTO t1 VALUES (9,9,9);
48+
ERROR 25006: Cannot execute statement in a READ ONLY transaction.
49+
DELETE FROM t1;
50+
ERROR 25006: Cannot execute statement in a READ ONLY transaction.
51+
SELECT count(*) FROM t1;
52+
count(*)
53+
5
54+
COMMIT;
55+
COMMIT;
56+
commit;
57+
SELECT COUNT(*) FROM t1;
58+
COUNT(*)
59+
5
60+
INSERT INTO t1 VALUES (9,9,9);
61+
COMMIT;
62+
BEGIN;
63+
SELECT COUNT(*) FROM t1;
64+
COUNT(*)
65+
6
66+
DELETE FROM t1;
67+
# Test temporary table now
68+
CREATE TEMPORARY TABLE tmp_a(c1 INT PRIMARY KEY, c2 INT, c3 INT, KEY(c2)) ENGINE=INNODB;
69+
START TRANSACTION READ ONLY;
70+
SELECT * FROM tmp_a;
71+
c1 c2 c3
72+
INSERT INTO tmp_a VALUES (1,2,3);
73+
COMMIT;
74+
START TRANSACTION READ ONLY;
75+
INSERT INTO tmp_a VALUES (2,3,4);
76+
SELECT * FROM tmp_a;
77+
c1 c2 c3
78+
1 2 3
79+
2 3 4
80+
COMMIT;
81+
commit;
82+
commit;
83+
commit;
84+
commit;
85+
commit;
86+
SET DEBUG = '+d,force_extend_descr';
87+
BEGIN;
88+
INSERT INTO t1 VALUES (9,9,9);
89+
UPDATE t1 SET c2=c2+1 WHERE c1 = 2;
90+
UPDATE t1 SET c2=c2+1 WHERE c1 = 2;
91+
SELECT * FROM t1 WHERE c1 = 2;
92+
c1 c2 c3
93+
COMMIT;
94+
CREATE PROCEDURE p1()
95+
BEGIN
96+
DECLARE c CURSOR FOR SELECT c1 FROM t1;
97+
OPEN c;
98+
CLOSE c;
99+
END //
100+
CALL p1();
101+
SET DEBUG='';
102+
BEGIN;
103+
INSERT INTO t1 VALUES (12,13,14);
104+
BEGIN;
105+
INSERT INTO t1 VALUES (13,14,15);
106+
UPDATE t1 SET c2=c2+1 WHERE c1 = 2;
107+
BEGIN;
108+
INSERT INTO t1 VALUES (14,15,16);
109+
SELECT COUNT(*) FROM t1;
110+
COUNT(*)
111+
1
112+
START TRANSACTION READ ONLY;
113+
SELECT COUNT(*) FROM t1;
114+
COUNT(*)
115+
1
116+
COMMIT;
117+
BEGIN;
118+
SELECT * FROM t1;
119+
c1 c2 c3
120+
9 9 9
121+
COMMIT;
122+
commit;
123+
commit;
124+
commit;
125+
BEGIN;
126+
INSERT INTO t2 VALUES (1,2,3);
127+
INSERT INTO t2 VALUES (2,3,4);
128+
UPDATE t2 SET c2=c2+1 WHERE c3 = 3;
129+
COMMIT;
130+
INSERT INTO t1 VALUES (1,2,3),(2,3,4);
131+
SET DEBUG_SYNC = 'RESET';
132+
SET DEBUG_SYNC= 'after_in_seria_list SIGNAL in_list WAIT_FOR check_sig';
133+
UPDATE t1 SET c3=c3+1 WHERE c1= 2;;
134+
SET DEBUG_SYNC= 'NOW WAIT_FOR in_list';
135+
SET DEBUG_SYNC = 'after_in_seria_list SIGNAL check_sig';
136+
BEGIN;
137+
SELECT * FROM t1 WHERE c1 = 2;
138+
c1 c2 c3
139+
2 3 4
140+
INSERT INTO t2 VALUES (9,9,9);
141+
COMMIT;
142+
SET SESSION tx_isolation = 'REPEATABLE-READ';
143+
BEGIN;
144+
INSERT INTO t1 VALUES (32,33,34);
145+
SET SESSION tx_isolation = 'REPEATABLE-READ';
146+
BEGIN;
147+
INSERT INTO t1 VALUES (33,34,35);
148+
SELECT * FROM t1 WHERE c1 = 12;
149+
c1 c2 c3
150+
12 13 14
151+
SET SESSION tx_isolation = 'REPEATABLE-READ';
152+
BEGIN;
153+
UPDATE t1 SET c3=c3+1 WHERE c1= 2;
154+
SELECT * FROM t1 WHERE c1 = 2;
155+
c1 c2 c3
156+
2 3 5
157+
COMMIT;
158+
COMMIT;
159+
COMMIT;
160+
DROP PROCEDURE p1;
161+
DROP TABLE t1;
162+
DROP TABLE t2;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
--query_cache_size=1M
2+
--query_cache_type=1

0 commit comments

Comments
 (0)