Browse Source
Bug #47863 binlog_format should be writable only at transaction boundaries
Bug #47863 binlog_format should be writable only at transaction boundaries
When @@session.binlog_format is modified inside a transaction,
it can cause slave to go out of sync.
To fix the problem, make the session variable 'binlog_format'
read-only inside a transaction.
mysql-test/suite/binlog/r/binlog_format_switch_inside_trans.result:
Test result for bug#47863.
mysql-test/suite/binlog/t/binlog_format_switch_inside_trans.test:
Added test file to verify if the session variable 'binlog_format'
is read-only inside a transaction and in sub-statements.
sql/set_var.cc:
Added code to make the session variable 'binlog_format'
read-only inside a transaction.
pull/374/head
4 changed files with 198 additions and 0 deletions
-
90mysql-test/suite/binlog/r/binlog_format_switch_inside_trans.result
-
98mysql-test/suite/binlog/t/binlog_format_switch_inside_trans.test
-
8sql/set_var.cc
-
2sql/share/errmsg.txt
@ -0,0 +1,90 @@ |
|||
set @save_binlog_format= @@global.binlog_format; |
|||
create table t1 (a int) engine= myisam; |
|||
create table t2 (a int) engine= innodb; |
|||
SELECT @@session.binlog_format; |
|||
@@session.binlog_format |
|||
ROW |
|||
SET AUTOCOMMIT=1; |
|||
# Test that the session variable 'binlog_format' |
|||
# is writable outside a transaction. |
|||
set @@session.binlog_format= statement; |
|||
SELECT @@session.binlog_format; |
|||
@@session.binlog_format |
|||
STATEMENT |
|||
begin; |
|||
# Test that the session variable 'binlog_format' is read-only |
|||
# inside a transaction with no preceding updates. |
|||
set @@session.binlog_format= mixed; |
|||
ERROR HY000: Cannot modify @@session.binlog_format inside a transaction |
|||
insert into t2 values (1); |
|||
# Test that the session variable 'binlog_format' is read-only |
|||
# inside a transaction with preceding transactional updates. |
|||
set @@session.binlog_format= row; |
|||
ERROR HY000: Cannot modify @@session.binlog_format inside a transaction |
|||
commit; |
|||
begin; |
|||
insert into t1 values (2); |
|||
# Test that the session variable 'binlog_format' is read-only |
|||
# inside a transaction with preceding non-transactional updates. |
|||
set @@session.binlog_format= statement; |
|||
ERROR HY000: Cannot modify @@session.binlog_format inside a transaction |
|||
commit; |
|||
# Test that the session variable 'binlog_format' is writable |
|||
# when AUTOCOMMIT=0, before a transaction has started. |
|||
set AUTOCOMMIT=0; |
|||
set @@session.binlog_format= row; |
|||
SELECT @@session.binlog_format; |
|||
@@session.binlog_format |
|||
ROW |
|||
insert into t1 values (4); |
|||
# Test that the session variable 'binlog_format' is read-only inside an |
|||
# AUTOCOMMIT=0 transaction with preceding non-transactional updates. |
|||
set @@session.binlog_format= statement; |
|||
ERROR HY000: Cannot modify @@session.binlog_format inside a transaction |
|||
SELECT @@session.binlog_format; |
|||
@@session.binlog_format |
|||
ROW |
|||
commit; |
|||
insert into t2 values (5); |
|||
# Test that the session variable 'binlog_format' is read-only inside an |
|||
# AUTOCOMMIT=0 transaction with preceding transactional updates. |
|||
set @@session.binlog_format= row; |
|||
ERROR HY000: Cannot modify @@session.binlog_format inside a transaction |
|||
SELECT @@session.binlog_format; |
|||
@@session.binlog_format |
|||
ROW |
|||
commit; |
|||
begin; |
|||
insert into t2 values (6); |
|||
# Test that the global variable 'binlog_format' is writable |
|||
# inside a transaction. |
|||
SELECT @@global.binlog_format; |
|||
@@global.binlog_format |
|||
ROW |
|||
set @@global.binlog_format= statement; |
|||
SELECT @@global.binlog_format; |
|||
@@global.binlog_format |
|||
STATEMENT |
|||
commit; |
|||
set @@global.binlog_format= @save_binlog_format; |
|||
create table t3(a int, b int) engine= innodb; |
|||
create table t4(a int) engine= innodb; |
|||
create table t5(a int) engine= innodb; |
|||
create trigger tr2 after insert on t3 for each row begin |
|||
insert into t4(a) values(1); |
|||
set @@session.binlog_format= statement; |
|||
insert into t4(a) values(2); |
|||
insert into t5(a) values(3); |
|||
end | |
|||
# Test that the session variable 'binlog_format' is read-only |
|||
# in sub-statements. |
|||
insert into t3(a,b) values(1,1); |
|||
ERROR HY000: Cannot change the binary logging format inside a stored function or trigger |
|||
SELECT @@session.binlog_format; |
|||
@@session.binlog_format |
|||
ROW |
|||
drop table t1; |
|||
drop table t2; |
|||
drop table t3; |
|||
drop table t4; |
|||
drop table t5; |
|||
@ -0,0 +1,98 @@ |
|||
# |
|||
# BUG#47863 |
|||
# This test verifies if the session variable 'binlog_format' |
|||
# is read-only inside a transaction and in sub-statements. |
|||
# |
|||
|
|||
source include/have_innodb.inc; |
|||
source include/have_binlog_format_row.inc; |
|||
|
|||
set @save_binlog_format= @@global.binlog_format; |
|||
create table t1 (a int) engine= myisam; |
|||
create table t2 (a int) engine= innodb; |
|||
|
|||
SELECT @@session.binlog_format; |
|||
SET AUTOCOMMIT=1; |
|||
--echo # Test that the session variable 'binlog_format' |
|||
--echo # is writable outside a transaction. |
|||
set @@session.binlog_format= statement; |
|||
SELECT @@session.binlog_format; |
|||
|
|||
begin; |
|||
--echo # Test that the session variable 'binlog_format' is read-only |
|||
--echo # inside a transaction with no preceding updates. |
|||
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT |
|||
set @@session.binlog_format= mixed; |
|||
|
|||
insert into t2 values (1); |
|||
--echo # Test that the session variable 'binlog_format' is read-only |
|||
--echo # inside a transaction with preceding transactional updates. |
|||
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT |
|||
set @@session.binlog_format= row; |
|||
commit; |
|||
|
|||
begin; |
|||
insert into t1 values (2); |
|||
--echo # Test that the session variable 'binlog_format' is read-only |
|||
--echo # inside a transaction with preceding non-transactional updates. |
|||
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT |
|||
set @@session.binlog_format= statement; |
|||
commit; |
|||
|
|||
--echo # Test that the session variable 'binlog_format' is writable |
|||
--echo # when AUTOCOMMIT=0, before a transaction has started. |
|||
set AUTOCOMMIT=0; |
|||
set @@session.binlog_format= row; |
|||
SELECT @@session.binlog_format; |
|||
|
|||
insert into t1 values (4); |
|||
--echo # Test that the session variable 'binlog_format' is read-only inside an |
|||
--echo # AUTOCOMMIT=0 transaction with preceding non-transactional updates. |
|||
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT |
|||
set @@session.binlog_format= statement; |
|||
SELECT @@session.binlog_format; |
|||
commit; |
|||
|
|||
insert into t2 values (5); |
|||
--echo # Test that the session variable 'binlog_format' is read-only inside an |
|||
--echo # AUTOCOMMIT=0 transaction with preceding transactional updates. |
|||
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT |
|||
set @@session.binlog_format= row; |
|||
SELECT @@session.binlog_format; |
|||
commit; |
|||
|
|||
begin; |
|||
insert into t2 values (6); |
|||
--echo # Test that the global variable 'binlog_format' is writable |
|||
--echo # inside a transaction. |
|||
SELECT @@global.binlog_format; |
|||
set @@global.binlog_format= statement; |
|||
SELECT @@global.binlog_format; |
|||
commit; |
|||
|
|||
set @@global.binlog_format= @save_binlog_format; |
|||
|
|||
create table t3(a int, b int) engine= innodb; |
|||
create table t4(a int) engine= innodb; |
|||
create table t5(a int) engine= innodb; |
|||
delimiter |; |
|||
eval create trigger tr2 after insert on t3 for each row begin |
|||
insert into t4(a) values(1); |
|||
set @@session.binlog_format= statement; |
|||
insert into t4(a) values(2); |
|||
insert into t5(a) values(3); |
|||
end | |
|||
delimiter ;| |
|||
|
|||
--echo # Test that the session variable 'binlog_format' is read-only |
|||
--echo # in sub-statements. |
|||
--error ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT |
|||
insert into t3(a,b) values(1,1); |
|||
SELECT @@session.binlog_format; |
|||
|
|||
drop table t1; |
|||
drop table t2; |
|||
drop table t3; |
|||
drop table t4; |
|||
drop table t5; |
|||
|
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue