~stewart/drizzle/embedded-innodb-create-select-transaction-arrgh

« back to all changes in this revision

Viewing changes to mysql-test/suite/rpl/t/rpl_idempotency.test

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Testing various forms of idempotency for replication that should
 
2
# work the same way under statement based as under row based.
 
3
 
 
4
source include/master-slave.inc;
 
5
connection master;
 
6
source include/have_innodb.inc;
 
7
connection slave;
 
8
source include/have_innodb.inc;
 
9
 
 
10
connection master;
 
11
CREATE TABLE t1 (a INT PRIMARY KEY);
 
12
CREATE TABLE t2 (a INT);
 
13
INSERT INTO t1 VALUES (-1),(-2),(-3);
 
14
INSERT INTO t2 VALUES (-1),(-2),(-3);
 
15
sync_slave_with_master;
 
16
 
 
17
# A delete for a row that does not exist, the statement is
 
18
# deliberately written to be idempotent for statement-based
 
19
# replication as well. We test this towards both a table with a
 
20
# primary key and without a primary key.
 
21
 
 
22
connection slave;
 
23
DELETE FROM t1 WHERE a = -2;
 
24
DELETE FROM t2 WHERE a = -2;
 
25
connection master;
 
26
DELETE FROM t1 WHERE a = -2;
 
27
DELETE FROM t2 WHERE a = -2;
 
28
SELECT * FROM t1 ORDER BY a;
 
29
SELECT * FROM t2 ORDER BY a;
 
30
sync_slave_with_master;
 
31
SELECT * FROM t1 ORDER BY a;
 
32
SELECT * FROM t2 ORDER BY a;
 
33
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
 
34
disable_query_log;
 
35
eval SELECT "$last_error" AS Last_SQL_Error;
 
36
enable_query_log;
 
37
 
 
38
# An insert of a row that already exists. Since we are replacing the
 
39
# row if it already exists, the most apropriate representation is
 
40
# INSERT IGNORE. We only test this towards a table with a primary key,
 
41
# since the other case does not make sense.
 
42
 
 
43
INSERT IGNORE INTO t1 VALUES (-2);
 
44
connection master;
 
45
INSERT IGNORE INTO t1 VALUES (-2);
 
46
SELECT * FROM t1 ORDER BY a;
 
47
sync_slave_with_master;
 
48
SELECT * FROM t1 ORDER BY a;
 
49
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
 
50
disable_query_log;
 
51
eval SELECT "$last_error" AS Last_SQL_Error;
 
52
enable_query_log;
 
53
 
 
54
# BUG#19958: RBR idempotency issue for UPDATE and DELETE
 
55
 
 
56
# Statement-based and row-based replication have different behaviour
 
57
# when updating a row with an explicit WHERE-clause that matches
 
58
# exactly one row (or no row at all). For statement-based replication,
 
59
# the statement is idempotent since the first time it is executed, it
 
60
# will update exactly one row, and the second time it will not update
 
61
# any row at all.  This was not the case for row-based replication, so
 
62
# we test under both row-based and statement-based replication both
 
63
# for tables with and without primary keys.
 
64
 
 
65
connection slave;
 
66
UPDATE t1 SET a = 1 WHERE a = -1;
 
67
UPDATE t2 SET a = 1 WHERE a = -1;
 
68
connection master;
 
69
UPDATE t1 SET a = 1 WHERE a = -1;
 
70
UPDATE t2 SET a = 1 WHERE a = -1;
 
71
SELECT * FROM t1 ORDER BY a;
 
72
SELECT * FROM t2 ORDER BY a;
 
73
sync_slave_with_master;
 
74
SELECT * FROM t1 ORDER BY a;
 
75
SELECT * FROM t2 ORDER BY a;
 
76
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
 
77
disable_query_log;
 
78
eval SELECT "$last_error" AS Last_SQL_Error;
 
79
enable_query_log;
 
80
 
 
81
connection master;
 
82
DROP TABLE t1, t2;
 
83
sync_slave_with_master;
 
84
 
 
85
# bug#31609 Not all RBR slave errors reported as errors
 
86
# bug#31552 Replication breaks when deleting rows from out-of-sync table
 
87
#           without PK
 
88
 
 
89
#
 
90
# Idempotent applying is not default any longer.
 
91
# The default for slave-exec-mode option and server
 
92
# variable slave_exec_mode  is 'STRICT'.
 
93
# When 'STRICT' mode is set, the slave SQL thread will stop whenever
 
94
# the row to change is not found. In 'IDEMPOTENT' mode, the SQL thread
 
95
# will continue running and apply the row - replace if it's Write_rows event -
 
96
# or skip to the next event.
 
97
 
 
98
# the previous part of the tests was with IDEMPOTENT slave's mode.
 
99
 
 
100
 
 
101
#
 
102
# Other than above idempotent errors dealing with foreign keys constraint
 
103
#
 
104
 
 
105
select @@global.slave_exec_mode /* must be IDEMPOTENT */;
 
106
 
 
107
connection master;
 
108
 
 
109
create table ti1 (b int primary key) engine = innodb;
 
110
create table ti2 (a int primary key, b int, foreign key (b) references ti1(b))
 
111
     engine = innodb;
 
112
set foreign_key_checks=1 /* ensure the check */;
 
113
 
 
114
insert into ti1 values (1),(2),(3);
 
115
insert into ti2 set a=2, b=2;
 
116
 
 
117
sync_slave_with_master;
 
118
 
 
119
#connection slave;
 
120
select * from ti1 order by b /* must be (1),(2),(3) */;
 
121
insert into ti2 set a=1, b=1;
 
122
select * from ti2 order by b /* must be (1,1) (2,2) */;
 
123
 
 
124
connection master;
 
125
 
 
126
# from now on checking rbr specific idempotent errors
 
127
set @save_binlog_format= @@session.binlog_format;
 
128
set @@session.binlog_format= row;
 
129
delete from ti1 where b=1;
 
130
 
 
131
select * from ti1 order by b /* must be (2),(3) */;
 
132
 
 
133
# slave must catch up (expect some warnings in error.log)
 
134
sync_slave_with_master;
 
135
 
 
136
#connection slave;
 
137
select * from ti1 order by b /* must stays as were on master (1),(2),(3) */;
 
138
 
 
139
delete from ti1 where b=3;
 
140
 
 
141
connection master;
 
142
insert into ti2 set a=3, b=3;
 
143
 
 
144
# slave must catch up (expect some warnings in error.log)
 
145
sync_slave_with_master;
 
146
 
 
147
#connection slave;
 
148
select * from ti2 order by b /* must be (1,1),(2,2) - not inserted */;
 
149
 
 
150
 
 
151
#
 
152
# Checking the new global sys variable
 
153
#
 
154
 
 
155
connection slave;
 
156
 
 
157
set global slave_exec_mode='IDEMPOTENT';
 
158
set global slave_exec_mode='STRICT';
 
159
 
 
160
# checking mutual exclusion for the options
 
161
--error ER_SLAVE_AMBIGOUS_EXEC_MODE
 
162
set global slave_exec_mode='IDEMPOTENT,STRICT';
 
163
 
 
164
select @@global.slave_exec_mode /* must be STRICT */;
 
165
 
 
166
#
 
167
# Checking stops.
 
168
# In the following sections strict slave sql thread is going to
 
169
# stop when faces an idempotent error. In order to proceed
 
170
# the mode is temporarily switched to indempotent.
 
171
#
 
172
 
 
173
#
 
174
--echo *** foreign keys errors as above now forces to stop
 
175
#
 
176
 
 
177
connection master;
 
178
 
 
179
set foreign_key_checks=0;
 
180
drop table ti2, ti1;
 
181
 
 
182
create table ti1 (b int primary key) engine = innodb;
 
183
create table ti2 (a int primary key, b int, foreign key (b) references ti1(b))
 
184
     engine = innodb;
 
185
set foreign_key_checks=1 /* ensure the check */;
 
186
 
 
187
insert into ti1 values (1),(2),(3);
 
188
insert into ti2 set a=2, b=2;
 
189
 
 
190
sync_slave_with_master;
 
191
 
 
192
#connection slave;
 
193
select * from ti1 order by b /* must be (1),(2),(3) */;
 
194
--echo *** conspire future problem
 
195
insert into ti2 set a=1, b=1;
 
196
select * from ti2 order by b /* must be (1,1) (2,2) */;
 
197
 
 
198
connection master;
 
199
 
 
200
delete from ti1 where b=1 /* offending delete event */;
 
201
select * from ti1 order by b /* must be (2),(3) */;
 
202
 
 
203
# foreign key: row is referenced
 
204
 
 
205
--echo *** slave must stop
 
206
source include/wait_for_slave_sql_to_stop.inc;
 
207
 
 
208
connection slave;
 
209
 
 
210
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
 
211
disable_query_log;
 
212
eval SELECT "$last_error" AS Last_SQL_Error;
 
213
enable_query_log;
 
214
 
 
215
select * from ti1 order by b /* must be (1),(2),(3) - not deleted */;
 
216
set foreign_key_checks= 0;
 
217
delete from ti2 where b=1;
 
218
set foreign_key_checks= 1;
 
219
set global slave_exec_mode='IDEMPOTENT';
 
220
start slave sql_thread;
 
221
connection master;
 
222
sync_slave_with_master;
 
223
#connection slave;
 
224
set global slave_exec_mode='STRICT';
 
225
 
 
226
connection master;
 
227
 
 
228
sync_slave_with_master;
 
229
 
 
230
#connection slave;
 
231
--echo *** conspire the following insert failure
 
232
# foreign key: no referenced row
 
233
 
 
234
--echo *** conspire future problem
 
235
delete from ti1 where b=3;
 
236
 
 
237
connection master;
 
238
insert into ti2 set a=3, b=3 /* offending write event */;
 
239
--echo *** slave must stop
 
240
 
 
241
source include/wait_for_slave_sql_to_stop.inc;
 
242
 
 
243
connection slave;
 
244
 
 
245
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
 
246
disable_query_log;
 
247
eval SELECT "$last_error" AS Last_SQL_Error;
 
248
enable_query_log;
 
249
 
 
250
select * from ti2 order by b /* must be (2,2) */;
 
251
set foreign_key_checks= 0;
 
252
insert into ti1 set b=3;
 
253
set foreign_key_checks= 1;
 
254
set global slave_exec_mode='IDEMPOTENT';
 
255
start slave sql_thread;
 
256
connection master;
 
257
sync_slave_with_master;
 
258
#connection slave;
 
259
set global slave_exec_mode='STRICT';
 
260
 
 
261
connection master;
 
262
 
 
263
sync_slave_with_master;
 
264
 
 
265
select * from ti2 order by b /* must be (2,2),(3,3) */;
 
266
 
 
267
 
268
--echo *** other errors
 
269
 
270
 
 
271
# dup key insert
 
272
 
 
273
#connection slave;
 
274
--echo *** conspiring query
 
275
insert into ti1 set b=1;
 
276
 
 
277
connection master;
 
278
insert into ti1 set b=1 /* offending write event */;
 
279
 
 
280
--echo *** slave must stop
 
281
source include/wait_for_slave_sql_to_stop.inc;
 
282
 
 
283
connection slave;
 
284
 
 
285
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
 
286
disable_query_log;
 
287
eval SELECT "$last_error" AS Last_SQL_Error;
 
288
enable_query_log;
 
289
 
 
290
set foreign_key_checks= 0;
 
291
delete from ti1 where b=1;
 
292
set foreign_key_checks= 1;
 
293
set global slave_exec_mode='IDEMPOTENT';
 
294
start slave sql_thread;
 
295
connection master;
 
296
sync_slave_with_master;
 
297
#connection slave;
 
298
set global slave_exec_mode='STRICT';
 
299
 
 
300
# key not found
 
301
 
 
302
connection master;
 
303
 
 
304
CREATE TABLE t1 (a INT PRIMARY KEY);
 
305
CREATE TABLE t2 (a INT);
 
306
INSERT INTO t1 VALUES (-1),(-2),(-3);
 
307
INSERT INTO t2 VALUES (-1),(-2),(-3);
 
308
sync_slave_with_master;
 
309
 
 
310
#connection slave;
 
311
DELETE FROM t1 WHERE a = -2;
 
312
DELETE FROM t2 WHERE a = -2;
 
313
connection master;
 
314
DELETE FROM t1 WHERE a = -2;
 
315
 
 
316
--echo *** slave must stop
 
317
source include/wait_for_slave_sql_to_stop.inc;
 
318
 
 
319
connection slave;
 
320
 
 
321
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
 
322
disable_query_log;
 
323
eval SELECT "$last_error" AS Last_SQL_Error;
 
324
enable_query_log;
 
325
 
 
326
set global slave_exec_mode='IDEMPOTENT';
 
327
start slave sql_thread;
 
328
connection master;
 
329
sync_slave_with_master;
 
330
#connection slave;
 
331
set global slave_exec_mode='STRICT';
 
332
 
 
333
connection master;
 
334
DELETE FROM t2 WHERE a = -2;
 
335
--echo *** slave must stop
 
336
source include/wait_for_slave_sql_to_stop.inc;
 
337
 
 
338
connection slave;
 
339
 
 
340
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
 
341
disable_query_log;
 
342
eval SELECT "$last_error" AS Last_SQL_Error;
 
343
enable_query_log;
 
344
 
 
345
set global slave_exec_mode='IDEMPOTENT';
 
346
start slave sql_thread;
 
347
connection master;
 
348
sync_slave_with_master;
 
349
#connection slave;
 
350
set global slave_exec_mode='STRICT';
 
351
 
 
352
UPDATE t1 SET a = 1 WHERE a = -1;
 
353
UPDATE t2 SET a = 1 WHERE a = -1;
 
354
 
 
355
connection master;
 
356
UPDATE t1 SET a = 1 WHERE a = -1;
 
357
 
 
358
--echo *** slave must stop
 
359
source include/wait_for_slave_sql_to_stop.inc;
 
360
 
 
361
connection slave;
 
362
 
 
363
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
 
364
disable_query_log;
 
365
eval SELECT "$last_error" AS Last_SQL_Error;
 
366
enable_query_log;
 
367
 
 
368
set global slave_exec_mode='IDEMPOTENT';
 
369
start slave sql_thread;
 
370
connection master;
 
371
sync_slave_with_master;
 
372
#connection slave;
 
373
set global slave_exec_mode='STRICT';
 
374
 
 
375
 
 
376
connection master;
 
377
UPDATE t2 SET a = 1 WHERE a = -1;
 
378
 
 
379
--echo *** slave must stop
 
380
source include/wait_for_slave_sql_to_stop.inc;
 
381
 
 
382
connection slave;
 
383
 
 
384
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
 
385
disable_query_log;
 
386
eval SELECT "$last_error" AS Last_SQL_Error;
 
387
enable_query_log;
 
388
 
 
389
set global slave_exec_mode='IDEMPOTENT';
 
390
start slave sql_thread;
 
391
connection master;
 
392
sync_slave_with_master;
 
393
#connection slave;
 
394
set global slave_exec_mode='STRICT';
 
395
 
 
396
 
 
397
# cleanup for bug#31609 tests
 
398
 
 
399
connection master;
 
400
set @@session.binlog_format= @save_binlog_format;
 
401
drop table t1,t2,ti2,ti1;
 
402
 
 
403
sync_slave_with_master;
 
404
 
 
405
 
 
406
--echo *** end of tests
 
407
 
 
408
 
 
409
 
 
410
 
 
411
 
 
412
 
 
413
 
 
414
 
 
415