mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 02:51:44 +01:00
c9221a2a6f
BUG#54872 MBR: replication failure caused by using tmp table inside transaction Changed criteria to classify a statement as unsafe in order to reduce the number of spurious warnings. So a statement is classified as unsafe when there is on-going transaction at any point of the execution if: 1. The mixed statement is about to update a transactional table and a non-transactional table. 2. The mixed statement is about to update a temporary transactional table and a non-transactional table. 3. The mixed statement is about to update a transactional table and read from a non-transactional table. 4. The mixed statement is about to update a temporary transactional table and read from a non-transactional table. 5. The mixed statement is about to update a non-transactional table and read from a transactional table when the isolation level is lower than repeatable read. After updating a transactional table if: 6. The mixed statement is about to update a non-transactional table and read from a temporary transactional table. 7. The mixed statement is about to update a non-transactional table and read from a temporary transactional table. 8. The mixed statement is about to update a non-transactionala table and read from a temporary non-transactional table. 9. The mixed statement is about to update a temporary non-transactional table and update a non-transactional table. 10. The mixed statement is about to update a temporary non-transactional table and read from a non-transactional table. 11. A statement is about to update a non-transactional table and the option variables.binlog_direct_non_trans_update is OFF. The reason for this is that locks acquired may not protected a concurrent transaction of interfering in the current execution and by consequence in the result. So the patch reduced the number of spurious unsafe warnings. Besides we fixed a regression caused by BUG#51894, which makes temporary tables to go into the trx-cache if there is an on-going transaction. In MIXED mode, the patch for BUG#51894 ignores that the trx-cache may have updates to temporary non-transactional tables that must be written to the binary log while rolling back the transaction. So we fix this problem by writing the content of the trx-cache to the binary log while rolling back a transaction if a non-transactional temporary table was updated and the binary logging format is MIXED.
128 lines
6.1 KiB
Text
128 lines
6.1 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;
|
|
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
|
|
########################################################################
|
|
# Environment
|
|
########################################################################
|
|
CREATE TABLE t (i INT, PRIMARY KEY(i), f CHAR(8)) engine = Innodb;
|
|
CREATE TABLE n (d DATETIME, f CHAR(32)) engine = MyIsam;
|
|
CREATE TRIGGER tr AFTER UPDATE ON t FOR EACH ROW
|
|
BEGIN
|
|
INSERT INTO n VALUES ( now(), concat( 'updated t: ', old.f, ' -> ', new.f ) );
|
|
END |
|
|
INSERT INTO t VALUES (4,'black'), (2,'red'), (3,'yelow'), (1,'cyan');
|
|
########################################################################
|
|
# Testing ER_LOCK_WAIT_TIMEOUT
|
|
########################################################################
|
|
SET AUTOCOMMIT = 1;
|
|
BEGIN;
|
|
UPDATE t SET f = 'yellow 2' WHERE i = 3;
|
|
Warnings:
|
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement accesses nontransactional table as well as transactional or temporary table, and writes to any of them.
|
|
SET AUTOCOMMIT = 1;
|
|
BEGIN;
|
|
UPDATE t SET f = 'magenta 2' WHERE f = 'red';
|
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
|
INSERT INTO t VALUES (5 + (2 * 10),"brown");
|
|
INSERT INTO n VALUES (now(),"brown");
|
|
COMMIT;
|
|
ROLLBACK;
|
|
Warnings:
|
|
Warning 1196 Some non-transactional changed tables couldn't be rolled back
|
|
show binlog events from <binlog_start>;
|
|
Log_name Pos Event_type Server_id End_log_pos Info
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO n VALUES (now(),"brown")
|
|
master-bin.000001 # Query # # COMMIT
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; UPDATE t SET f = 'yellow 2' WHERE i = 3
|
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; UPDATE t SET f = 'magenta 2' WHERE f = 'red'
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO t VALUES (5 + (2 * 10),"brown")
|
|
master-bin.000001 # Query # # ROLLBACK
|
|
SET AUTOCOMMIT = 1;
|
|
BEGIN;
|
|
UPDATE t SET f = 'gray 2' WHERE i = 3;
|
|
Warnings:
|
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement accesses nontransactional table as well as transactional or temporary table, and writes to any of them.
|
|
SET AUTOCOMMIT = 1;
|
|
BEGIN;
|
|
UPDATE t SET f = 'dark blue 2' WHERE f = 'red';
|
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
|
INSERT INTO t VALUES (6 + (2 * 10),"brown");
|
|
INSERT INTO n VALUES (now(),"brown");
|
|
COMMIT;
|
|
COMMIT;
|
|
show binlog events from <binlog_start>;
|
|
Log_name Pos Event_type Server_id End_log_pos Info
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO n VALUES (now(),"brown")
|
|
master-bin.000001 # Query # # COMMIT
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; UPDATE t SET f = 'gray 2' WHERE i = 3
|
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; UPDATE t SET f = 'dark blue 2' WHERE f = 'red'
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO t VALUES (6 + (2 * 10),"brown")
|
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
|
SET AUTOCOMMIT = 0;
|
|
UPDATE t SET f = 'yellow 1' WHERE i = 3;
|
|
Warnings:
|
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement accesses nontransactional table as well as transactional or temporary table, and writes to any of them.
|
|
SET AUTOCOMMIT = 0;
|
|
UPDATE t SET f = 'magenta 1' WHERE f = 'red';
|
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
|
INSERT INTO t VALUES (5 + (1 * 10),"brown");
|
|
INSERT INTO n VALUES (now(),"brown");
|
|
COMMIT;
|
|
ROLLBACK;
|
|
Warnings:
|
|
Warning 1196 Some non-transactional changed tables couldn't be rolled back
|
|
show binlog events from <binlog_start>;
|
|
Log_name Pos Event_type Server_id End_log_pos Info
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO n VALUES (now(),"brown")
|
|
master-bin.000001 # Query # # COMMIT
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; UPDATE t SET f = 'yellow 1' WHERE i = 3
|
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; UPDATE t SET f = 'magenta 1' WHERE f = 'red'
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO t VALUES (5 + (1 * 10),"brown")
|
|
master-bin.000001 # Query # # ROLLBACK
|
|
SET AUTOCOMMIT = 0;
|
|
UPDATE t SET f = 'gray 1' WHERE i = 3;
|
|
Warnings:
|
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement accesses nontransactional table as well as transactional or temporary table, and writes to any of them.
|
|
SET AUTOCOMMIT = 0;
|
|
UPDATE t SET f = 'dark blue 1' WHERE f = 'red';
|
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
|
INSERT INTO t VALUES (6 + (1 * 10),"brown");
|
|
INSERT INTO n VALUES (now(),"brown");
|
|
COMMIT;
|
|
COMMIT;
|
|
show binlog events from <binlog_start>;
|
|
Log_name Pos Event_type Server_id End_log_pos Info
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO n VALUES (now(),"brown")
|
|
master-bin.000001 # Query # # COMMIT
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; UPDATE t SET f = 'gray 1' WHERE i = 3
|
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; UPDATE t SET f = 'dark blue 1' WHERE f = 'red'
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO t VALUES (6 + (1 * 10),"brown")
|
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
|
source include/diff_master_slave.inc;
|
|
source include/diff_master_slave.inc;
|
|
########################################################################
|
|
# Cleanup
|
|
########################################################################
|
|
DROP TRIGGER tr;
|
|
DROP TABLE t;
|
|
DROP TABLE n;
|