mariadb/mysql-test/r/rpl_user_variables.result
unknown e52ec3e6d5 BUG#20141 "User-defined variables are not replicated properly for SF/
Triggers in SBR mode."
BUG#14914 "SP: Uses of session variables in routines are not always
           replicated"
BUG#25167 "Dupl. usage of user-variables in trigger/function is not
           replicated correctly"

User-defined variables used inside of stored functions/triggers in
statements which did not update tables directly were not replicated.
We also had problems with replication of user-defined variables which
were used in triggers (or stored functions called from table-updating
statements) more than once.

This patch addresses the first issue by enabling logging of all
references to user-defined variables in triggers/stored functions
and not only references from table-updating statements.

The second issue stemmed from the fact that for user-defined
variables used from triggers or stored functions called from
table-updating statements we were writing binlog events for each
reference instead of only one event for the first reference.
This problem is already solved for stored functions called from
non-updating statements with help of "event unioning" mechanism.
So the patch simply extends this mechanism to the case affected.
It also fixes small problem in this mechanism which caused wrong
logging of references to user-variables in cases when non-updating
statement called several stored functions which used the same
variable and some of these function calls were omitted from binlog
as they were not updating any tables.


mysql-test/r/rpl_user_variables.result:
  BUG#20141 - User-defined variables are not replicated properly for SF/Triggers in SBR mode.
  This patch adds the correct results for execution of the added test procedures to the
  rpl_user_variables test.
mysql-test/t/rpl_user_variables.test:
  BUG#20141 - User-defined variables are not replicated properly for SF/Triggers in SBR mode.
  This patch adds additional tests to the rpl_user_variables test that test many of the
  different ways user-defined variables can be required to be replicated.
sql/item_func.cc:
  BUG#20141 - User-defined variables are not replicated properly for SF/Triggers in SBR mode.
  To properly log accesses to user-defined variables from stored functions/triggers,
  the get_var_with_binlog() method needs to log references to such variables even from 
  non-table-updating statements within them.
sql/log.cc:
  BUG#20141 - User-defined variables are not replicated properly for SF/Triggers in SBR mode.
  This patch modifies the start_union_events method to accept the query id from a parameter.
  This allows callers to set the query_id to the id of the sub statement such as a trigger
  or stored function. Which permits the code to identify when a user defined variable has
  been used by the statement and this already present in THD::user_var_event.
  
  Note:
  The changes to sql_class.cc, sp_head.cc, and log.cc are designed to allow the proper 
  replication of access to user-defined variables under a special test case (the last case 
  shown in rpl_user_variables.test).
sql/sp_head.cc:
  BUG#20141 - User-defined variables are not replicated properly for SF/Triggers in SBR mode.
  This patch modifies the code to allow for cases where events for function calls have
  a separate union for each event and thus cannot use the query_id of the caller as the
  start of the union. Thus, we use an artifically created query_id to set the start of 
  the events.
  
  Note:
  The changes to sql_class.cc, sp_head.cc, and log.cc are designed to allow the proper 
  replication of access to user-defined variables under a special test case (the last case 
  shown in rpl_user_variables.test).
sql/sql_class.cc:
  BUG#20141 - User-defined variables are not replicated properly for SF/Triggers in SBR mode.
  This patch adds the query_id parameter to the calls to mysql_bin_log.start_union_events().
  
  Note:
  The changes to sql_class.cc, sp_head.cc, and log.cc are designed to allow the proper 
  replication of access to user-defined variables under a special test case (the last case 
  shown in rpl_user_variables.test).
sql/sql_class.h:
  BUG#20141 - User-defined variables are not replicated properly for SF/Triggers in SBR mode.
  This patch adds the query_id parameter to the calls to mysql_bin_log.start_union_events().
2007-02-23 12:58:56 -05:00

287 lines
6.4 KiB
Text

stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
reset master;
create table t1(n char(30));
set @i1:=12345678901234, @i2:=-12345678901234, @i3:=0, @i4:=-1;
set @s1:='This is a test', @r1:=12.5, @r2:=-12.5;
set @n1:=null;
set @s2:='', @s3:='abc\'def', @s4:= 'abc\\def', @s5:= 'abc''def';
insert into t1 values (@i1), (@i2), (@i3), (@i4);
insert into t1 values (@r1), (@r2);
insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5);
insert into t1 values (@n1);
insert into t1 values (@n2);
insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1);
insert into t1 values (@a+(@b:=@a+1));
set @q:='abc';
insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'));
set @a:=5;
insert into t1 values (@a),(@a);
insert into t1 values (@a),(@a),(@a*5);
select * from t1;
n
12345678901234
-12345678901234
0
-1
12.5
-12.5
This is a test
abc'def
abc\def
abc'def
NULL
NULL
0
1
2
5
abc
abcn1
abcn1n2
5
5
NULL
NULL
NULL
select * from t1;
n
12345678901234
-12345678901234
0
-1
12.5
-12.5
This is a test
abc'def
abc\def
abc'def
NULL
NULL
0
1
2
5
abc
abcn1
abcn1n2
5
5
NULL
NULL
NULL
show binlog events from 98;
Log_name Pos Event_type Server_id End_log_pos Info
slave-bin.000001 # Query 1 # use `test`; create table t1(n char(30))
slave-bin.000001 # User var 2 # @`i1`=12345678901234
slave-bin.000001 # User var 2 # @`i2`=-12345678901234
slave-bin.000001 # User var 2 # @`i3`=0
slave-bin.000001 # User var 2 # @`i4`=-1
slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@i1), (@i2), (@i3), (@i4)
slave-bin.000001 # User var 2 # @`r1`=12.5
slave-bin.000001 # User var 2 # @`r2`=-12.5
slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@r1), (@r2)
slave-bin.000001 # User var 2 # @`s1`=_latin1 0x5468697320697320612074657374 COLLATE latin1_swedish_ci
slave-bin.000001 # User var 2 # @`s2`=_latin1 "" COLLATE latin1_swedish_ci
slave-bin.000001 # User var 2 # @`s3`=_latin1 0x61626327646566 COLLATE latin1_swedish_ci
slave-bin.000001 # User var 2 # @`s4`=_latin1 0x6162635C646566 COLLATE latin1_swedish_ci
slave-bin.000001 # User var 2 # @`s5`=_latin1 0x61626327646566 COLLATE latin1_swedish_ci
slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5)
slave-bin.000001 # User var 2 # @`n1`=NULL
slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@n1)
slave-bin.000001 # User var 2 # @`n2`=NULL
slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@n2)
slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1)
slave-bin.000001 # User var 2 # @`a`=2
slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@a+(@b:=@a+1))
slave-bin.000001 # User var 2 # @`q`=_latin1 0x616263 COLLATE latin1_swedish_ci
slave-bin.000001 # Query 1 # use `test`; insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'))
slave-bin.000001 # User var 2 # @`a`=5
slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@a),(@a)
slave-bin.000001 # User var 2 # @`a`=NULL
slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@a),(@a),(@a*5)
insert into t1 select * FROM (select @var1 union select @var2) AS t2;
drop table t1;
End of 4.1 tests.
DROP TABLE IF EXISTS t20;
DROP TABLE IF EXISTS t21;
DROP PROCEDURE IF EXISTS test.insert;
CREATE TABLE t20 (a VARCHAR(20));
CREATE TABLE t21 (a VARCHAR(20));
CREATE PROCEDURE test.insert()
BEGIN
IF (@VAR)
THEN
INSERT INTO test.t20 VALUES ('SP_TRUE');
ELSE
INSERT INTO test.t20 VALUES ('SP_FALSE');
END IF;
END|
CREATE TRIGGER test.insert_bi BEFORE INSERT
ON test.t20 FOR EACH ROW
BEGIN
IF (@VAR)
THEN
INSERT INTO test.t21 VALUES ('TRIG_TRUE');
ELSE
INSERT INTO test.t21 VALUES ('TRIG_FALSE');
END IF;
END|
SET @VAR=0;
CALL test.insert();
SET @VAR=1;
CALL test.insert();
On master: Check the tables for correct data
SELECT * FROM t20;
a
SP_FALSE
SP_TRUE
SELECT * FROM t21;
a
TRIG_FALSE
TRIG_TRUE
On slave: Check the tables for correct data and it matches master
SELECT * FROM t20;
a
SP_FALSE
SP_TRUE
SELECT * FROM t21;
a
TRIG_FALSE
TRIG_TRUE
DROP TABLE t20;
DROP TABLE t21;
DROP PROCEDURE test.insert;
DROP TABLE IF EXISTS t1;
DROP FUNCTION IF EXISTS test.square;
CREATE TABLE t1 (i INT);
CREATE FUNCTION test.square() RETURNS INTEGER DETERMINISTIC RETURN (@var * @var);
SET @var = 1;
INSERT INTO t1 VALUES (square());
SET @var = 2;
INSERT INTO t1 VALUES (square());
SET @var = 3;
INSERT INTO t1 VALUES (square());
SET @var = 4;
INSERT INTO t1 VALUES (square());
SET @var = 5;
INSERT INTO t1 VALUES (square());
On master: Retrieve the values from the table
SELECT * FROM t1;
i
1
4
9
16
25
On slave: Retrieve the values from the table and verify they are the same as on master
SELECT * FROM t1;
i
1
4
9
16
25
DROP TABLE t1;
DROP FUNCTION test.square;
DROP TABLE IF EXISTS t1;
DROP FUNCTION IF EXISTS f1;
DROP FUNCTION IF EXISTS f2;
CREATE TABLE t1(a int);
CREATE FUNCTION f1() returns int deterministic
BEGIN
return @a;
END |
CREATE FUNCTION f2() returns int deterministic
BEGIN
IF (@b > 0) then
SET @c = (@a + @b);
else
SET @c = (@a - 1);
END if;
return @c;
END |
SET @a=500;
INSERT INTO t1 values(f1());
SET @b = 125;
SET @c = 1;
INSERT INTO t1 values(f2());
On master: Retrieve the values from the table
SELECT * from t1;
a
500
625
On slave: Check the tables for correct data and it matches master
SELECT * from t1;
a
500
625
DROP TABLE t1;
DROP FUNCTION f1;
DROP FUNCTION f2;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1 (i int);
CREATE TABLE t2 (k int);
CREATE trigger t1_bi before INSERT on t1 for each row
BEGIN
INSERT INTO t2 values (@a);
SET @a:=42;
INSERT INTO t2 values (@a);
END |
SET @a:=100;
INSERT INTO t1 values (5);
On master: Check to see that data was inserted correctly in both tables
SELECT * from t1;
i
5
SELECT * from t2;
k
100
42
On slave: Check the tables for correct data and it matches master
SELECT * from t1;
i
5
SELECT * from t2;
k
100
42
End of 5.0 tests.
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE IF EXISTS t1;
DROP FUNCTION IF EXISTS f1;
DROP FUNCTION IF EXISTS f2;
CREATE TABLE t1 (i INT);
CREATE FUNCTION f1() RETURNS INT RETURN @a;
CREATE FUNCTION f2() RETURNS INT
BEGIN
INSERT INTO t1 VALUES (10 + @a);
RETURN 0;
END|
SET @a:=123;
SELECT f1(), f2();
f1() f2()
123 0
On master: Check to see that data was inserted correctly
INSERT INTO t1 VALUES(f1());
SELECT * FROM t1;
i
133
123
On slave: Check the table for correct data and it matches master
SELECT * FROM t1;
i
133
123
DROP FUNCTION f1;
DROP FUNCTION f2;
DROP TABLE t1;
stop slave;