Skip to content

Commit d90a2b4

Browse files
knielsenandrelkin
authored andcommitted
MDEV-33668: More precise dependency tracking of XA XID in parallel replication
Keep track of each recently active XID, recording which worker it was queued on. If an XID might still be active, choose the same worker to queue event groups that refer to the same XID to avoid conflicts. Otherwise, schedule the XID freely in the next round-robin slot. This way, XA PREPARE can normally be scheduled without restrictions (unless duplicate XID transactions come close together). This improves scheduling and parallelism over the old method, where the worker thread to schedule XA PREPARE on was fixed based on a hash value of the XID. XA COMMIT will normally be scheduled on the same worker as XA PREPARE, but can be a different one if the XA PREPARE is far back in the event history. Testcase and code for trimming dynamic array due to Andrei. Reviewed-by: Andrei Elkin <andrei.elkin@mariadb.com> Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
1 parent f9ecaa8 commit d90a2b4

File tree

5 files changed

+391
-12
lines changed

5 files changed

+391
-12
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
include/master-slave.inc
2+
[connection master]
3+
call mtr.add_suppression("Deadlock found when trying to get lock; try restarting transaction");
4+
call mtr.add_suppression("WSREP: handlerton rollback failed");
5+
connection master;
6+
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
7+
connection slave;
8+
include/stop_slave.inc
9+
SET @old_parallel_threads = @@GLOBAL.slave_parallel_threads;
10+
SET @old_slave_domain_parallel_threads = @@GLOBAL.slave_domain_parallel_threads;
11+
SET @@global.slave_parallel_threads = 5;
12+
SET @@global.slave_domain_parallel_threads = 3;
13+
SET @old_parallel_mode = @@GLOBAL.slave_parallel_mode;
14+
CHANGE MASTER TO master_use_gtid=slave_pos;
15+
connection master;
16+
CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=InnoDB;
17+
INSERT INTO t1 VALUES (1, 0);
18+
include/save_master_gtid.inc
19+
connection slave;
20+
include/start_slave.inc
21+
include/sync_with_master_gtid.inc
22+
include/stop_slave.inc
23+
SET @@global.slave_parallel_mode ='optimistic';
24+
connection master;
25+
include/save_master_gtid.inc
26+
connection slave;
27+
include/start_slave.inc
28+
include/sync_with_master_gtid.inc
29+
include/stop_slave.inc
30+
connection master;
31+
include/save_master_gtid.inc
32+
connection slave;
33+
SET @@global.slave_parallel_mode ='conservative';
34+
include/start_slave.inc
35+
include/sync_with_master_gtid.inc
36+
include/stop_slave.inc
37+
include/save_master_gtid.inc
38+
connection slave;
39+
SET @@global.slave_parallel_mode = 'optimistic';
40+
include/start_slave.inc
41+
include/sync_with_master_gtid.inc
42+
include/diff_tables.inc [master:t1, slave:t1]
43+
connection slave;
44+
include/stop_slave.inc
45+
SET @@global.slave_parallel_mode = @old_parallel_mode;
46+
SET @@global.slave_parallel_threads = @old_parallel_threads;
47+
SET @@global.slave_domain_parallel_threads = @old_slave_domain_parallel_threads;
48+
include/start_slave.inc
49+
connection master;
50+
DROP TABLE t1;
51+
include/save_master_gtid.inc
52+
connection slave;
53+
include/sync_with_master_gtid.inc
54+
connection master;
55+
include/rpl_end.inc
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# Similar to rpl_parallel_optimistic_xa to verify XA
2+
# parallel execution with multiple gtid domain.
3+
# References:
4+
# MDEV-33668 Adapt parallel slave's round-robin scheduling to XA events
5+
6+
--source include/have_innodb.inc
7+
--source include/have_perfschema.inc
8+
--source include/master-slave.inc
9+
10+
# Tests' global declarations
11+
--let $trx = _trx_
12+
13+
call mtr.add_suppression("Deadlock found when trying to get lock; try restarting transaction");
14+
call mtr.add_suppression("WSREP: handlerton rollback failed");
15+
16+
--connection master
17+
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
18+
--save_master_pos
19+
20+
# Prepare to restart slave into optimistic parallel mode
21+
--connection slave
22+
--sync_with_master
23+
--source include/stop_slave.inc
24+
SET @old_parallel_threads = @@GLOBAL.slave_parallel_threads;
25+
SET @old_slave_domain_parallel_threads = @@GLOBAL.slave_domain_parallel_threads;
26+
SET @@global.slave_parallel_threads = 5;
27+
SET @@global.slave_domain_parallel_threads = 3;
28+
SET @old_parallel_mode = @@GLOBAL.slave_parallel_mode;
29+
30+
CHANGE MASTER TO master_use_gtid=slave_pos;
31+
32+
--connection master
33+
CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=InnoDB;
34+
INSERT INTO t1 VALUES (1, 0);
35+
--source include/save_master_gtid.inc
36+
37+
--connection slave
38+
--source include/start_slave.inc
39+
--source include/sync_with_master_gtid.inc
40+
--source include/stop_slave.inc
41+
42+
--let $mode = 2
43+
# mode = 2 is optimistic
44+
SET @@global.slave_parallel_mode ='optimistic';
45+
while ($mode)
46+
{
47+
--connection master
48+
#
49+
# create XA events alternating gtid domains to run them in parallel on slave.
50+
#
51+
--let $domain_num = 3
52+
--let $trx_num = 777
53+
--let $i = $trx_num
54+
--let $conn = master
55+
--disable_query_log
56+
while($i > 0)
57+
{
58+
--let $domain_id = `SELECT $i % $domain_num`
59+
--eval set @@gtid_domain_id = $domain_id
60+
# 'decision' to commit 0, or rollback 1
61+
--let $decision = `SELECT $i % 2`
62+
--eval XA START '$conn$trx$i'
63+
--eval UPDATE t1 SET b = 1 - 2 * $decision WHERE a = 1
64+
--eval XA END '$conn$trx$i'
65+
--eval XA PREPARE '$conn$trx$i'
66+
--let $term = COMMIT
67+
if ($decision)
68+
{
69+
--let $term = ROLLBACK
70+
}
71+
--eval XA $term '$conn$trx$i'
72+
73+
--dec $i
74+
}
75+
--enable_query_log
76+
--source include/save_master_gtid.inc
77+
78+
--connection slave
79+
if (`select $mode = 1`)
80+
{
81+
SET @@global.slave_parallel_mode ='conservative';
82+
}
83+
--source include/start_slave.inc
84+
--source include/sync_with_master_gtid.inc
85+
--source include/stop_slave.inc
86+
87+
--dec $mode
88+
}
89+
90+
91+
# Generations test.
92+
# Create few ranges of XAP groups length of greater than
93+
# 3 * slave_parallel_threads + 1
94+
# terminated upon each range.
95+
--let $iter = 3
96+
--let $generation_len = @@global.slave_parallel_threads
97+
--let $domain_num = 3
98+
--disable_query_log
99+
--connection master
100+
while ($iter)
101+
{
102+
--let $k = `select 3 * 3 * $generation_len`
103+
--let $_k = $k
104+
while ($k)
105+
{
106+
--source include/count_sessions.inc
107+
--connect(con$k,localhost,root,,)
108+
#
109+
# create XA events alternating gtid domains to run them in parallel on slave.
110+
#
111+
--let $domain_id = `SELECT $k % $domain_num`
112+
--eval set @@gtid_domain_id = $domain_id
113+
--eval XA START '$trx$k'
114+
--eval INSERT INTO t1 VALUES ($k + 1, $iter)
115+
--eval XA END '$trx$k'
116+
--eval XA PREPARE '$trx$k'
117+
118+
--disconnect con$k
119+
--connection master
120+
--source include/wait_until_count_sessions.inc
121+
122+
--dec $k
123+
}
124+
125+
--connection master
126+
--let $k = $_k
127+
while ($k)
128+
{
129+
--let $term = COMMIT
130+
--let $decision = `SELECT $k % 2`
131+
if ($decision)
132+
{
133+
--let $term = ROLLBACK
134+
}
135+
--eval XA $term '$trx$k'
136+
}
137+
--dec $iter
138+
}
139+
--enable_query_log
140+
--source include/save_master_gtid.inc
141+
142+
--connection slave
143+
SET @@global.slave_parallel_mode = 'optimistic';
144+
--source include/start_slave.inc
145+
--source include/sync_with_master_gtid.inc
146+
147+
148+
#
149+
# Overall consistency check
150+
#
151+
--let $diff_tables= master:t1, slave:t1
152+
--source include/diff_tables.inc
153+
154+
155+
#
156+
# Clean up.
157+
#
158+
--connection slave
159+
--source include/stop_slave.inc
160+
SET @@global.slave_parallel_mode = @old_parallel_mode;
161+
SET @@global.slave_parallel_threads = @old_parallel_threads;
162+
SET @@global.slave_domain_parallel_threads = @old_slave_domain_parallel_threads;
163+
--source include/start_slave.inc
164+
165+
--connection master
166+
DROP TABLE t1;
167+
--source include/save_master_gtid.inc
168+
169+
--connection slave
170+
--source include/sync_with_master_gtid.inc
171+
172+
--connection master
173+
--source include/rpl_end.inc

sql/log_event_server.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4199,7 +4199,8 @@ int XA_prepare_log_event::do_commit()
41994199
thd->lex->xid= &xid;
42004200
if (!one_phase)
42014201
{
4202-
if ((res= thd->wait_for_prior_commit()))
4202+
if (thd->is_current_stmt_binlog_disabled() &&
4203+
(res= thd->wait_for_prior_commit()))
42034204
return res;
42044205

42054206
thd->lex->sql_command= SQLCOM_XA_PREPARE;

0 commit comments

Comments
 (0)