Commit 8a5e5274 authored by unknown's avatar unknown
Browse files

Fix for BUG#12335 (SP replication) : New binlogging strategy for stored PROCEDUREs/FUNCTIONs.

"Interleaved SPs execution is now binlogged properly, "SELECT spfunc()" is binlogged too.
The known remaining issue is binlogging/replication of "a routine is deleted while it is executed" scenario.


mysql-test/r/rpl_sp.result:
  Fix for BUG#12335: updated test cases/results
mysql-test/t/rpl_sp.test:
  Fix for BUG#12335: updated test cases/results
sql/item.cc:
  Fix for BUG#12335 (SP replication): 
   - Added Item_name_const 'function'
   - Addede 'delete reuse' to call dtor on item reuse
sql/item.h:
  Fix for BUG#12335 (SP replication) : Added Item_name_const 'function' + code cleanup
sql/item_create.cc:
   Fix for BUG#12335 (SP replication) : Added Item_name_const 'function'
sql/item_create.h:
   Fix for BUG#12335 (SP replication) : Added Item_name_const 'function'
sql/item_func.cc:
  Fix for BUG#12335 (SP replication) : binary log is now constrolled from within execute_function.
sql/lex.h:
  Fix for BUG#12335 (SP replication) : Added Item_name_const 'function'
sql/log.cc:
  Fix for BUG#12335 (SP replication) : Added MYSQL_LOG::{start|stop}_union_events to allow
  one to temporary disable binlogging but collect a 'union' information about binlog write
  calls.
sql/mysql_priv.h:
  Fix for BUG#12335 (SP replication)
sql/sp_head.cc:
  Fix for BUG#12335 (SP replication) : Now we use different SP binlogging strategy, grep for 
  StoredRoutinesBinlogging for details
sql/sp_head.h:
  Comments added
sql/sp_pcontext.h:
  Comments added
sql/sp_rcontext.h:
  Comments added
sql/sql_class.cc:
  Fix for BUG#12335 (SP replication) : Now we use different SP binlogging strategy, grep for 
  StoredRoutinesBinlogging for details
sql/sql_class.h:
  Fix for BUG#12335 (SP replication) : Added MYSQL_LOG::{start|stop}_union_events to allow
  one to temporary disable binlogging but collect a 'union' information about binlog write
  calls.
sql/sql_delete.cc:
  Fix for BUG#12335: check THD::query_str_binlog_unsuitable when writing to binlog.
sql/sql_insert.cc:
  Fix for BUG#12335: check THD::query_str_binlog_unsuitable when writing to binlog.
sql/sql_lex.cc:
  Fix for BUG#12335 (SP replication): Add ability to extract previous returned token from
  the tokenizer.
sql/sql_lex.h:
  Fix for BUG#12335 (SP replication): Add ability to extract previous returned token from
  the tokenizer.
sql/sql_parse.cc:
  Fix for BUG#12335 (SP replication) : Now we use different SP binlogging strategy, grep for 
  StoredRoutinesBinlogging for details
sql/sql_update.cc:
  Fix for BUG#12335: check THD::query_str_binlog_unsuitable when writing to binlog.
sql/sql_yacc.yy:
  Fix for BUG#12335 (SP replication) : When creating Item_splocal, remember where it is located
  in the query.
parent 9017addf
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -60,7 +60,8 @@ set b = 8;
insert into t1 values (b);
insert into t1 values (unix_timestamp());
end
master-bin.000001	#	Query	1	#	use `mysqltest1`; call foo()
master-bin.000001	#	Query	1	#	use `mysqltest1`; insert into t1 values ( NAME_CONST('b',8))
master-bin.000001	#	Query	1	#	use `mysqltest1`; insert into t1 values (unix_timestamp())
select * from t1;
a
8
@@ -76,8 +77,10 @@ reads sql data
select * from mysqltest1.t1;
call foo2();
a
show binlog events from 605;
show binlog events from 518;
Log_name	Pos	Event_type	Server_id	End_log_pos	Info
master-bin.000001	#	Query	1	#	use `mysqltest1`; insert into t1 values ( NAME_CONST('b',8))
master-bin.000001	#	Query	1	#	use `mysqltest1`; insert into t1 values (unix_timestamp())
master-bin.000001	#	Query	1	#	use `mysqltest1`; delete from t1
master-bin.000001	#	Query	1	#	use `mysqltest1`; create procedure foo2()
not deterministic
@@ -124,7 +127,7 @@ alter procedure foo4 sql security invoker;
call foo4();
show warnings;
Level	Code	Message
show binlog events from 841;
show binlog events from 990;
Log_name	Pos	Event_type	Server_id	End_log_pos	Info
master-bin.000001	#	Query	1	#	use `mysqltest1`; drop table t1
master-bin.000001	#	Query	1	#	use `mysqltest1`; create table t1 (a int)
@@ -141,9 +144,12 @@ begin
insert into t2 values(3);
insert into t1 values (5);
end
master-bin.000001	#	Query	1	#	use `mysqltest1`; call foo3()
master-bin.000001	#	Query	1	#	use `mysqltest1`; insert into t2 values(3)
master-bin.000001	#	Query	1	#	use `mysqltest1`; insert into t1 values (15)
master-bin.000001	#	Query	1	#	use `mysqltest1`; insert into t2 values(3)
master-bin.000001	#	Query	1	#	use `mysqltest1`; alter procedure foo4 sql security invoker
master-bin.000001	#	Query	1	#	use `mysqltest1`; call foo4()
master-bin.000001	#	Query	1	#	use `mysqltest1`; insert into t2 values(3)
master-bin.000001	#	Query	1	#	use `mysqltest1`; insert into t1 values (5)
select * from t1;
a
15
@@ -160,6 +166,8 @@ a
select * from t2;
a
3
3
3
select * from mysql.proc where name="foo4" and db='mysqltest1';
db	name	type	specific_name	language	sql_data_access	is_deterministic	security_type	param_list	returns	body	definer	created	modified	sql_mode	comment
mysqltest1	foo4	PROCEDURE	foo4	SQL	CONTAINS_SQL	YES	INVOKER			begin
@@ -196,6 +204,7 @@ a
select * from t1;
a
21
20
select * from t2;
a
23
+216 −0
Original line number Diff line number Diff line
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;
drop procedure if exists p1;
drop procedure if exists p2;
drop function if exists f1;
drop table if exists t1,t2;
drop view if exists v1;
create table t1 (a int);
create procedure p1()
begin
declare spv int default 0;
while spv < 5 do
insert into t1 values(spv+1);
set spv=spv+1;
end while;
end//
call p1();
select * from t1;
a
1
2
3
4
5
delete from t1;
create procedure p2()
begin
declare a int default 4;
create table t2 as select a;
end//
call p2();
select * from t2;
a
4
select * from t2;
a
4
drop procedure p1;
drop procedure p2;
drop table t2;
create function f1(x int) returns int
begin
insert into t1 values(x);
return x+1;
end//
create procedure p1(a int, b int)
begin
declare v int default f1(5);
if (f1(6)) then
select 'yes';
end if;
set v = f1(7);
while f1(8) < 1 do 
select 'this cant be';
end while;
end//
call p1(f1(1), f1(2));
yes
yes
select * from t1;
a
1
2
5
6
7
8
create table t2(a int);
insert into t2 values (10),(11);
select a,f1(a) from t2;
a	f1(a)
10	11
11	12
insert into t2 select f1(3);
select 'master:',a from t1;
master:	a
master:	1
master:	2
master:	5
master:	6
master:	7
master:	8
master:	10
master:	11
master:	3
select 'slave:',a from t1;
slave:	a
slave:	1
slave:	2
slave:	5
slave:	6
slave:	7
slave:	8
slave:	10
slave:	11
slave:	3
drop procedure p1;
delete from t1;
delete from t2;
delete from t1;
insert into t2 values(1),(2);
create view v1 as select f1(a) from t2;
select * from v1;
f1(a)
2
3
select 'master:',a from t1;
master:	a
master:	1
master:	2
select 'slave:',a from t1;
slave:	a
slave:	1
slave:	2
drop view v1;
delete from t1;
prepare s1 from 'select f1(?)';
set @xx=123;
execute s1 using @xx;
f1(?)
124
select 'master:',a from t1;
master:	a
master:	123
select 'slave:',a from t1;
slave:	a
slave:	123
delete from t1;
create procedure p1(spv int)
begin
declare c cursor for select f1(spv) from t2;
while (spv > 2) do
open c;
fetch c into spv;
close c;
set spv= spv - 10;
end while;
end//
call p1(15);
select 'master:',a from t1;
master:	a
master:	15
master:	15
master:	6
master:	6
select 'slave:',a from t1;
slave:	a
slave:	15
slave:	15
slave:	6
slave:	6
drop procedure p1;
drop function f1;
drop table t1,t2;
create table t1 (a int);
create table t2 (a char(200));
create procedure p1()
begin
declare dummy int;
while ((select count(*) from t1) < 1) do
set dummy = sleep(1);
end while;
end//
create procedure p2()
begin
select f1();
call p1();
delete from t1 limit 1;
select f1();
call p1();
delete from t1 limit 1;
select f1();
end//
create function f1() returns int 
begin
insert into t2 values('f1-r1');
return 0;
end//
 call p2();
drop function f1//
create function f1() returns int 
begin
insert into t2 values('f1-r2');
return 0;
end//
insert into t1 values (1) //
call p1()//
drop function f1//
create function f1() returns int 
begin
insert into t2 values('f1-r3');
return 0;
end//
insert into t1 values (1) //
call p1()//
f1()
0
f1()
0
f1()
0
select * from t2;
a
f1-r1
f1-r1
f1-r1
select * from t2;
a
f1-r1
f1-r3
f1-r3
drop table t1;
+2 −2
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ create procedure foo2()
call foo2();
# verify CALL is not in binlog
--replace_column 2 # 5 #
show binlog events from 605;
show binlog events from 518;

--error 1418;
alter procedure foo2 contains sql;
@@ -147,7 +147,7 @@ show warnings;

# Check that only successful CALLs are in binlog
--replace_column 2 # 5 #
show binlog events from 841;
show binlog events from 990;

# Note that half-failed CALLs are not in binlog, which is a known
# bug. If we compare t2 on master and slave we see they differ:
+1 −0
Original line number Diff line number Diff line
--log_bin_trust_routine_creators=1
+1 −0
Original line number Diff line number Diff line
--log_bin_trust_routine_creators=1
Loading