mirror of
https://github.com/MariaDB/server.git
synced 2025-11-24 06:01:25 +03:00
BUG#53560 CREATE TEMP./DROP TEMP. are not binglogged correctly after a failed statement
This patch fixes two problems described as follows:
1 - If there is an on-going transaction and a temporary table is created or
dropped, any failed statement that follows the "create" or "drop commands"
triggers a rollback and by consequence the slave will go out sync because
the binary log will have a wrong sequence of events.
To fix the problem, we changed the expression that evaluates when the
cache should be flushed after either the rollback of a statment or
transaction.
2 - When a "CREATE TEMPORARY TABLE SELECT * FROM" was executed the
OPTION_KEEP_LOG was not set into the thd->options. For that reason, if
the transaction had updated only transactional engines and was rolled
back at the end (.e.g due to a deadlock) the changes were not written
to the binary log, including the creation of the temporary table.
To fix the problem, we have set the OPTION_KEEP_LOG into the thd->options
when a "CREATE TEMPORARY TABLE SELECT * FROM" is executed.
sql/log.cc:
Reorganized the code based on the following functions:
- bool ending_trans(const THD* thd, const bool all);
- bool trans_has_updated_non_trans_table(const THD* thd);
- bool trans_has_no_stmt_committed(const THD* thd, const bool all);
- bool stmt_has_updated_non_trans_table(const THD* thd);
sql/log.h:
Added functions to organize the code in log.cc.
sql/log_event.cc:
Removed the OPTION_KEEP_LOG since it must be used only when
creating and dropping temporary tables.
sql/log_event_old.cc:
Removed the OPTION_KEEP_LOG since it must be used only when
creating and dropping temporary tables.
sql/sql_parse.cc:
When a "CREATE TEMPORARY TABLE SELECT * FROM" was executed the
OPTION_KEEP_LOG was not set into the thd->options.
To fix the problem, we have set the OPTION_KEEP_LOG into the
thd->options when a "CREATE TEMPORARY TABLE SELECT * FROM"
is executed.
This commit is contained in:
@@ -81,4 +81,61 @@ Last_SQL_Errno 0
|
||||
Last_SQL_Error
|
||||
DROP TABLE t1;
|
||||
**** On Master ****
|
||||
SET SQL_LOG_BIN= 0;
|
||||
DROP TABLE t1;
|
||||
SET SQL_LOG_BIN= 1;
|
||||
SET SESSION BINLOG_FORMAT=MIXED;
|
||||
CREATE TABLE t_myisam (id INT, PRIMARY KEY (id)) engine= MyIsam;
|
||||
INSERT INTO t_myisam (id) VALUES(1);
|
||||
CREATE TABLE t_innodb (id INT) engine= Innodb;
|
||||
INSERT INTO t_innodb (id) VALUES(1);
|
||||
BEGIN;
|
||||
INSERT INTO t_innodb(id) VALUES(2);
|
||||
INSERT INTO t_myisam(id) VALUES(3);
|
||||
CREATE TEMPORARY TABLE x (id INT);
|
||||
INSERT INTO t_myisam(id) VALUES(4),(1);
|
||||
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
|
||||
INSERT INTO t_innodb(id) VALUES(5);
|
||||
COMMIT;
|
||||
SELECT * FROM t_innodb;
|
||||
id
|
||||
1
|
||||
2
|
||||
5
|
||||
SELECT * FROM t_myisam;
|
||||
id
|
||||
1
|
||||
3
|
||||
4
|
||||
SELECT * FROM t_innodb;
|
||||
id
|
||||
1
|
||||
2
|
||||
5
|
||||
SELECT * FROM t_myisam;
|
||||
id
|
||||
1
|
||||
3
|
||||
4
|
||||
BEGIN;
|
||||
CREATE TEMPORARY TABLE tmp2 SELECT * FROM t_innodb;
|
||||
INSERT INTO t_innodb(id) VALUES(1);
|
||||
INSERT INTO t_innodb(id) VALUES(1);
|
||||
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 t_innodb(id) VALUES(2)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO t_myisam(id) VALUES(3)
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE x (id INT)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO t_myisam(id) VALUES(4),(1)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO t_innodb(id) VALUES(5)
|
||||
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp2 SELECT * FROM t_innodb
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO t_innodb(id) VALUES(1)
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO t_innodb(id) VALUES(1)
|
||||
master-bin.000001 # Query # # ROLLBACK
|
||||
DROP TABLE t_myisam, t_innodb;
|
||||
|
||||
Reference in New Issue
Block a user