summaryrefslogtreecommitdiff
path: root/mysql-test/suite/innodb/t/group_commit_no_optimize_thread.test
blob: 107fc6f40563462bf707132df931aaf2d9adfbc7 (plain)
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
--source include/have_innodb.inc
--source include/have_debug_sync.inc
--source include/have_log_bin.inc

# Test some group commit code paths by using debug_sync to do controlled
# commits of 6 transactions: first 1 alone, then 3 as a group, then 2 as a
# group.
#
# Group 3 is allowed to race as far as possible ahead before group 2 finishes
# to check some edge case for concurrency control.

CREATE TABLE t1 (a VARCHAR(10) PRIMARY KEY) ENGINE=innodb;
# MDEV-515 takes X-LOCK on the table for the first insert.
# So concurrent insert won't happen on the table
INSERT INTO t1 VALUES("default");

SELECT variable_value INTO @commits FROM information_schema.global_status
 WHERE variable_name = 'binlog_commits';
SELECT variable_value INTO @group_commits FROM information_schema.global_status
 WHERE variable_name = 'binlog_group_commits';

connect(con1,localhost,root,,);
connect(con2,localhost,root,,);
connect(con3,localhost,root,,);
connect(con4,localhost,root,,);
connect(con5,localhost,root,,);
connect(con6,localhost,root,,);

# Start group1 (with one thread) doing commit, waiting for
# group2 to queue up before finishing.

connection con1;
SET DEBUG_SYNC= "commit_before_get_LOCK_after_binlog_sync SIGNAL group1_running WAIT_FOR group2_queued";
send INSERT INTO t1 VALUES ("con1");

# Make group2 (with three threads) queue up.
# Make sure con2 is the group commit leader for group2.
# Make group2 wait with running commit_ordered() until group3 has committed.

connection con2;
set DEBUG_SYNC= "now WAIT_FOR group1_running";
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con2";
SET DEBUG_SYNC= "commit_before_get_LOCK_after_binlog_sync SIGNAL group2_running";
SET DEBUG_SYNC= "commit_after_release_LOCK_log WAIT_FOR group3_committed";
send INSERT INTO t1 VALUES ("con2");
connection con3;
SET DEBUG_SYNC= "now WAIT_FOR group2_con2";
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con3";
send INSERT INTO t1 VALUES ("con3");
connection con4;
SET DEBUG_SYNC= "now WAIT_FOR group2_con3";
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con4";
SET DEBUG_SYNC= "commit_after_group_run_commit_ordered SIGNAL group2_visible WAIT_FOR group2_checked";
send INSERT INTO t1 VALUES ("con4");

# When group2 is queued, let group1 continue and queue group3.

connection default;
SET DEBUG_SYNC= "now WAIT_FOR group2_con4";

# At this point, trasaction 1 is still not visible as commit_ordered() has not
# been called yet.
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
SELECT * FROM t1 ORDER BY a;

SET DEBUG_SYNC= "now SIGNAL group2_queued";
connection con1;
reap;

# Now transaction 1 is visible.
connection default;
SELECT * FROM t1 ORDER BY a;

connection con5;
SET DEBUG_SYNC= "commit_before_get_LOCK_after_binlog_sync SIGNAL group3_con5";
SET DEBUG_SYNC= "commit_after_get_LOCK_log SIGNAL con5_leader WAIT_FOR con6_queued";
set DEBUG_SYNC= "now WAIT_FOR group2_running";
send INSERT INTO t1 VALUES ("con5");

connection con6;
SET DEBUG_SYNC= "now WAIT_FOR con5_leader";
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con6_queued";
send INSERT INTO t1 VALUES ("con6");

connection default;
SET DEBUG_SYNC= "now WAIT_FOR group3_con5";
# Still only transaction 1 visible, as group2 have not yet run commit_ordered().
SELECT * FROM t1 ORDER BY a;
SET DEBUG_SYNC= "now SIGNAL group3_committed";
SET DEBUG_SYNC= "now WAIT_FOR group2_visible";
# Now transactions 1-4 visible.
SELECT * FROM t1 ORDER BY a;
SET DEBUG_SYNC= "now SIGNAL group2_checked";

connection con2;
reap;

connection con3;
reap;

connection con4;
reap;

connection con5;
reap;

connection con6;
reap;

connection default;
# Check all transactions finally visible.
SELECT * FROM t1 ORDER BY a;

SELECT variable_value - @commits FROM information_schema.global_status
 WHERE variable_name = 'binlog_commits';
SELECT variable_value - @group_commits FROM information_schema.global_status
 WHERE variable_name = 'binlog_group_commits';

SET DEBUG_SYNC= 'RESET';
DROP TABLE t1;