1
by brian
clean slate |
1 |
#
|
2 |
# Test of triggers with replication
|
|
3 |
# Adding statement include due to Bug 12574
|
|
4 |
# TODO: Remove statement include once 12574 is patched
|
|
5 |
--source include/have_binlog_format_mixed_or_statement.inc |
|
6 |
--source include/master-slave.inc |
|
7 |
||
8 |
--disable_warnings |
|
9 |
DROP TABLE IF EXISTS t1; |
|
10 |
DROP TABLE IF EXISTS t2; |
|
11 |
DROP TABLE IF EXISTS t3; |
|
12 |
||
13 |
--enable_warnings |
|
14 |
||
15 |
#
|
|
16 |
# #12482: Triggers has side effects with auto_increment values
|
|
17 |
#
|
|
18 |
||
19 |
create table t1 (a int auto_increment, primary key (a), b int, rand_value double not null); |
|
20 |
create table t2 (a int auto_increment, primary key (a), b int); |
|
21 |
create table t3 (a int auto_increment, primary key (a), name varchar(64) not null, old_a int, old_b int, rand_value double not null); |
|
22 |
||
23 |
delimiter |; |
|
24 |
create trigger t1 before insert on t1 for each row |
|
25 |
begin
|
|
26 |
insert into t3 values (NULL, "t1", new.a, new.b, rand()); |
|
27 |
end| |
|
28 |
||
29 |
create trigger t2 after insert on t2 for each row |
|
30 |
begin
|
|
31 |
insert into t3 values (NULL, "t2", new.a, new.b, rand()); |
|
32 |
end| |
|
33 |
delimiter ;| |
|
34 |
||
35 |
insert into t3 values(100,"log",0,0,0); |
|
36 |
||
37 |
# Ensure we always have same random numbers
|
|
38 |
SET @@RAND_SEED1=658490765, @@RAND_SEED2=635893186; |
|
39 |
||
40 |
# Emulate that we have rows 2-9 deleted on the slave
|
|
41 |
insert into t1 values(1,1,rand()),(NULL,2,rand()); |
|
42 |
insert into t2 (b) values(last_insert_id()); |
|
43 |
insert into t2 values(3,0),(NULL,0); |
|
44 |
insert into t2 values(NULL,0),(500,0); |
|
45 |
||
46 |
select a,b, truncate(rand_value,4) from t1; |
|
47 |
select * from t2; |
|
48 |
select a,name, old_a, old_b, truncate(rand_value,4) from t3; |
|
49 |
save_master_pos; |
|
50 |
connection slave; |
|
51 |
sync_with_master; |
|
52 |
--disable_query_log |
|
53 |
select "--- On slave --" as ""; |
|
54 |
--enable_query_log |
|
55 |
select a,b, truncate(rand_value,4) from t1; |
|
56 |
select * from t2; |
|
57 |
select a,name, old_a, old_b, truncate(rand_value,4) from t3; |
|
58 |
connection master; |
|
59 |
drop table t1,t2,t3; |
|
60 |
||
61 |
#
|
|
62 |
# #12480: NOW() is not constant in a trigger
|
|
63 |
# #12481: Using NOW() in a stored function breaks statement based replication
|
|
64 |
#
|
|
65 |
||
66 |
# Start by getting a lock on 'bug12480' to be able to use get_lock() as sleep()
|
|
67 |
connect (con2,localhost,root,,); |
|
68 |
connection con2; |
|
69 |
select get_lock("bug12480",2); |
|
70 |
connection default; |
|
71 |
||
72 |
create table t1 (a datetime,b datetime, c datetime); |
|
73 |
--disable_warnings |
|
74 |
drop function if exists bug12480; |
|
75 |
--enable_warnings |
|
76 |
||
77 |
delimiter |; |
|
78 |
||
79 |
create function bug12480() returns datetime |
|
80 |
begin
|
|
81 |
set @a=get_lock("bug12480",2); |
|
82 |
return now(); |
|
83 |
end| |
|
84 |
||
85 |
create trigger t1_first before insert on t1 |
|
86 |
for each row begin |
|
87 |
set @a=get_lock("bug12480",2); |
|
88 |
set new.b= now(); |
|
89 |
set new.c= bug12480(); |
|
90 |
end
|
|
91 |
|
|
|
92 |
||
93 |
delimiter ;| |
|
94 |
insert into t1 set a = now(); |
|
95 |
select a=b && a=c from t1; |
|
96 |
let $time=`select a from t1`; |
|
97 |
||
98 |
# Check that definer attribute is replicated properly:
|
|
99 |
# - dump definers on the master;
|
|
100 |
# - wait for the slave to synchronize with the master;
|
|
101 |
# - dump definers on the slave;
|
|
102 |
||
103 |
SELECT routine_name, definer |
|
104 |
FROM information_schema.routines |
|
105 |
WHERE routine_name = 'bug12480'; |
|
106 |
||
107 |
SELECT trigger_name, definer |
|
108 |
FROM information_schema.triggers |
|
109 |
WHERE trigger_name = 't1_first'; |
|
110 |
||
111 |
save_master_pos; |
|
112 |
connection slave; |
|
113 |
sync_with_master; |
|
114 |
--disable_query_log |
|
115 |
select "--- On slave --" as ""; |
|
116 |
--enable_query_log |
|
117 |
||
118 |
# XXX: Definers of stored procedures and functions are not replicated. WL#2897
|
|
119 |
# (Complete definer support in the stored routines) addresses this issue. So,
|
|
120 |
# the result file is expected to be changed after implementation of this WL
|
|
121 |
# item.
|
|
122 |
||
123 |
SELECT routine_name, definer |
|
124 |
FROM information_schema.routines |
|
125 |
WHERE routine_name = 'bug12480'; |
|
126 |
||
127 |
SELECT trigger_name, definer |
|
128 |
FROM information_schema.triggers |
|
129 |
WHERE trigger_name = 't1_first'; |
|
130 |
||
131 |
select a=b && a=c from t1; |
|
132 |
--disable_query_log |
|
133 |
eval select a='$time' as 'test' from t1; |
|
134 |
--enable_query_log |
|
135 |
||
136 |
connection master; |
|
137 |
disconnect con2; |
|
138 |
||
139 |
truncate table t1; |
|
140 |
drop trigger t1_first; |
|
141 |
||
142 |
insert into t1 values ("2003-03-03","2003-03-03","2003-03-03"),(bug12480(),bug12480(),bug12480()),(now(),now(),now()); |
|
143 |
select a=b && a=c from t1; |
|
144 |
||
145 |
drop function bug12480; |
|
146 |
drop table t1; |
|
147 |
||
148 |
#
|
|
149 |
# #14614: Replication of tables with trigger generates error message if databases is changed
|
|
150 |
# Note. The error message is emitted by _myfree() using fprintf() to the stderr
|
|
151 |
# and because of that does not fall into the .result file.
|
|
152 |
#
|
|
153 |
||
154 |
create table t1 (i int); |
|
155 |
create table t2 (i int); |
|
156 |
||
157 |
delimiter |; |
|
158 |
create trigger tr1 before insert on t1 for each row |
|
159 |
begin
|
|
160 |
insert into t2 values (1); |
|
161 |
end| |
|
162 |
delimiter ;| |
|
163 |
||
164 |
create database other; |
|
165 |
use other; |
|
166 |
insert into test.t1 values (1); |
|
167 |
||
168 |
save_master_pos; |
|
169 |
connection slave; |
|
170 |
sync_with_master; |
|
171 |
||
172 |
connection master; |
|
173 |
use test; |
|
174 |
drop table t1,t2; |
|
175 |
drop database other; |
|
176 |
||
177 |
||
178 |
#
|
|
179 |
# Test specific triggers including SELECT into var with replication
|
|
180 |
# BUG#13227:
|
|
181 |
# slave performs an update to the replicatable table, t1,
|
|
182 |
# and modifies its local data, t3, by mean of its local trigger that uses
|
|
183 |
# another local table t2.
|
|
184 |
# Expected values are commented into queries.
|
|
185 |
#
|
|
186 |
# Body of the test executes in a loop since the problem occurred randomly.
|
|
187 |
#
|
|
188 |
||
189 |
let $max_rows=5; |
|
190 |
let $rnd=10; |
|
191 |
||
192 |
--echo test case for BUG#13227 |
|
193 |
while ($rnd) |
|
194 |
{
|
|
195 |
--echo ------------------- |
|
196 |
echo $rnd; |
|
197 |
--echo ------------------- |
|
198 |
||
199 |
### SETUP
|
|
200 |
||
201 |
--disable_warnings |
|
202 |
connection master; |
|
203 |
eval drop table if exists t1$rnd; |
|
204 |
connection slave; |
|
205 |
eval drop table if exists t2$rnd,t3$rnd; |
|
206 |
--enable_warnings |
|
207 |
||
208 |
connection master; |
|
209 |
eval create table t1$rnd (f1 int) /* 2 replicate */; |
|
210 |
let $i=$max_rows; |
|
211 |
while ($i) |
|
212 |
{
|
|
213 |
eval insert into t1$rnd values (-$i); |
|
214 |
dec $i; |
|
215 |
}
|
|
216 |
||
217 |
sync_slave_with_master; |
|
218 |
#connection slave;
|
|
219 |
eval select * from t1$rnd; |
|
220 |
delimiter |; |
|
221 |
eval create trigger trg1$rnd before update on t1$rnd /* slave local */ |
|
222 |
for each row |
|
223 |
begin
|
|
224 |
DECLARE r integer; |
|
225 |
SELECT f2 INTO r FROM t2$rnd where f1=NEW.f1; |
|
226 |
INSERT INTO t3$rnd values (r); |
|
227 |
end| |
|
228 |
delimiter ;| |
|
229 |
eval create table t2$rnd (f1 int, f2 int) /* slave local */; |
|
230 |
eval create table t3$rnd (f3 int) /* slave local */; |
|
231 |
let $i=$max_rows; |
|
232 |
while ($i) |
|
233 |
{
|
|
234 |
eval insert into t2$rnd values ($i, $i*100); |
|
235 |
dec $i; |
|
236 |
}
|
|
237 |
||
238 |
### Test
|
|
239 |
||
240 |
#connection slave;
|
|
241 |
||
242 |
# trigger works as specified when updates from slave
|
|
243 |
eval select * from t2$rnd; |
|
244 |
eval UPDATE t1$rnd SET f1=$max_rows where f1=-$max_rows; |
|
245 |
eval SELECT * from t1$rnd /* must be f1 $max_rows, 1 - $max_rows 2 - $max_rows ... -1 */; |
|
246 |
eval SELECT * from t3$rnd /* must be f3 $max_rows*100 */; |
|
247 |
||
248 |
connection master; |
|
249 |
let $i=$max_rows; |
|
250 |
while ($i) |
|
251 |
{
|
|
252 |
eval UPDATE t1$rnd SET f1=$i where f1=-$i; |
|
253 |
dec $i; |
|
254 |
}
|
|
255 |
||
256 |
sync_slave_with_master; |
|
257 |
#connection slave;
|
|
258 |
eval SELECT * from t1$rnd /* must be f1 $max_rows ... 1 */; |
|
259 |
eval SELECT * from t3$rnd /* must be f3 $max_rows * 100 ... 100 */; |
|
260 |
||
261 |
### CLEANUP
|
|
262 |
#connection slave;
|
|
263 |
eval drop trigger trg1$rnd; |
|
264 |
eval drop table t2$rnd,t3$rnd; |
|
265 |
||
266 |
connection master; |
|
267 |
eval drop table t1$rnd; |
|
268 |
||
269 |
dec $rnd; |
|
270 |
}
|
|
271 |
||
272 |
||
273 |
#
|
|
274 |
# BUG#16266: Definer is not fully qualified error during replication.
|
|
275 |
#
|
|
276 |
# The idea of this test is to emulate replication of a trigger from the old
|
|
277 |
# master (master w/o "DEFINER in triggers" support) to the new slave and check
|
|
278 |
# that:
|
|
279 |
# 1. the trigger on the slave will be replicated w/o errors;
|
|
280 |
# 2. the trigger on the slave will be non-SUID (will have no DEFINER);
|
|
281 |
# 3. the trigger can be activated later on the slave w/o errors.
|
|
282 |
#
|
|
283 |
# In order to emulate this kind of replication, we make the slave playing the binlog,
|
|
284 |
# recorded by 5.0.16 master. This binlog contains the following statements:
|
|
285 |
# CREATE TABLE t1(c INT);
|
|
286 |
# CREATE TABLE t2(s CHAR(200));
|
|
287 |
# CREATE TRIGGER trg1 AFTER INSERT ON t1
|
|
288 |
# FOR EACH ROW
|
|
289 |
# INSERT INTO t2 VALUES(CURRENT_USER());
|
|
290 |
# INSERT INTO t1 VALUES(1);
|
|
291 |
#
|
|
292 |
||
293 |
# 1. Check that the trigger's replication is succeeded.
|
|
294 |
||
295 |
# Stop the slave.
|
|
296 |
||
297 |
connection slave; |
|
298 |
STOP SLAVE; |
|
299 |
||
300 |
# Replace master's binlog.
|
|
301 |
||
302 |
connection master; |
|
303 |
FLUSH LOGS; |
|
304 |
exec cp $MYSQL_TEST_DIR/std_data/bug16266.000001 $MYSQLTEST_VARDIR/log/master-bin.000001; |
|
305 |
||
306 |
# Make the slave to replay the new binlog.
|
|
307 |
||
308 |
connection slave; |
|
309 |
RESET SLAVE; |
|
310 |
START SLAVE; |
|
311 |
||
312 |
SELECT MASTER_POS_WAIT('master-bin.000001', 513) >= 0; |
|
313 |
||
314 |
# Check that the replication succeeded.
|
|
315 |
||
316 |
SHOW TABLES LIKE 't_'; |
|
317 |
SHOW TRIGGERS; |
|
318 |
SELECT * FROM t1; |
|
319 |
SELECT * FROM t2; |
|
320 |
||
321 |
# 2. Check that the trigger is non-SUID on the slave;
|
|
322 |
# 3. Check that the trigger can be activated on the slave.
|
|
323 |
#
|
|
324 |
# We disable warnings here since it affects the result file in
|
|
325 |
# different ways depending on the mode being used.
|
|
326 |
||
327 |
disable_warnings; |
|
328 |
INSERT INTO t1 VALUES(2); |
|
329 |
enable_warnings; |
|
330 |
||
331 |
SELECT * FROM t1; |
|
332 |
SELECT * FROM t2; |
|
333 |
||
334 |
# That's all, cleanup.
|
|
335 |
||
336 |
DROP TRIGGER trg1; |
|
337 |
DROP TABLE t1; |
|
338 |
DROP TABLE t2; |
|
339 |
||
340 |
STOP SLAVE; |
|
341 |
RESET SLAVE; |
|
342 |
||
343 |
# The master should be clean.
|
|
344 |
||
345 |
connection master; |
|
346 |
SHOW TABLES LIKE 't_'; |
|
347 |
SHOW TRIGGERS; |
|
348 |
||
349 |
RESET MASTER; |
|
350 |
||
351 |
# Restart slave.
|
|
352 |
||
353 |
connection slave; |
|
354 |
START SLAVE; |
|
355 |
||
356 |
||
357 |
#
|
|
358 |
# BUG#20438: CREATE statements for views, stored routines and triggers can be
|
|
359 |
# not replicable.
|
|
360 |
#
|
|
361 |
||
362 |
--echo |
|
363 |
--echo ---> Test for BUG#20438 |
|
364 |
||
365 |
# Prepare environment.
|
|
366 |
||
367 |
--echo |
|
368 |
--echo ---> Preparing environment... |
|
369 |
--echo ---> connection: master |
|
370 |
--connection master |
|
371 |
||
372 |
--disable_warnings |
|
373 |
DROP TABLE IF EXISTS t1; |
|
374 |
DROP TABLE IF EXISTS t2; |
|
375 |
--enable_warnings |
|
376 |
||
377 |
--echo |
|
378 |
--echo ---> Synchronizing slave with master... |
|
379 |
||
380 |
--save_master_pos |
|
381 |
--connection slave |
|
382 |
--sync_with_master |
|
383 |
||
384 |
--echo |
|
385 |
--echo ---> connection: master |
|
386 |
--connection master |
|
387 |
||
388 |
# Test.
|
|
389 |
||
390 |
--echo |
|
391 |
--echo ---> Creating objects... |
|
392 |
||
393 |
CREATE TABLE t1(c INT); |
|
394 |
CREATE TABLE t2(c INT); |
|
395 |
||
396 |
/*!50003 CREATE TRIGGER t1_bi BEFORE INSERT ON t1 |
|
397 |
FOR EACH ROW |
|
398 |
INSERT INTO t2 VALUES(NEW.c * 10) */; |
|
399 |
||
400 |
--echo |
|
401 |
--echo ---> Inserting value... |
|
402 |
||
403 |
INSERT INTO t1 VALUES(1); |
|
404 |
||
405 |
--echo |
|
406 |
--echo ---> Checking on master... |
|
407 |
||
408 |
SELECT * FROM t1; |
|
409 |
SELECT * FROM t2; |
|
410 |
||
411 |
--echo |
|
412 |
--echo ---> Synchronizing slave with master... |
|
413 |
||
414 |
--save_master_pos |
|
415 |
--connection slave |
|
416 |
--sync_with_master |
|
417 |
||
418 |
--echo ---> connection: master |
|
419 |
||
420 |
--echo |
|
421 |
--echo ---> Checking on slave... |
|
422 |
||
423 |
SELECT * FROM t1; |
|
424 |
SELECT * FROM t2; |
|
425 |
||
426 |
# Cleanup.
|
|
427 |
||
428 |
--echo |
|
429 |
--echo ---> connection: master |
|
430 |
--connection master |
|
431 |
||
432 |
--echo |
|
433 |
--echo ---> Cleaning up... |
|
434 |
||
435 |
DROP TABLE t1; |
|
436 |
DROP TABLE t2; |
|
437 |
||
438 |
--save_master_pos |
|
439 |
--connection slave |
|
440 |
--sync_with_master |
|
441 |
--connection master |
|
442 |
||
443 |
#
|
|
444 |
# BUG#23703: DROP TRIGGER needs an IF EXISTS
|
|
445 |
#
|
|
446 |
||
447 |
connection master; |
|
448 |
||
449 |
--disable_warnings |
|
450 |
drop table if exists t1; |
|
451 |
--enable_warnings |
|
452 |
||
453 |
create table t1(a int, b varchar(50)); |
|
454 |
||
455 |
-- error ER_TRG_DOES_NOT_EXIST |
|
456 |
drop trigger not_a_trigger; |
|
457 |
||
458 |
drop trigger if exists not_a_trigger; |
|
459 |
||
460 |
create trigger t1_bi before insert on t1 |
|
461 |
for each row set NEW.b := "In trigger t1_bi"; |
|
462 |
||
463 |
insert into t1 values (1, "a"); |
|
464 |
drop trigger if exists t1_bi; |
|
465 |
insert into t1 values (2, "b"); |
|
466 |
drop trigger if exists t1_bi; |
|
467 |
insert into t1 values (3, "c"); |
|
468 |
||
469 |
select * from t1; |
|
470 |
||
471 |
save_master_pos; |
|
472 |
connection slave; |
|
473 |
sync_with_master; |
|
474 |
||
475 |
select * from t1; |
|
476 |
||
477 |
connection master; |
|
478 |
||
479 |
drop table t1; |
|
480 |
||
481 |
#
|
|
482 |
# End of tests
|
|
483 |
#
|
|
484 |
save_master_pos; |
|
485 |
connection slave; |
|
486 |
sync_with_master; |