mirror of
https://github.com/MariaDB/server.git
synced 2025-11-28 17:36:30 +03:00
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.
107 lines
5.4 KiB
Plaintext
107 lines
5.4 KiB
Plaintext
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
|
|
CREATE TABLE t1m (m INT, n INT) ENGINE=MYISAM;
|
|
CREATE TABLE t1b (b INT, c INT) ENGINE=BLACKHOLE;
|
|
CREATE TABLE t1n (e INT, f INT) ENGINE=NDB;
|
|
RESET MASTER;
|
|
SET SESSION BINLOG_FORMAT=STATEMENT;
|
|
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;
|
|
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 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.
|
|
UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c;
|
|
COMMIT;
|
|
TRUNCATE t1m;
|
|
TRUNCATE t1b;
|
|
TRUNCATE t1n;
|
|
show binlog events from <binlog_start>;
|
|
Log_name Pos Event_type Server_id End_log_pos Info
|
|
mysqld-bin.000001 # Query # # BEGIN
|
|
mysqld-bin.000001 # Query # # use `test`; INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2)
|
|
mysqld-bin.000001 # Query # # COMMIT
|
|
mysqld-bin.000001 # Query # # BEGIN
|
|
mysqld-bin.000001 # Query # # use `test`; INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2)
|
|
mysqld-bin.000001 # Query # # COMMIT
|
|
mysqld-bin.000001 # Query # # BEGIN
|
|
mysqld-bin.000001 # Query # # use `test`; UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c
|
|
mysqld-bin.000001 # Query # # COMMIT
|
|
mysqld-bin.000001 # Query # # BEGIN
|
|
mysqld-bin.000001 # Query # # use `test`; UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c
|
|
mysqld-bin.000001 # Query # # COMMIT
|
|
mysqld-bin.000001 # Query # # BEGIN
|
|
mysqld-bin.000001 # Query # # use `test`; INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2)
|
|
mysqld-bin.000001 # Query # # use `test`; UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f
|
|
mysqld-bin.000001 # Query # # COMMIT
|
|
mysqld-bin.000001 # Query # # BEGIN
|
|
mysqld-bin.000001 # Table_map # # table_id: # (test.t1n)
|
|
mysqld-bin.000001 # Table_map # # table_id: # (mysql.ndb_apply_status)
|
|
mysqld-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
|
mysqld-bin.000001 # Query # # COMMIT
|
|
mysqld-bin.000001 # Query # # use `test`; TRUNCATE t1m
|
|
mysqld-bin.000001 # Query # # use `test`; TRUNCATE t1b
|
|
mysqld-bin.000001 # Query # # use `test`; TRUNCATE t1n
|
|
RESET MASTER;
|
|
SET SESSION BINLOG_FORMAT=MIXED;
|
|
INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2);
|
|
INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2);
|
|
The last event before the COMMIT is use `test`; INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2)
|
|
INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2);
|
|
UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c;
|
|
UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
|
|
ERROR HY000: Cannot execute statement: impossible to write to binary log since more than one engine is involved and at least one engine is self-logging.
|
|
TRUNCATE t1m;
|
|
TRUNCATE t1b;
|
|
TRUNCATE t1n;
|
|
show binlog events from <binlog_start>;
|
|
Log_name Pos Event_type Server_id End_log_pos Info
|
|
mysqld-bin.000001 # Query # # BEGIN
|
|
mysqld-bin.000001 # Query # # use `test`; INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2)
|
|
mysqld-bin.000001 # Query # # COMMIT
|
|
mysqld-bin.000001 # Query # # BEGIN
|
|
mysqld-bin.000001 # Query # # use `test`; INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2)
|
|
mysqld-bin.000001 # Query # # COMMIT
|
|
mysqld-bin.000001 # Query # # BEGIN
|
|
mysqld-bin.000001 # Table_map # # table_id: # (test.t1n)
|
|
mysqld-bin.000001 # Table_map # # table_id: # (mysql.ndb_apply_status)
|
|
mysqld-bin.000001 # Write_rows # # table_id: #
|
|
mysqld-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
|
mysqld-bin.000001 # Query # # COMMIT
|
|
mysqld-bin.000001 # Query # # BEGIN
|
|
mysqld-bin.000001 # Query # # use `test`; UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c
|
|
mysqld-bin.000001 # Query # # COMMIT
|
|
mysqld-bin.000001 # Query # # use `test`; TRUNCATE t1m
|
|
mysqld-bin.000001 # Query # # use `test`; TRUNCATE t1b
|
|
mysqld-bin.000001 # Query # # use `test`; TRUNCATE t1n
|
|
RESET MASTER;
|
|
SET SESSION BINLOG_FORMAT=ROW;
|
|
INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2);
|
|
INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2);
|
|
INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2);
|
|
UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
|
|
ERROR HY000: Cannot execute statement: impossible to write to binary log since more than one engine is involved and at least one engine is self-logging.
|
|
UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c;
|
|
ERROR HY000: Cannot execute statement: impossible to write to binary log since more than one engine is involved and at least one engine is self-logging.
|
|
show binlog events from <binlog_start>;
|
|
Log_name Pos Event_type Server_id End_log_pos Info
|
|
mysqld-bin.000001 # Query # # BEGIN
|
|
mysqld-bin.000001 # Table_map # # table_id: # (test.t1m)
|
|
mysqld-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
|
mysqld-bin.000001 # Query # # COMMIT
|
|
mysqld-bin.000001 # Query # # BEGIN
|
|
mysqld-bin.000001 # Table_map # # table_id: # (test.t1b)
|
|
mysqld-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
|
mysqld-bin.000001 # Query # # COMMIT
|
|
mysqld-bin.000001 # Query # # BEGIN
|
|
mysqld-bin.000001 # Table_map # # table_id: # (test.t1n)
|
|
mysqld-bin.000001 # Table_map # # table_id: # (mysql.ndb_apply_status)
|
|
mysqld-bin.000001 # Write_rows # # table_id: #
|
|
mysqld-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
|
mysqld-bin.000001 # Query # # COMMIT
|
|
RESET MASTER;
|
|
DROP TABLE t1m, t1b, t1n;
|