WL#2977 and WL#2712 global and session-level variable to set the binlog format (row/statement),
and new binlog format called "mixed" (which is statement-based except if only row-based is correct,
in this cset it means if UDF or UUID is used; more cases could be added in later 5.1 release):
SET GLOBAL|SESSION BINLOG_FORMAT=row|statement|mixed|default;
the global default is statement unless cluster is enabled (then it's row) as in 5.1-alpha.
It's not possible to use SET on this variable if a session is currently in row-based mode and has open temporary tables (because CREATE
TEMPORARY TABLE was not binlogged so temp table is not known on slave), or if NDB is enabled (because
NDB does not support such change on-the-fly, though it will later), of if in a stored function (see below).
The added tests test the possibility or impossibility to SET, their effects, and the mixed mode,
including in prepared statements and in stored procedures and functions.
Caveats:
a) The mixed mode will not work for stored functions: in mixed mode, a stored function will
always be binlogged as one call and in a statement-based way (e.g. INSERT VALUES(myfunc()) or SELECT myfunc()).
b) for the same reason, changing the thread's binlog format inside a stored function is
refused with an error message.
c) the same problems apply to triggers; implementing b) for triggers will be done later (will ask
Dmitri).
Additionally, as the binlog format is now changeable by each user for his session, I remove the implication
which was done at startup, where row-based automatically set log-bin-trust-routine-creators to 1
(not possible anymore as a user can now switch to stmt-based and do nasty things again), and automatically
set --innodb-locks-unsafe-for-binlog to 1 (was anyway theoretically incorrect as it disabled
phantom protection).
Plus fixes for compiler warnings.
2006-02-25 22:21:03 +01:00
|
|
|
-- source include/have_binlog_format_row.inc
|
|
|
|
-- source include/master-slave.inc
|
|
|
|
|
|
|
|
connection master;
|
|
|
|
--disable_warnings
|
|
|
|
drop database if exists mysqltest1;
|
|
|
|
create database mysqltest1;
|
|
|
|
--enable_warnings
|
|
|
|
use mysqltest1;
|
|
|
|
|
|
|
|
show global variables like "binlog_format%";
|
|
|
|
show session variables like "binlog_format%";
|
|
|
|
select @@global.binlog_format, @@session.binlog_format;
|
|
|
|
|
|
|
|
CREATE TABLE t1 (a varchar(100));
|
|
|
|
|
|
|
|
prepare stmt1 from 'insert into t1 select concat(UUID(),?)';
|
|
|
|
set @string="emergency";
|
|
|
|
insert into t1 values("work");
|
|
|
|
execute stmt1 using @string;
|
|
|
|
deallocate prepare stmt1;
|
|
|
|
|
|
|
|
prepare stmt1 from 'insert into t1 select ?';
|
|
|
|
insert into t1 values(concat(UUID(),"work"));
|
|
|
|
execute stmt1 using @string;
|
|
|
|
deallocate prepare stmt1;
|
|
|
|
|
|
|
|
insert into t1 values(concat("for",UUID()));
|
|
|
|
insert into t1 select "yesterday";
|
|
|
|
|
|
|
|
# verify that temp tables prevent a switch to SBR
|
|
|
|
create temporary table tmp(a char(3));
|
|
|
|
insert into tmp values("see");
|
|
|
|
--error ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR
|
|
|
|
set binlog_format=statement;
|
|
|
|
insert into t1 select * from tmp;
|
|
|
|
drop temporary table tmp;
|
|
|
|
|
|
|
|
# Now we go to SBR
|
|
|
|
set binlog_format=statement;
|
|
|
|
show global variables like "binlog_format%";
|
|
|
|
show session variables like "binlog_format%";
|
|
|
|
select @@global.binlog_format, @@session.binlog_format;
|
|
|
|
set global binlog_format=statement;
|
|
|
|
show global variables like "binlog_format%";
|
|
|
|
show session variables like "binlog_format%";
|
|
|
|
select @@global.binlog_format, @@session.binlog_format;
|
|
|
|
|
|
|
|
prepare stmt1 from 'insert into t1 select ?';
|
|
|
|
set @string="emergency";
|
|
|
|
insert into t1 values("work");
|
|
|
|
execute stmt1 using @string;
|
|
|
|
deallocate prepare stmt1;
|
|
|
|
|
|
|
|
prepare stmt1 from 'insert into t1 select ?';
|
|
|
|
insert into t1 values("work");
|
|
|
|
execute stmt1 using @string;
|
|
|
|
deallocate prepare stmt1;
|
|
|
|
|
|
|
|
insert into t1 values("for");
|
|
|
|
insert into t1 select "yesterday";
|
|
|
|
|
|
|
|
# test SET DEFAULT (=statement at this point of test)
|
|
|
|
set binlog_format=default;
|
|
|
|
select @@global.binlog_format, @@session.binlog_format;
|
|
|
|
# due to cluster it's hard to set back to default
|
|
|
|
--error ER_NO_DEFAULT
|
|
|
|
set global binlog_format=default;
|
|
|
|
select @@global.binlog_format, @@session.binlog_format;
|
|
|
|
|
|
|
|
prepare stmt1 from 'insert into t1 select ?';
|
|
|
|
set @string="emergency";
|
|
|
|
insert into t1 values("work");
|
|
|
|
execute stmt1 using @string;
|
|
|
|
deallocate prepare stmt1;
|
|
|
|
|
|
|
|
prepare stmt1 from 'insert into t1 select ?';
|
|
|
|
insert into t1 values("work");
|
|
|
|
execute stmt1 using @string;
|
|
|
|
deallocate prepare stmt1;
|
|
|
|
|
|
|
|
insert into t1 values("for");
|
|
|
|
insert into t1 select "yesterday";
|
|
|
|
|
|
|
|
# and now the mixed mode
|
|
|
|
|
|
|
|
set binlog_format=mixed;
|
|
|
|
select @@global.binlog_format, @@session.binlog_format;
|
|
|
|
set global binlog_format=mixed;
|
|
|
|
select @@global.binlog_format, @@session.binlog_format;
|
|
|
|
|
|
|
|
prepare stmt1 from 'insert into t1 select concat(UUID(),?)';
|
|
|
|
set @string="emergency";
|
|
|
|
insert into t1 values("work");
|
|
|
|
execute stmt1 using @string;
|
|
|
|
deallocate prepare stmt1;
|
|
|
|
|
|
|
|
prepare stmt1 from 'insert into t1 select ?';
|
|
|
|
insert into t1 values(concat(UUID(),"work"));
|
|
|
|
execute stmt1 using @string;
|
|
|
|
deallocate prepare stmt1;
|
|
|
|
|
|
|
|
insert into t1 values(concat("for",UUID()));
|
|
|
|
insert into t1 select "yesterday";
|
|
|
|
|
|
|
|
prepare stmt1 from 'insert into t1 select ?';
|
|
|
|
insert into t1 values(concat(UUID(),"work"));
|
|
|
|
execute stmt1 using @string;
|
|
|
|
deallocate prepare stmt1;
|
|
|
|
|
|
|
|
insert into t1 values(concat("for",UUID()));
|
|
|
|
insert into t1 select "yesterday";
|
|
|
|
|
2006-03-13 15:34:30 +01:00
|
|
|
# Test of CREATE TABLE SELECT
|
|
|
|
|
|
|
|
create table t2 select UUID();
|
|
|
|
create table t3 select 1 union select UUID();
|
|
|
|
create table t4 select * from t1 where 3 in (select 1 union select 2 union select UUID() union select 3);
|
|
|
|
create table t5 select * from t1 where 3 in (select 1 union select 2 union select curdate() union select 3);
|
|
|
|
# what if UUID() is first:
|
|
|
|
insert into t5 select UUID() from t1 where 3 in (select 1 union select 2 union select 3 union select * from t4);
|
|
|
|
|
WL#2977 and WL#2712 global and session-level variable to set the binlog format (row/statement),
and new binlog format called "mixed" (which is statement-based except if only row-based is correct,
in this cset it means if UDF or UUID is used; more cases could be added in later 5.1 release):
SET GLOBAL|SESSION BINLOG_FORMAT=row|statement|mixed|default;
the global default is statement unless cluster is enabled (then it's row) as in 5.1-alpha.
It's not possible to use SET on this variable if a session is currently in row-based mode and has open temporary tables (because CREATE
TEMPORARY TABLE was not binlogged so temp table is not known on slave), or if NDB is enabled (because
NDB does not support such change on-the-fly, though it will later), of if in a stored function (see below).
The added tests test the possibility or impossibility to SET, their effects, and the mixed mode,
including in prepared statements and in stored procedures and functions.
Caveats:
a) The mixed mode will not work for stored functions: in mixed mode, a stored function will
always be binlogged as one call and in a statement-based way (e.g. INSERT VALUES(myfunc()) or SELECT myfunc()).
b) for the same reason, changing the thread's binlog format inside a stored function is
refused with an error message.
c) the same problems apply to triggers; implementing b) for triggers will be done later (will ask
Dmitri).
Additionally, as the binlog format is now changeable by each user for his session, I remove the implication
which was done at startup, where row-based automatically set log-bin-trust-routine-creators to 1
(not possible anymore as a user can now switch to stmt-based and do nasty things again), and automatically
set --innodb-locks-unsafe-for-binlog to 1 (was anyway theoretically incorrect as it disabled
phantom protection).
Plus fixes for compiler warnings.
2006-02-25 22:21:03 +01:00
|
|
|
# inside a stored procedure (inside a function or trigger won't
|
|
|
|
# work)
|
|
|
|
|
|
|
|
delimiter |;
|
|
|
|
create procedure foo()
|
|
|
|
begin
|
|
|
|
insert into t1 values("work");
|
|
|
|
insert into t1 values(concat("for",UUID()));
|
|
|
|
insert into t1 select "yesterday";
|
|
|
|
end|
|
|
|
|
create procedure foo2()
|
|
|
|
begin
|
|
|
|
insert into t1 values(concat("emergency",UUID()));
|
|
|
|
insert into t1 values("work");
|
|
|
|
insert into t1 values(concat("for",UUID()));
|
|
|
|
set session binlog_format=row; # accepted for stored procs
|
|
|
|
insert into t1 values("more work");
|
|
|
|
set session binlog_format=mixed;
|
|
|
|
end|
|
|
|
|
create function foo3() returns bigint unsigned
|
|
|
|
begin
|
|
|
|
set session binlog_format=row; # rejected for stored funcs
|
|
|
|
insert into t1 values("alarm");
|
|
|
|
return 100;
|
|
|
|
end|
|
|
|
|
delimiter ;|
|
|
|
|
call foo();
|
|
|
|
call foo2();
|
|
|
|
|
2006-03-13 15:34:30 +01:00
|
|
|
# test that can't SET in a stored function
|
WL#2977 and WL#2712 global and session-level variable to set the binlog format (row/statement),
and new binlog format called "mixed" (which is statement-based except if only row-based is correct,
in this cset it means if UDF or UUID is used; more cases could be added in later 5.1 release):
SET GLOBAL|SESSION BINLOG_FORMAT=row|statement|mixed|default;
the global default is statement unless cluster is enabled (then it's row) as in 5.1-alpha.
It's not possible to use SET on this variable if a session is currently in row-based mode and has open temporary tables (because CREATE
TEMPORARY TABLE was not binlogged so temp table is not known on slave), or if NDB is enabled (because
NDB does not support such change on-the-fly, though it will later), of if in a stored function (see below).
The added tests test the possibility or impossibility to SET, their effects, and the mixed mode,
including in prepared statements and in stored procedures and functions.
Caveats:
a) The mixed mode will not work for stored functions: in mixed mode, a stored function will
always be binlogged as one call and in a statement-based way (e.g. INSERT VALUES(myfunc()) or SELECT myfunc()).
b) for the same reason, changing the thread's binlog format inside a stored function is
refused with an error message.
c) the same problems apply to triggers; implementing b) for triggers will be done later (will ask
Dmitri).
Additionally, as the binlog format is now changeable by each user for his session, I remove the implication
which was done at startup, where row-based automatically set log-bin-trust-routine-creators to 1
(not possible anymore as a user can now switch to stmt-based and do nasty things again), and automatically
set --innodb-locks-unsafe-for-binlog to 1 (was anyway theoretically incorrect as it disabled
phantom protection).
Plus fixes for compiler warnings.
2006-02-25 22:21:03 +01:00
|
|
|
--error ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT
|
|
|
|
select foo3();
|
|
|
|
select * from t1 where a="alarm";
|
|
|
|
|
2006-03-13 15:34:30 +01:00
|
|
|
# If you want to do manual testing of the mixed mode regarding UDFs (not
|
|
|
|
# testable automatically as quite platform- and compiler-dependent),
|
|
|
|
# you just need to set the variable below to 1, and to
|
|
|
|
# "make udf_example.so" in sql/, and to copy sql/udf_example.so to
|
|
|
|
# MYSQL_TEST_DIR/lib/mysql.
|
|
|
|
let $you_want_to_test_UDF=0;
|
|
|
|
if ($you_want_to_test_UDF)
|
|
|
|
{
|
|
|
|
CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so';
|
|
|
|
prepare stmt1 from 'insert into t1 select metaphon(?)';
|
|
|
|
set @string="emergency";
|
|
|
|
insert into t1 values("work");
|
|
|
|
execute stmt1 using @string;
|
|
|
|
deallocate prepare stmt1;
|
|
|
|
prepare stmt1 from 'insert into t1 select ?';
|
|
|
|
insert into t1 values(metaphon("work"));
|
|
|
|
execute stmt1 using @string;
|
|
|
|
deallocate prepare stmt1;
|
|
|
|
insert into t1 values(metaphon("for"));
|
|
|
|
insert into t1 select "yesterday";
|
|
|
|
create table t6 select metaphon("for");
|
|
|
|
create table t7 select 1 union select metaphon("for");
|
|
|
|
create table t8 select * from t1 where 3 in (select 1 union select 2 union select metaphon("for") union select 3);
|
|
|
|
create table t9 select * from t1 where 3 in (select 1 union select 2 union select curdate() union select 3);
|
|
|
|
}
|
|
|
|
|
WL#2977 and WL#2712 global and session-level variable to set the binlog format (row/statement),
and new binlog format called "mixed" (which is statement-based except if only row-based is correct,
in this cset it means if UDF or UUID is used; more cases could be added in later 5.1 release):
SET GLOBAL|SESSION BINLOG_FORMAT=row|statement|mixed|default;
the global default is statement unless cluster is enabled (then it's row) as in 5.1-alpha.
It's not possible to use SET on this variable if a session is currently in row-based mode and has open temporary tables (because CREATE
TEMPORARY TABLE was not binlogged so temp table is not known on slave), or if NDB is enabled (because
NDB does not support such change on-the-fly, though it will later), of if in a stored function (see below).
The added tests test the possibility or impossibility to SET, their effects, and the mixed mode,
including in prepared statements and in stored procedures and functions.
Caveats:
a) The mixed mode will not work for stored functions: in mixed mode, a stored function will
always be binlogged as one call and in a statement-based way (e.g. INSERT VALUES(myfunc()) or SELECT myfunc()).
b) for the same reason, changing the thread's binlog format inside a stored function is
refused with an error message.
c) the same problems apply to triggers; implementing b) for triggers will be done later (will ask
Dmitri).
Additionally, as the binlog format is now changeable by each user for his session, I remove the implication
which was done at startup, where row-based automatically set log-bin-trust-routine-creators to 1
(not possible anymore as a user can now switch to stmt-based and do nasty things again), and automatically
set --innodb-locks-unsafe-for-binlog to 1 (was anyway theoretically incorrect as it disabled
phantom protection).
Plus fixes for compiler warnings.
2006-02-25 22:21:03 +01:00
|
|
|
# and now compare:
|
|
|
|
|
2006-03-13 15:34:30 +01:00
|
|
|
# first check that data on master is sensible
|
|
|
|
select count(*) from t1;
|
|
|
|
select count(*) from t2;
|
|
|
|
select count(*) from t3;
|
|
|
|
select count(*) from t4;
|
|
|
|
select count(*) from t5;
|
|
|
|
if ($you_want_to_test_UDF)
|
|
|
|
{
|
|
|
|
select count(*) from t6;
|
|
|
|
select count(*) from t7;
|
|
|
|
select count(*) from t8;
|
|
|
|
select count(*) from t9;
|
|
|
|
}
|
|
|
|
|
2006-03-09 15:59:29 +01:00
|
|
|
--replace_column 2 # 5 #
|
|
|
|
--replace_regex /table_id: [0-9]+/table_id: #/
|
WL#2977 and WL#2712 global and session-level variable to set the binlog format (row/statement),
and new binlog format called "mixed" (which is statement-based except if only row-based is correct,
in this cset it means if UDF or UUID is used; more cases could be added in later 5.1 release):
SET GLOBAL|SESSION BINLOG_FORMAT=row|statement|mixed|default;
the global default is statement unless cluster is enabled (then it's row) as in 5.1-alpha.
It's not possible to use SET on this variable if a session is currently in row-based mode and has open temporary tables (because CREATE
TEMPORARY TABLE was not binlogged so temp table is not known on slave), or if NDB is enabled (because
NDB does not support such change on-the-fly, though it will later), of if in a stored function (see below).
The added tests test the possibility or impossibility to SET, their effects, and the mixed mode,
including in prepared statements and in stored procedures and functions.
Caveats:
a) The mixed mode will not work for stored functions: in mixed mode, a stored function will
always be binlogged as one call and in a statement-based way (e.g. INSERT VALUES(myfunc()) or SELECT myfunc()).
b) for the same reason, changing the thread's binlog format inside a stored function is
refused with an error message.
c) the same problems apply to triggers; implementing b) for triggers will be done later (will ask
Dmitri).
Additionally, as the binlog format is now changeable by each user for his session, I remove the implication
which was done at startup, where row-based automatically set log-bin-trust-routine-creators to 1
(not possible anymore as a user can now switch to stmt-based and do nasty things again), and automatically
set --innodb-locks-unsafe-for-binlog to 1 (was anyway theoretically incorrect as it disabled
phantom protection).
Plus fixes for compiler warnings.
2006-02-25 22:21:03 +01:00
|
|
|
show binlog events from 102;
|
|
|
|
sync_slave_with_master;
|
|
|
|
# as we're using UUID we don't SELECT but use "diff" like in rpl_row_UUID
|
2006-03-13 15:34:30 +01:00
|
|
|
--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_master.sql
|
|
|
|
--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_slave.sql
|
WL#2977 and WL#2712 global and session-level variable to set the binlog format (row/statement),
and new binlog format called "mixed" (which is statement-based except if only row-based is correct,
in this cset it means if UDF or UUID is used; more cases could be added in later 5.1 release):
SET GLOBAL|SESSION BINLOG_FORMAT=row|statement|mixed|default;
the global default is statement unless cluster is enabled (then it's row) as in 5.1-alpha.
It's not possible to use SET on this variable if a session is currently in row-based mode and has open temporary tables (because CREATE
TEMPORARY TABLE was not binlogged so temp table is not known on slave), or if NDB is enabled (because
NDB does not support such change on-the-fly, though it will later), of if in a stored function (see below).
The added tests test the possibility or impossibility to SET, their effects, and the mixed mode,
including in prepared statements and in stored procedures and functions.
Caveats:
a) The mixed mode will not work for stored functions: in mixed mode, a stored function will
always be binlogged as one call and in a statement-based way (e.g. INSERT VALUES(myfunc()) or SELECT myfunc()).
b) for the same reason, changing the thread's binlog format inside a stored function is
refused with an error message.
c) the same problems apply to triggers; implementing b) for triggers will be done later (will ask
Dmitri).
Additionally, as the binlog format is now changeable by each user for his session, I remove the implication
which was done at startup, where row-based automatically set log-bin-trust-routine-creators to 1
(not possible anymore as a user can now switch to stmt-based and do nasty things again), and automatically
set --innodb-locks-unsafe-for-binlog to 1 (was anyway theoretically incorrect as it disabled
phantom protection).
Plus fixes for compiler warnings.
2006-02-25 22:21:03 +01:00
|
|
|
|
|
|
|
connection master;
|
|
|
|
drop database mysqltest1;
|
|
|
|
sync_slave_with_master;
|
|
|
|
|
|
|
|
# Let's compare. Note: If they match test will pass, if they do not match
|
|
|
|
# the test will show that the diff statement failed and not reject file
|
|
|
|
# will be created. You will need to go to the mysql-test dir and diff
|
|
|
|
# the files your self to see what is not matching
|
|
|
|
|
2006-03-13 15:34:30 +01:00
|
|
|
--exec diff $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_master.sql $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_slave.sql;
|