Commit 2b89bd9f authored by Alfranio Correia's avatar Alfranio Correia

auto-merge mysql-trunk-bugfixing (local) --> mysql-trunk-bugfixing

parents 61aae511 e0328736
......@@ -1767,7 +1767,7 @@ sync_slave_with_master;
--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-nmt-master.sql
--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-nmt-slave.sql
if (`select @@session.binlog_format != 'STATEMENT'`)
if (`select @@session.binlog_direct_non_transactional_updates = 0 || @@session.binlog_format != 'STATEMENT'`)
{
--diff_files $MYSQLTEST_VARDIR/tmp/test-nmt-master.sql $MYSQLTEST_VARDIR/tmp/test-nmt-slave.sql
}
......
......@@ -8,14 +8,14 @@ INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2);
INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2);
UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
The last event before the COMMIT is use `test`; UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c
*** Please look in binlog_multi_engine.test if you have a diff here ****
START TRANSACTION;
INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2);
UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c;
COMMIT;
TRUNCATE t1m;
......
......@@ -8,7 +8,7 @@ begin;
insert into t1 values(1);
insert into t2 select * from t1;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
commit;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
......@@ -23,7 +23,7 @@ begin;
insert into t1 values(2);
insert into t2 select * from t1;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
rollback;
Warnings:
Warning 1196 Some non-transactional changed tables couldn't be rolled back
......@@ -42,7 +42,7 @@ savepoint my_savepoint;
insert into t1 values(4);
insert into t2 select * from t1;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
rollback to savepoint my_savepoint;
Warnings:
Warning 1196 Some non-transactional changed tables couldn't be rolled back
......@@ -65,7 +65,7 @@ savepoint my_savepoint;
insert into t1 values(6);
insert into t2 select * from t1;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
rollback to savepoint my_savepoint;
Warnings:
Warning 1196 Some non-transactional changed tables couldn't be rolled back
......@@ -95,7 +95,7 @@ begin;
insert into t1 values(8);
insert into t2 select * from t1;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
select get_lock("a",10);
get_lock("a",10)
1
......@@ -111,7 +111,7 @@ reset master;
insert into t1 values(9);
insert into t2 select * from t1;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
......@@ -127,7 +127,7 @@ insert into t1 values(10);
begin;
insert into t2 select * from t1;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
......@@ -427,7 +427,7 @@ begin;
insert into t1 values(8);
insert into t2 select * from t1;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
select get_lock("a",10);
get_lock("a",10)
1
......@@ -454,7 +454,7 @@ insert into ti values (1);
insert into ti values (2) ;
insert into tt select * from ti;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
rollback;
Warnings:
Warning 1196 Some non-transactional changed tables couldn't be rolled back
......@@ -473,7 +473,7 @@ count(*)
0
insert into ti select * from tt;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
select * from ti /* that is what slave would miss - a bug */;
a
1
......@@ -501,7 +501,7 @@ count(*)
0
insert into ti select * from tt;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
select * from tt /* that is what otherwise slave missed - the bug */;
a
1
......@@ -718,7 +718,7 @@ insert into ti values (1);
insert into ti values (2) ;
insert into tt select * from ti;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
rollback;
Warnings:
Warning 1196 Some non-transactional changed tables couldn't be rolled back
......@@ -737,7 +737,7 @@ count(*)
0
insert into ti select * from tt;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
select * from ti /* that is what slave would miss - bug#28960 */;
a
1
......@@ -765,7 +765,7 @@ count(*)
0
insert into ti select * from tt;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
select * from tt /* that is what otherwise slave missed - the bug */;
a
1
......
......@@ -5,9 +5,14 @@ create table t2 (a int) engine= innodb;
SELECT @@session.binlog_format;
@@session.binlog_format
ROW
SELECT @@session.binlog_direct_non_transactional_updates;
@@session.binlog_direct_non_transactional_updates
1
SET AUTOCOMMIT=1;
# Test that the session variable 'binlog_format'
# is writable outside a transaction.
# Test that the session variable 'binlog_format' and
# 'binlog_direct_non_transactional_updates' are
# writable outside a transaction.
# Current session values are ROW and FALSE, respectively.
set @@session.binlog_format= statement;
set @@session.binlog_direct_non_transactional_updates= TRUE;
SELECT @@session.binlog_format;
......@@ -17,15 +22,19 @@ SELECT @@session.binlog_direct_non_transactional_updates;
@@session.binlog_direct_non_transactional_updates
1
begin;
# Test that the session variable 'binlog_format' is read-only
# inside a transaction with no preceding updates.
# Test that the session variable 'binlog_format' and
# 'binlog_direct_non_transactional_updates' are
# read-only inside a transaction with no preceding updates.
# Current session values are STATEMENT and TRUE, respectively.
set @@session.binlog_format= mixed;
ERROR HY000: Cannot modify @@session.binlog_format inside a transaction
set @@session.binlog_direct_non_transactional_updates= FALSE;
ERROR HY000: Cannot modify @@session.binlog_direct_non_transactional_updates 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.
# Test that the session variable 'binlog_format' and
# 'binlog_direct_non_transactional_updates' are
# read-only inside a transaction with preceding transactional updates.
# Current session values are STATEMENT and TRUE, respectively.
set @@session.binlog_format= row;
ERROR HY000: Cannot modify @@session.binlog_format inside a transaction
set @@session.binlog_direct_non_transactional_updates= FALSE;
......@@ -33,15 +42,19 @@ ERROR HY000: Cannot modify @@session.binlog_direct_non_transactional_updates ins
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;
# Test that the session variable 'binlog_format' and
# 'binlog_direct_non_transactional_updates' are
# read-only inside a transaction with preceding non-transactional updates.
# Current session values are STATEMENT and TRUE, respectively.
set @@session.binlog_format= mixed;
ERROR HY000: Cannot modify @@session.binlog_format inside a transaction
set @@session.binlog_direct_non_transactional_updates= FALSE;
ERROR HY000: Cannot modify @@session.binlog_direct_non_transactional_updates inside a transaction
commit;
# Test that the session variable 'binlog_format' is writable
# when AUTOCOMMIT=0, before a transaction has started.
# Test that the session variable 'binlog_format' and
# 'binlog_direct_non_transactional_updates' are
# writable when AUTOCOMMIT=0, before a transaction has started.
# Current session values are STATEMENT and TRUE, respectively.
set AUTOCOMMIT=0;
set @@session.binlog_format= row;
set @@session.binlog_direct_non_transactional_updates= FALSE;
......@@ -51,9 +64,12 @@ ROW
SELECT @@session.binlog_direct_non_transactional_updates;
@@session.binlog_direct_non_transactional_updates
0
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.
insert into t1 values (3);
# Test that the session variable 'binlog_format' and
# 'binlog_direct_non_transactional_updates' are
# read-only inside an AUTOCOMMIT=0 transaction
# with preceding non-transactional updates.
# Current session values are ROW and FALSE, respectively.
set @@session.binlog_format= statement;
ERROR HY000: Cannot modify @@session.binlog_format inside a transaction
set @@session.binlog_direct_non_transactional_updates= TRUE;
......@@ -65,10 +81,13 @@ SELECT @@session.binlog_direct_non_transactional_updates;
@@session.binlog_direct_non_transactional_updates
0
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;
insert into t2 values (4);
# Test that the session variable 'binlog_format' and
# 'binlog_direct_non_transactional_updates' are
# read-only inside an AUTOCOMMIT=0 transaction with
# preceding transactional updates.
# Current session values are ROW and FALSE, respectively.
set @@session.binlog_format= statement;
ERROR HY000: Cannot modify @@session.binlog_format inside a transaction
set @@session.binlog_direct_non_transactional_updates= TRUE;
ERROR HY000: Cannot modify @@session.binlog_direct_non_transactional_updates inside a transaction
......@@ -80,9 +99,11 @@ SELECT @@session.binlog_direct_non_transactional_updates;
0
commit;
begin;
insert into t2 values (6);
# Test that the global variable 'binlog_format' is writable
# inside a transaction.
insert into t2 values (5);
# Test that the global variable 'binlog_format' and
# 'binlog_direct_non_transactional_updates' are
# writable inside a transaction.
# Current session values are ROW and FALSE, respectively.
SELECT @@global.binlog_format;
@@global.binlog_format
ROW
......@@ -96,18 +117,19 @@ SELECT @@global.binlog_direct_non_transactional_updates;
1
commit;
set @@global.binlog_format= @save_binlog_format;
set @@global.binlog_direct_non_transactional_updates= @save_binlog_dirct;
set @@global.binlog_direct_non_transactional_updates= @save_binlog_dirct;
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 tr1 after insert on t3 for each row begin
insert into t4(a) values(1);
set @@session.binlog_format= statement;
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.
# Current session value is ROW.
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;
......@@ -118,12 +140,14 @@ create table t7(a int) engine= innodb;
create table t8(a int) engine= innodb;
create trigger tr2 after insert on t6 for each row begin
insert into t7(a) values(1);
set @@global.binlog_direct_non_transactional_updates= FALSE;
set @@session.binlog_direct_non_transactional_updates= TRUE;
insert into t7(a) values(2);
insert into t8(a) values(3);
end |
# Test that the session variable 'binlog_format' is read-only
# in sub-statements.
# Test that the session variable
# 'binlog_direct_non_transactional_updates' is
# read-only in sub-statements.
# Current session value is FALSE.
insert into t6(a,b) values(1,1);
ERROR HY000: Cannot change the binlog direct flag inside a stored function or trigger
SELECT @@session.binlog_direct_non_transactional_updates;
......
#
# BUG#47863
# This test verifies if the session variable 'binlog_format'
# is read-only inside a transaction and in sub-statements.
# This test verifies if the session variable 'binlog_format' and
# 'binlog_direct_non_transactional_updates' are read-only inside
# a transaction and in sub-statements.
#
source include/have_innodb.inc;
......@@ -13,25 +14,32 @@ create table t1 (a int) engine= myisam;
create table t2 (a int) engine= innodb;
SELECT @@session.binlog_format;
SELECT @@session.binlog_direct_non_transactional_updates;
SET AUTOCOMMIT=1;
--echo # Test that the session variable 'binlog_format'
--echo # is writable outside a transaction.
--echo # Test that the session variable 'binlog_format' and
--echo # 'binlog_direct_non_transactional_updates' are
--echo # writable outside a transaction.
--echo # Current session values are ROW and FALSE, respectively.
set @@session.binlog_format= statement;
set @@session.binlog_direct_non_transactional_updates= TRUE;
SELECT @@session.binlog_format;
SELECT @@session.binlog_direct_non_transactional_updates;
begin;
--echo # Test that the session variable 'binlog_format' is read-only
--echo # inside a transaction with no preceding updates.
--echo # Test that the session variable 'binlog_format' and
--echo # 'binlog_direct_non_transactional_updates' are
--echo # read-only inside a transaction with no preceding updates.
--echo # Current session values are STATEMENT and TRUE, respectively.
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT
set @@session.binlog_format= mixed;
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT
set @@session.binlog_direct_non_transactional_updates= FALSE;
insert into t2 values (1);
--echo # Test that the session variable 'binlog_format' is read-only
--echo # inside a transaction with preceding transactional updates.
--echo # Test that the session variable 'binlog_format' and
--echo # 'binlog_direct_non_transactional_updates' are
--echo # read-only inside a transaction with preceding transactional updates.
--echo # Current session values are STATEMENT and TRUE, respectively.
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT
set @@session.binlog_format= row;
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT
......@@ -40,25 +48,32 @@ 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.
--echo # Test that the session variable 'binlog_format' and
--echo # 'binlog_direct_non_transactional_updates' are
--echo # read-only inside a transaction with preceding non-transactional updates.
--echo # Current session values are STATEMENT and TRUE, respectively.
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT
set @@session.binlog_format= statement;
set @@session.binlog_format= mixed;
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT
set @@session.binlog_direct_non_transactional_updates= FALSE;
commit;
--echo # Test that the session variable 'binlog_format' is writable
--echo # when AUTOCOMMIT=0, before a transaction has started.
--echo # Test that the session variable 'binlog_format' and
--echo # 'binlog_direct_non_transactional_updates' are
--echo # writable when AUTOCOMMIT=0, before a transaction has started.
--echo # Current session values are STATEMENT and TRUE, respectively.
set AUTOCOMMIT=0;
set @@session.binlog_format= row;
set @@session.binlog_direct_non_transactional_updates= FALSE;
SELECT @@session.binlog_format;
SELECT @@session.binlog_direct_non_transactional_updates;
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.
insert into t1 values (3);
--echo # Test that the session variable 'binlog_format' and
--echo # 'binlog_direct_non_transactional_updates' are
--echo # read-only inside an AUTOCOMMIT=0 transaction
--echo # with preceding non-transactional updates.
--echo # Current session values are ROW and FALSE, respectively.
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT
set @@session.binlog_format= statement;
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT
......@@ -67,11 +82,14 @@ SELECT @@session.binlog_format;
SELECT @@session.binlog_direct_non_transactional_updates;
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.
insert into t2 values (4);
--echo # Test that the session variable 'binlog_format' and
--echo # 'binlog_direct_non_transactional_updates' are
--echo # read-only inside an AUTOCOMMIT=0 transaction with
--echo # preceding transactional updates.
--echo # Current session values are ROW and FALSE, respectively.
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT
set @@session.binlog_format= row;
set @@session.binlog_format= statement;
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT
set @@session.binlog_direct_non_transactional_updates= TRUE;
SELECT @@session.binlog_format;
......@@ -79,9 +97,11 @@ SELECT @@session.binlog_direct_non_transactional_updates;
commit;
begin;
insert into t2 values (6);
--echo # Test that the global variable 'binlog_format' is writable
--echo # inside a transaction.
insert into t2 values (5);
--echo # Test that the global variable 'binlog_format' and
--echo # 'binlog_direct_non_transactional_updates' are
--echo # writable inside a transaction.
--echo # Current session values are ROW and FALSE, respectively.
SELECT @@global.binlog_format;
set @@global.binlog_format= statement;
set @@global.binlog_direct_non_transactional_updates= TRUE;
......@@ -90,7 +110,7 @@ begin;
commit;
set @@global.binlog_format= @save_binlog_format;
set @@global.binlog_direct_non_transactional_updates= @save_binlog_dirct;
set @@global.binlog_direct_non_transactional_updates= @save_binlog_dirct;
create table t3(a int, b int) engine= innodb;
create table t4(a int) engine= innodb;
......@@ -98,7 +118,7 @@ create table t5(a int) engine= innodb;
delimiter |;
eval create trigger tr1 after insert on t3 for each row begin
insert into t4(a) values(1);
set @@session.binlog_format= statement;
set @@session.binlog_format= statement;
insert into t4(a) values(2);
insert into t5(a) values(3);
end |
......@@ -106,6 +126,7 @@ delimiter ;|
--echo # Test that the session variable 'binlog_format' is read-only
--echo # in sub-statements.
--echo # Current session value is ROW.
--error ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT
insert into t3(a,b) values(1,1);
SELECT @@session.binlog_format;
......@@ -116,14 +137,16 @@ create table t8(a int) engine= innodb;
delimiter |;
eval create trigger tr2 after insert on t6 for each row begin
insert into t7(a) values(1);
set @@global.binlog_direct_non_transactional_updates= FALSE;
set @@session.binlog_direct_non_transactional_updates= TRUE;
insert into t7(a) values(2);
insert into t8(a) values(3);
end |
delimiter ;|
--echo # Test that the session variable 'binlog_format' is read-only
--echo # in sub-statements.
--echo # Test that the session variable
--echo # 'binlog_direct_non_transactional_updates' is
--echo # read-only in sub-statements.
--echo # Current session value is FALSE.
--error ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT
insert into t6(a,b) values(1,1);
SELECT @@session.binlog_direct_non_transactional_updates;
......
......@@ -9,12 +9,12 @@ INSERT INTO t1 VALUES (1,1), (1,2), (2,1), (2,2);
INSERT INTO t2 VALUES (1,1), (1,2), (2,1), (2,2);
UPDATE t1, t2 SET m = 2, b = 3 WHERE n = c;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
START TRANSACTION;
INSERT INTO t3 VALUES (1,1), (1,2), (2,1), (2,2);
UPDATE t1, t3 SET m = 2, e = 3 WHERE n = f;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
UPDATE t3, t2 SET e = 2, b = 3 WHERE f = c;
COMMIT;
show binlog events from <binlog_start>;
......
......@@ -22,7 +22,7 @@ SET AUTOCOMMIT = 1;
BEGIN;
UPDATE t SET f = 'yellow 2' WHERE i = 3;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
SET AUTOCOMMIT = 1;
BEGIN;
UPDATE t SET f = 'magenta 2' WHERE f = 'red';
......@@ -51,7 +51,7 @@ SET AUTOCOMMIT = 1;
BEGIN;
UPDATE t SET f = 'gray 2' WHERE i = 3;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
SET AUTOCOMMIT = 1;
BEGIN;
UPDATE t SET f = 'dark blue 2' WHERE f = 'red';
......@@ -77,7 +77,7 @@ master-bin.000001 # Xid # # COMMIT /* XID */
SET AUTOCOMMIT = 0;
UPDATE t SET f = 'yellow 1' WHERE i = 3;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
SET AUTOCOMMIT = 0;
UPDATE t SET f = 'magenta 1' WHERE f = 'red';
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
......@@ -104,7 +104,7 @@ master-bin.000001 # Query # # ROLLBACK
SET AUTOCOMMIT = 0;
UPDATE t SET f = 'gray 1' WHERE i = 3;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
SET AUTOCOMMIT = 0;
UPDATE t SET f = 'dark blue 1' WHERE f = 'red';
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
......
......@@ -40,7 +40,7 @@ Got one of the listed errors
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
BEGIN;
Got one of the listed errors
Got one of the listed errors
......
......@@ -53,7 +53,7 @@ set @@global.debug="+d,stop_slave_middle_group";
set @@global.debug="+d,incomplete_group_in_relay_log";
update tm as t1, ti as t2 set t1.a=t1.a * 2, t2.a=t2.a * 2;
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statements that read from both transactional and non-transactional tables and write to any of them are unsafe.
SELECT "Fatal error: ... The slave SQL is stopped, leaving the current group of events unfinished with a non-transaction table changed. If the group consists solely of Row-based events, you can try restarting the slave with --slave-exec-mode=IDEMPOTENT, which ignores duplicate key, key not found, and similar errors (see documentation for details)." AS Last_SQL_Error, @check as `true`;
Last_SQL_Error true
Fatal error: ... The slave SQL is stopped, leaving the current group of events unfinished with a non-transaction table changed. If the group consists solely of Row-based events, you can try restarting the slave with --slave-exec-mode=IDEMPOTENT, which ignores duplicate key, key not found, and similar errors (see documentation for details). 1
......
###################################################################################
# This test cases evaluates the mixture of non-transactional and transcational
# tables. For further details, please, read WL#2687 and WL#5072.
###################################################################################
--source include/have_binlog_format_mixed.inc
--source include/master-slave.inc
--source include/have_innodb.inc
--disable_query_log
SET SESSION binlog_direct_non_transactional_updates = OFF;
--enable_query_log
let $engine_type=Innodb;
--source extra/rpl_tests/rpl_mixing_engines.test
--diff_files suite/rpl/r/rpl_non_direct_mixed_mixing_engines.result suite/rpl/r/rpl_mixed_mixing_engines.result
###################################################################################
# This test cases evaluates the mixture of non-transactional and transcational
# tables. For further details, please, read WL#2687 and WL#5072.
###################################################################################
--source include/have_binlog_format_row.inc
--source include/master-slave.inc
--source include/have_innodb.inc
--disable_query_log
SET SESSION binlog_direct_non_transactional_updates = OFF;
--enable_query_log
let $engine_type=Innodb;
--source extra/rpl_tests/rpl_mixing_engines.test
--diff_files suite/rpl/r/rpl_non_direct_row_mixing_engines.result suite/rpl/r/rpl_row_mixing_engines.result
###################################################################################
# This test cases evaluates the mixture of non-transactional and transcational
# tables. For further details, please, read WL#2687 and WL#5072.
###################################################################################
--source include/have_binlog_format_statement.inc
--source include/master-slave.inc
--source include/have_innodb.inc
--disable_query_log
SET SESSION binlog_direct_non_transactional_updates = OFF;
--enable_query_log
let $engine_type=Innodb;
--source extra/rpl_tests/rpl_mixing_engines.test
......@@ -15,6 +15,7 @@ call mtr.add_suppression("Unsafe statement binlogged in statement format since B
connection slave;
call mtr.add_suppression("Master server does not support semi-sync");
call mtr.add_suppression("Semi-sync slave .* reply");
call mtr.add_suppression("Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT.");
enable_query_log;
connection master;
......
......@@ -341,6 +341,25 @@ ROLLBACK;
Warnings:
Warning 1196 Some non-transactional changed tables couldn't be rolled back
SET AUTOCOMMIT = 1;
---- Mixed statements Innodb ----
BEGIN;
INSERT INTO tndb VALUES (147);
INSERT INTO tinnodb SELECT * FROM tndb ORDER BY a DESC LIMIT 1;
COMMIT;
INSERT INTO tndb VALUES (148);
BEGIN;
INSERT INTO tinnodb SELECT * FROM tndb ORDER BY a DESC LIMIT 1;
INSERT INTO tndb VALUES (149);
COMMIT;
BEGIN;
INSERT INTO tndb VALUES (150);
INSERT INTO tmyisam SELECT * FROM tndb ORDER BY a DESC LIMIT 1;
COMMIT;
INSERT INTO tndb VALUES (151);
BEGIN;
INSERT INTO tmyisam SELECT * FROM tndb ORDER BY a DESC LIMIT 1;
INSERT INTO tndb VALUES (152);
COMMIT;
==== Verify the result ====
SELECT * FROM tmyisam ORDER BY a;
a
......@@ -393,6 +412,8 @@ a
140
142
146
150
151
SELECT * FROM tinnodb ORDER BY a;
a
1
......@@ -420,6 +441,8 @@ a
120
125
127
147
148
SELECT * FROM tndb ORDER BY a;
a
2
......@@ -447,6 +470,12 @@ a
121
123
126
147
148
149
150
151
152
[on slave]
Comparing tables master:test.tmyisam and slave:test.tmyisam
Comparing tables master:test.tinnodb and slave:test.tinnodb
......
......@@ -418,6 +418,29 @@ ROLLBACK;
SET AUTOCOMMIT = 1;
--echo ---- Mixed statements Innodb ----
BEGIN;
INSERT INTO tndb VALUES (147);
INSERT INTO tinnodb SELECT * FROM tndb ORDER BY a DESC LIMIT 1;
COMMIT;
INSERT INTO tndb VALUES (148);
BEGIN;
INSERT INTO tinnodb SELECT * FROM tndb ORDER BY a DESC LIMIT 1;
INSERT INTO tndb VALUES (149);
COMMIT;
BEGIN;
INSERT INTO tndb VALUES (150);
INSERT INTO tmyisam SELECT * FROM tndb ORDER BY a DESC LIMIT 1;
COMMIT;
INSERT INTO tndb VALUES (151);
BEGIN;
INSERT INTO tmyisam SELECT * FROM tndb ORDER BY a DESC LIMIT 1;
INSERT INTO tndb VALUES (152);
COMMIT;
--echo ==== Verify the result ====
......
......@@ -1640,7 +1640,10 @@ binlog_flush_stmt_cache(THD *thd, binlog_cache_mngr *cache_mngr)
*/
bool const is_transactional= FALSE;
IO_CACHE *cache_log= &cache_mngr->stmt_cache.cache_log;
thd->binlog_flush_pending_rows_event(TRUE, is_transactional);
if (thd->binlog_flush_pending_rows_event(TRUE, is_transactional))
DBUG_RETURN(1);
Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE, TRUE, 0);
if ((error= mysql_bin_log.write(thd, cache_log, &qev,
cache_mngr->stmt_cache.has_incident())))
......@@ -4189,7 +4192,7 @@ bool MYSQL_BIN_LOG::is_query_in_union(THD *thd, query_id_t query_id_param)
}
/**
This function checks if a transactional talbe was updated by the
This function checks if a transactional table was updated by the
current transaction.
@param thd The client thread that executed the current statement.
......@@ -4202,11 +4205,11 @@ trans_has_updated_trans_table(const THD* thd)
binlog_cache_mngr *const cache_mngr=
(binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
return (cache_mngr ? my_b_tell (&cache_mngr->trx_cache.cache_log) : 0);
return (cache_mngr ? !cache_mngr->trx_cache.empty() : 0);
}
/**
This function checks if a transactional talbe was updated by the
This function checks if a transactional table was updated by the
current statement.
@param thd The client thread that executed the current statement.
......@@ -4218,7 +4221,8 @@ stmt_has_updated_trans_table(const THD *thd)
{
Ha_trx_info *ha_info;
for (ha_info= thd->transaction.stmt.ha_list; ha_info; ha_info= ha_info->next())
for (ha_info= thd->transaction.stmt.ha_list; ha_info;
ha_info= ha_info->next())
{
if (ha_info->is_trx_read_write() && ha_info->ht() != binlog_hton)
return (TRUE);
......@@ -4228,11 +4232,14 @@ stmt_has_updated_trans_table(const THD *thd)
/**
This function checks if either a trx-cache or a non-trx-cache should
be used. If @c bin_log_direct_non_trans_update is active, the cache
to be used depends on the flag @c is_transactional.
be used. If @c bin_log_direct_non_trans_update is active or the format
is either MIXED or ROW, the cache to be used depends on the flag @c
is_transactional.
Otherswise, we use the trx-cache if either the @c is_transactional
is true or the trx-cache is not empty.
On the other hand, if binlog_format is STMT or direct option is
OFF, the trx-cache should be used if and only if the statement is
transactional or the trx-cache is not empty. Otherwise, the
non-trx-cache should be used.
@param thd The client thread.
@param is_transactional The changes are related to a trx-table.
......@@ -4245,8 +4252,9 @@ bool use_trans_cache(const THD* thd, bool is_transactional)
(binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
return
(thd->variables.binlog_direct_non_trans_update ? is_transactional :
(cache_mngr->trx_cache.empty() && !is_transactional ? FALSE : TRUE));
((thd->variables.binlog_format != BINLOG_FORMAT_STMT ||
thd->variables.binlog_direct_non_trans_update) ? is_transactional :
(is_transactional || !cache_mngr->trx_cache.empty()));
}
/*
......
......@@ -6330,3 +6330,9 @@ ER_DATA_OUT_OF_RANGE 22003
ER_WRONG_SPVAR_TYPE_IN_LIMIT
eng "A variable of a non-integer type in LIMIT clause"
ER_BINLOG_UNSAFE_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE
eng "Mixing self-logging and non-self-logging engines in a statement is unsafe."
ER_BINLOG_UNSAFE_MIXED_STATEMENT
eng "Statements that read from both transactional and non-transactional tables and write to any of them are unsafe."
......@@ -3601,13 +3601,33 @@ int THD::decide_logging_format(TABLE_LIST *tables)
capabilities, and one with the intersection of all the engine
capabilities.
*/
handler::Table_flags flags_write_some_set= 0;
handler::Table_flags flags_some_set= 0;
handler::Table_flags flags_all_set=
handler::Table_flags flags_write_all_set=
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE;
my_bool multi_engine= FALSE;
my_bool mixed_engine= FALSE;
my_bool all_trans_engines= TRUE;
/*
If different types of engines are about to be updated.
For example: Innodb and Falcon; Innodb and MyIsam.
*/
my_bool multi_write_engine= FALSE;
/*
If different types of engines are about to be accessed
and any of them is about to be updated. For example:
Innodb and Falcon; Innodb and MyIsam.
*/
my_bool multi_access_engine= FALSE;
/*
If non-transactional and transactional engines are about
to be accessed and any of them is about to be updated.
For example: Innodb and MyIsam.
*/
my_bool trans_non_trans_access_engines= FALSE;
/*
If all engines that are about to be updated are
transactional.
*/
my_bool all_trans_write_engines= TRUE;
TABLE* prev_write_table= NULL;
TABLE* prev_access_table= NULL;
......@@ -3633,32 +3653,50 @@ int THD::decide_logging_format(TABLE_LIST *tables)
continue;
if (table->table->s->table_category == TABLE_CATEGORY_PERFORMANCE)
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_TABLE);
handler::Table_flags const flags= table->table->file->ha_table_flags();
DBUG_PRINT("info", ("table: %s; ha_table_flags: 0x%llx",
table->table_name, flags));
if (table->lock_type >= TL_WRITE_ALLOW_WRITE)
{
handler::Table_flags const flags= table->table->file->ha_table_flags();
DBUG_PRINT("info", ("table: %s; ha_table_flags: 0x%llx",
table->table_name, flags));
if (prev_write_table && prev_write_table->file->ht !=
table->table->file->ht)
multi_engine= TRUE;
all_trans_engines= all_trans_engines &&
table->table->file->has_transactions();
multi_write_engine= TRUE;
all_trans_write_engines= all_trans_write_engines &&
table->table->file->has_transactions();
prev_write_table= table->table;
flags_all_set &= flags;
flags_some_set |= flags;
flags_write_all_set &= flags;
flags_write_some_set |= flags;
}
flags_some_set |= flags;
if (prev_access_table && prev_access_table->file->ht != table->table->file->ht)
mixed_engine= mixed_engine || (prev_access_table->file->has_transactions() !=
table->table->file->has_transactions());
{
multi_access_engine= TRUE;
trans_non_trans_access_engines= trans_non_trans_access_engines ||
(prev_access_table->file->has_transactions() !=
table->table->file->has_transactions());
}
prev_access_table= table->table;
}
DBUG_PRINT("info", ("flags_write_all_set: 0x%llx", flags_write_all_set));
DBUG_PRINT("info", ("flags_write_some_set: 0x%llx", flags_write_some_set));
DBUG_PRINT("info", ("flags_some_set: 0x%llx", flags_some_set));
DBUG_PRINT("info", ("multi_write_engine: %d", multi_write_engine));
DBUG_PRINT("info", ("multi_access_engine: %d", multi_access_engine));
DBUG_PRINT("info", ("trans_non_trans_access_engines: %d",
trans_non_trans_access_engines));
int error= 0;
int unsafe_flags;
/*
Set the statement as unsafe if:
. it is a mixed statement, i.e. access transactional and non-transactional
tables, and updates at least one;
or
tables, and update any of them;
or:
. an early statement updated a transactional table;
. and, the current statement updates a non-transactional table.
......@@ -3722,32 +3760,26 @@ int THD::decide_logging_format(TABLE_LIST *tables)
isolation level but if we have pure repeatable read or serializable the
lock history on the slave will be different from the master.
*/
if (mixed_engine ||
(trans_has_updated_trans_table(this) && !all_trans_engines))
if (trans_non_trans_access_engines)
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_MIXED_STATEMENT);
else if (trans_has_updated_trans_table(this) && !all_trans_write_engines)
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_NONTRANS_AFTER_TRANS);
DBUG_PRINT("info", ("flags_all_set: 0x%llx", flags_all_set));
DBUG_PRINT("info", ("flags_some_set: 0x%llx", flags_some_set));
DBUG_PRINT("info", ("multi_engine: %d", multi_engine));
int error= 0;
int unsafe_flags;
/*
If more than one engine is involved in the statement and at
least one is doing it's own logging (is *self-logging*), the
statement cannot be logged atomically, so we generate an error
rather than allowing the binlog to become corrupt.
*/
if (multi_engine &&
(flags_some_set & HA_HAS_OWN_BINLOGGING))
{
if (multi_write_engine &&
(flags_write_some_set & HA_HAS_OWN_BINLOGGING))
my_error((error= ER_BINLOG_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE),
MYF(0));
}
else if (multi_access_engine && flags_some_set & HA_HAS_OWN_BINLOGGING)
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE);
/* both statement-only and row-only engines involved */
if ((flags_all_set & (HA_BINLOG_STMT_CAPABLE | HA_BINLOG_ROW_CAPABLE)) == 0)
if ((flags_write_all_set & (HA_BINLOG_STMT_CAPABLE | HA_BINLOG_ROW_CAPABLE)) == 0)
{
/*
1. Error: Binary logging impossible since both row-incapable
......@@ -3756,7 +3788,7 @@ int THD::decide_logging_format(TABLE_LIST *tables)
my_error((error= ER_BINLOG_ROW_ENGINE_AND_STMT_ENGINE), MYF(0));
}
/* statement-only engines involved */
else if ((flags_all_set & HA_BINLOG_ROW_CAPABLE) == 0)
else if ((flags_write_all_set & HA_BINLOG_ROW_CAPABLE) == 0)
{
if (lex->is_stmt_row_injection())
{
......@@ -3804,7 +3836,7 @@ int THD::decide_logging_format(TABLE_LIST *tables)
*/
my_error((error= ER_BINLOG_ROW_INJECTION_AND_STMT_MODE), MYF(0));
}
else if ((flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
else if ((flags_write_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
{
/*
5. Error: Cannot modify table that uses a storage engine
......@@ -3832,7 +3864,7 @@ int THD::decide_logging_format(TABLE_LIST *tables)
else
{
if (lex->is_stmt_unsafe() || lex->is_stmt_row_injection()
|| (flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
|| (flags_write_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
{
/* log in row format! */
set_current_stmt_binlog_format_row_if_mixed();
......
......@@ -56,7 +56,9 @@ Query_tables_list::binlog_stmt_unsafe_errcode[BINLOG_STMT_UNSAFE_COUNT] =
ER_BINLOG_UNSAFE_UDF,
ER_BINLOG_UNSAFE_SYSTEM_VARIABLE,
ER_BINLOG_UNSAFE_SYSTEM_FUNCTION,
ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS
ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS,
ER_BINLOG_UNSAFE_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE,
ER_BINLOG_UNSAFE_MIXED_STATEMENT,
};
......
......@@ -1161,6 +1161,18 @@ class Query_tables_list
*/
BINLOG_STMT_UNSAFE_NONTRANS_AFTER_TRANS,
/**
Mixing self-logging and non-self-logging engines in a statement
is unsafe.
*/
BINLOG_STMT_UNSAFE_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE,
/**
Statements that read from both transactional and non-transactional
tables and write to any of them are unsafe.
*/
BINLOG_STMT_UNSAFE_MIXED_STATEMENT,
/* The last element of this enumeration type. */
BINLOG_STMT_UNSAFE_COUNT
};
......
......@@ -258,6 +258,12 @@ static bool check_has_super(sys_var *self, THD *thd, set_var *var)
}
static bool binlog_format_check(sys_var *self, THD *thd, set_var *var)
{
if (check_has_super(self, thd, var))
return true;
if (var->type == OPT_GLOBAL)
return false;
/*
If RBR and open temporary tables, their CREATE TABLE may not be in the
binlog, so we can't toggle to SBR in this connection.
......@@ -289,18 +295,12 @@ static bool binlog_format_check(sys_var *self, THD *thd, set_var *var)
/*
Make the session variable 'binlog_format' read-only inside a transaction.
*/
if (thd->active_transaction() && (var->type == OPT_SESSION))
if (thd->active_transaction())
{
my_error(ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT, MYF(0));
return true;
}
if (check_has_super(self, thd, var))
return true;
if (var->type == OPT_GLOBAL ||
(thd->variables.binlog_format == var->save_result.ulonglong_value))
return false;
return false;
}
......@@ -329,32 +329,31 @@ static Sys_var_enum Sys_binlog_format(
static bool binlog_direct_check(sys_var *self, THD *thd, set_var *var)
{
if (check_has_super(self, thd, var))
return true;
if (var->type == OPT_GLOBAL)
return false;
/*
Makes the session variable 'binlog_direct_non_transactional_updates'
read-only inside a transaction.
read-only if within a procedure, trigger or function.
*/
if (thd->active_transaction() && (var->type == OPT_SESSION))
if (thd->in_sub_stmt)
{
my_error(ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT, MYF(0));
return 1;
my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT, MYF(0));
return true;
}
/*
Makes the session variable 'binlog_direct_non_transactional_updates'
read-only if within a procedure, trigger or function.
read-only inside a transaction.
*/
if (thd->in_sub_stmt)
if (thd->active_transaction())
{
my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT, MYF(0));
return 1;
my_error(ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT, MYF(0));
return true;
}
if (check_has_super(self, thd, var))
return true;
if (var->type == OPT_GLOBAL ||
(thd->variables.binlog_direct_non_trans_update ==
static_cast<my_bool>(var->save_result.ulonglong_value)))
return false;
return false;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment