mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 05:22:25 +01:00
Bug#55478 Row events wrongly apply on the temporary table of the same name
Rows events were applied wrongly on the temporary table with the same name. But rows events are generated only for base tables. As temporary table's data never be binlogged on row mode. Normally, base table of the same name cannot be updated if a temporary table has the same name. But there are two cases which can generate rows events on the base table of same name. Case1: 'CREATE TABLE ... SELECT' statement. In mixed format, it will generate rows events if it is unsafe. Case2: Drop a transactional temporary table in a transaction (happens only on 5.5+). BEGIN; DROP TEMPORARY TABLE t1; # t1 is a InnoDB table INSERT INTO t1 VALUES(rand()); # t1 is a MyISAM table COMMIT; 'DROP TEMPORARY TABLE' will be put in the transaction cache and binlogged after the rows events generated by the 'INSERT' statement. After this patch, slave opens only base table when applying a rows event.
This commit is contained in:
parent
560ee2158d
commit
aa235b1b15
3 changed files with 98 additions and 0 deletions
|
@ -69,3 +69,47 @@ slave-bin.000001 # Query # # COMMIT
|
|||
slave-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `t2_tmp` /* generated by server */
|
||||
slave-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (2)
|
||||
slave-bin.000001 # Query # # use `test`; DROP TABLE t3, t1
|
||||
|
||||
# Bug#55478 Row events wrongly apply on the temporary table of the same name
|
||||
# ==========================================================================
|
||||
# The statement should be binlogged
|
||||
CREATE TEMPORARY TABLE t1(c1 INT) ENGINE=InnoDB;
|
||||
|
||||
# Case 1: CREATE TABLE t1 ... SELECT
|
||||
# ----------------------------------
|
||||
|
||||
# The statement generates row events on t1. And the rows events should
|
||||
# be inserted into the base table on slave.
|
||||
CREATE TABLE t1 ENGINE=MyISAM SELECT rand();
|
||||
show binlog events in 'master-bin.000001' 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`; CREATE TABLE `t1` (
|
||||
`rand()` double NOT NULL DEFAULT '0'
|
||||
) ENGINE=MyISAM
|
||||
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
|
||||
# Case 2: DROP TEMPORARY TABLE in a transacation(happens only on 5.5+)
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
BEGIN;
|
||||
DROP TEMPORARY TABLE t1;
|
||||
# The statement will binlogged after 'DROP TEMPORARY TABLE t1'
|
||||
INSERT INTO t1 VALUES(1);
|
||||
# The rows event will binlogged after 'INSERT INTO t1 VALUES(1)'
|
||||
INSERT INTO t1 VALUES(Rand());
|
||||
COMMIT;
|
||||
show binlog events in 'master-bin.000001' from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `t1` /* generated by server */
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES(1)
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
# Compare the base table.
|
||||
Comparing tables master:test.t1 and slave:test.t1
|
||||
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
source include/master-slave.inc;
|
||||
source include/have_binlog_format_mixed.inc;
|
||||
source include/have_innodb.inc;
|
||||
|
||||
--echo ==== Initialize ====
|
||||
|
||||
|
@ -146,3 +147,55 @@ DROP TABLE t3, t1;
|
|||
-- sync_slave_with_master
|
||||
|
||||
-- source include/show_binlog_events.inc
|
||||
|
||||
--echo
|
||||
--echo # Bug#55478 Row events wrongly apply on the temporary table of the same name
|
||||
--echo # ==========================================================================
|
||||
connection master;
|
||||
|
||||
let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1);
|
||||
let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
|
||||
--echo # The statement should be binlogged
|
||||
CREATE TEMPORARY TABLE t1(c1 INT) ENGINE=InnoDB;
|
||||
|
||||
--echo
|
||||
--echo # Case 1: CREATE TABLE t1 ... SELECT
|
||||
--echo # ----------------------------------
|
||||
let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1);
|
||||
let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
|
||||
--echo
|
||||
--echo # The statement generates row events on t1. And the rows events should
|
||||
--echo # be inserted into the base table on slave.
|
||||
CREATE TABLE t1 ENGINE=MyISAM SELECT rand();
|
||||
|
||||
source include/show_binlog_events.inc;
|
||||
let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1);
|
||||
let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
|
||||
--echo
|
||||
--echo # Case 2: DROP TEMPORARY TABLE in a transacation(happens only on 5.5+)
|
||||
--echo # --------------------------------------------------------------------
|
||||
--echo
|
||||
|
||||
BEGIN;
|
||||
DROP TEMPORARY TABLE t1;
|
||||
|
||||
--echo # The statement will binlogged after 'DROP TEMPORARY TABLE t1'
|
||||
INSERT INTO t1 VALUES(1);
|
||||
|
||||
--echo # The rows event will binlogged after 'INSERT INTO t1 VALUES(1)'
|
||||
INSERT INTO t1 VALUES(Rand());
|
||||
COMMIT;
|
||||
|
||||
source include/show_binlog_events.inc;
|
||||
|
||||
--echo # Compare the base table.
|
||||
let diff_table= test.t1;
|
||||
source include/rpl_diff_tables.inc;
|
||||
|
||||
--echo
|
||||
connection master;
|
||||
DROP TABLE t1;
|
||||
source include/master-slave-end.inc;
|
||||
|
|
|
@ -8258,6 +8258,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
|
|||
m_field_metadata, m_field_metadata_size,
|
||||
m_null_bits, m_flags);
|
||||
table_list->m_tabledef_valid= TRUE;
|
||||
table_list->skip_temporary= 1;
|
||||
|
||||
/*
|
||||
We record in the slave's information that the table should be
|
||||
|
|
Loading…
Reference in a new issue