summaryrefslogtreecommitdiff
path: root/mysql-test/suite/bugs/t/rpl_bug38205.test
blob: 52b36636e79ab57e1f3ed5616cd98c20e7246bac (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
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
#
# Bug #38205 Row-based Replication (RBR) causes inconsistencies: HA_ERR_FOUND_DUPP_KEY
# Bug#319  if while a non-transactional slave is replicating a transaction possible problem 
#
# Verifying the fact that STOP SLAVE in the middle of a group execution waits
# for the end of the group before the slave sql thread will stop.
# The patch refines STOP SLAVE to not interrupt a transaction or other type of 
# the replication events group (the part I).
# Killing the sql thread continues to provide a "hard" stop (the part II).
#
# Non-deterministic tests
#

source include/master-slave.inc;
source include/have_innodb.inc;


#
# Part II, killed sql slave leaves instantly
#

# A. multi-statement transaction as the replication group

connection master;

create table t1i(n int primary key) engine=innodb;
create table t2m(n int primary key) engine=myisam;

sync_slave_with_master;

connection master;

begin;
insert into t1i values (1);
insert into t1i values (2);
insert into t1i values (3);
commit;

sync_slave_with_master;

#
# todo: first challenge is to find out the SQL thread id
# the following is not fully reliable
#

let $id=`SELECT id from information_schema.processlist where user like 'system user' and state like '%Has read all relay log%' or user like 'system user' and state like '%Reading event from the relay log%'`;
connection slave;
begin;
insert into t1i values (5);

connection master;
let $pos0_master= query_get_value(SHOW MASTER STATUS, Position, 1);
begin;
insert into t1i values (4);
insert into t2m values (1); # non-ta update
update t1i set n = 5 where n = 4; # to block at. can't be played with killed
commit;
let $pos1_master= query_get_value(SHOW MASTER STATUS, Position, 1);

connection slave;
# slave sql thread must be locked out by the conn `slave' explicit lock
let $pos0_slave= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1);
--disable_query_log
eval select $pos0_master - $pos0_slave as zero;
--enable_query_log

connection slave1;

let $count= 1;
let $table= t2m;
source include/wait_until_rows_count.inc;
#
# todo: may fail as said above
#
--echo *** kill sql thread ***
--disable_query_log
eval kill connection $id;
--enable_query_log

connection slave;
rollback; # release the sql thread

connection slave1;

source include/wait_for_slave_sql_to_stop.inc;
let $sql_status= query_get_value(SHOW SLAVE STATUS, Slave_SQL_Running, 1);
--echo *** sql thread is *not* running: $sql_status ***
let $pos1_slave= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1);

connection slave;
--echo *** the prove: the killed slave has not finished the current transaction ***

--disable_query_log
select count(*) as three from t1i;
eval select $pos1_master > $pos1_slave as one;
eval select $pos1_slave - $pos0_slave as zero;
--enable_query_log

delete from t2m; # remove the row to be able to replay
start slave sql_thread;

#
# Part I: B The homogenous transaction remains interuptable in between
#

connection master;
delete from t1i;
delete from t2m;

sync_slave_with_master;
begin;
insert into t1i values (5);

connection master;
let $pos0_master= query_get_value(SHOW MASTER STATUS, Position, 1);
begin;
insert into t1i values (4);
update t1i set n = 5 where n = 4; # to block at. not to be played
commit;
let $pos1_master= query_get_value(SHOW MASTER STATUS, Position, 1);


connection slave1;
# slave sql can't advance as must be locked by the conn `slave' trans
let $pos0_slave= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1);
--disable_query_log
eval select $pos0_master - $pos0_slave as zero;
--enable_query_log

#
# the replicated trans is blocked by the slave's local.
# However, it's not easy to catch the exact moment when it happens.
# The test issues sleep which makes the test either non-deterministic or
# wasting too much time.
#
--sleep 3

send stop slave sql_thread;

connection slave;
rollback; # release the sql thread

connection slave1;
reap;
source include/wait_for_slave_sql_to_stop.inc;
let $sql_status= query_get_value(SHOW SLAVE STATUS, Slave_SQL_Running, 1);
--echo *** sql thread is *not* running: $sql_status ***

let $pos1_slave= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1);

--echo *** the prove: the stopped slave has rolled back the current transaction ***

--disable_query_log
select count(*) as zero from t1i;
eval select $pos0_master - $pos0_slave as zero;
eval select $pos1_master > $pos0_slave as one;
--enable_query_log

start slave sql_thread;

# clean-up

connection master;
drop table t1i, t2m;

sync_slave_with_master;