Commit 06d2e1d8 authored by Michael Widenius's avatar Michael Widenius

read-only slave using statement replication should replicate tmp tables

Relates to MDEV-17863 DROP TEMPORARY TABLE creates a transaction in
binary log on read only server

Other things:
- Fixed that insert into normal_table select from tmp_table is
  replicated as row events if tmp_table doesn't exists on slave.
parent 7def2877
......@@ -46,6 +46,8 @@ select * from tmp2;
a b
1 NULL
2 NULL
insert into t1 select a+100 from tmp2;
ERROR HY000: The MariaDB server is running with the --read-only option so it cannot execute this statement
drop table tmp1,tmp2,tmp3;
# Clean up test connection
disconnect con1;
......@@ -92,8 +94,20 @@ a b c
11 4 NULL
20 5 1
21 5 2
insert into t1 select a+200 from tmp5;
select * from t1;
a
1
2
201
202
210
211
220
221
drop table tmp4,tmp5;
# Check what is logged. Only the last create select should be row-logged
# Check what is logged. Only last create select and the insert...select's should be
# row-logged
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
......@@ -104,6 +118,11 @@ master-bin.000001 # Annotate_rows # # create table t2 select * from tmp4
master-bin.000001 # Table_map # # table_id: # (test.t2)
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Annotate_rows # # insert into t1 select a+200 from tmp5
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT
# Clean up
drop user test@localhost;
drop table t1,t2;
......@@ -46,6 +46,8 @@ select * from tmp2;
a b
1 NULL
2 NULL
insert into t1 select a+100 from tmp2;
ERROR HY000: The MariaDB server is running with the --read-only option so it cannot execute this statement
drop table tmp1,tmp2,tmp3;
# Clean up test connection
disconnect con1;
......@@ -92,8 +94,20 @@ a b c
11 4 NULL
20 5 1
21 5 2
insert into t1 select a+200 from tmp5;
select * from t1;
a
1
2
201
202
210
211
220
221
drop table tmp4,tmp5;
# Check what is logged. Only the last create select should be row-logged
# Check what is logged. Only last create select and the insert...select's should be
# row-logged
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
......@@ -104,6 +118,11 @@ master-bin.000001 # Annotate_rows # # create table t2 select * from tmp4
master-bin.000001 # Table_map # # table_id: # (test.t2)
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Annotate_rows # # insert into t1 select a+200 from tmp5
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT
# Clean up
drop user test@localhost;
drop table t1,t2;
......@@ -34,6 +34,8 @@ create temporary table tmp3 like t1;
create or replace temporary table tmp3 like t1;
alter table tmp2 add column (b int);
select * from tmp2;
--error ER_OPTION_PREVENTS_STATEMENT
insert into t1 select a+100 from tmp2;
drop table tmp1,tmp2,tmp3;
--echo # Clean up test connection
......@@ -64,9 +66,12 @@ create table t2 select * from tmp4;
alter table tmp5 add column (c int);
insert into tmp5 values (20,5,1),(21,5,2);
select * from tmp5;
insert into t1 select a+200 from tmp5;
select * from t1;
drop table tmp4,tmp5;
--echo # Check what is logged. Only the last create select should be row-logged
--echo # Check what is logged. Only last create select and the insert...select's should be
--echo # row-logged
source include/show_binlog_events.inc;
--echo # Clean up
......
include/master-slave.inc
[connection master]
#
# Ensure that read-only slave logs temporary table statements under statement based
# replication. This is related to MDEV-17863.
#
connection slave;
set global read_only=1;
connection master;
create table t1(a int) engine=MyISAM;
create temporary table tmp1 (a int) engine=MyISAM;
insert into t1 values(1);
insert into tmp1 values (2);
insert into t1 select * from tmp1;
insert into t1 values(3);
select * from t1;
a
1
2
3
analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
drop table t1;
drop temporary table tmp1;
connection slave;
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
slave-bin.000001 # Gtid # # GTID #-#-#
slave-bin.000001 # Query # # use `test`; create table t1(a int) engine=MyISAM
slave-bin.000001 # Gtid # # GTID #-#-#
slave-bin.000001 # Query # # use `test`; create temporary table tmp1 (a int) engine=MyISAM
slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
slave-bin.000001 # Query # # use `test`; insert into t1 values(1)
slave-bin.000001 # Query # # COMMIT
slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
slave-bin.000001 # Query # # use `test`; insert into tmp1 values (2)
slave-bin.000001 # Query # # COMMIT
slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
slave-bin.000001 # Query # # use `test`; insert into t1 select * from tmp1
slave-bin.000001 # Query # # COMMIT
slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
slave-bin.000001 # Query # # use `test`; insert into t1 values(3)
slave-bin.000001 # Query # # COMMIT
slave-bin.000001 # Gtid # # GTID #-#-#
slave-bin.000001 # Query # # use `test`; analyze table t1
slave-bin.000001 # Gtid # # GTID #-#-#
slave-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by server */
slave-bin.000001 # Gtid # # GTID #-#-#
slave-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tmp1` /* generated by server */
set global read_only=0;
connection master;
include/rpl_end.inc
--source include/have_binlog_format_statement.inc
--source include/master-slave.inc
--echo #
--echo # Ensure that read-only slave logs temporary table statements under statement based
--echo # replication. This is related to MDEV-17863.
--echo #
connection slave;
set global read_only=1;
connection master;
create table t1(a int) engine=MyISAM;
create temporary table tmp1 (a int) engine=MyISAM;
insert into t1 values(1);
insert into tmp1 values (2);
insert into t1 select * from tmp1;
insert into t1 values(3);
select * from t1;
analyze table t1;
drop table t1;
drop temporary table tmp1;
sync_slave_with_master;
--source include/show_binlog_events.inc
set global read_only=0;
connection master;
--source include/rpl_end.inc
......@@ -1314,7 +1314,7 @@ bool Sql_cmd_analyze_table::execute(THD *thd)
"analyze", lock_type, 1, 0, 0, 0,
&handler::ha_analyze, 0);
/* ! we write after unlocking the table */
if (!res && !m_lex->no_write_to_binlog && !opt_readonly)
if (!res && !m_lex->no_write_to_binlog && (!opt_readonly || thd->slave_thread))
{
/*
Presumably, ANALYZE and binlog writing doesn't require synchronization
......@@ -1372,7 +1372,7 @@ bool Sql_cmd_optimize_table::execute(THD *thd)
"optimize", TL_WRITE, 1, 0, 0, 0,
&handler::ha_optimize, 0);
/* ! we write after unlocking the table */
if (!res && !m_lex->no_write_to_binlog && !opt_readonly)
if (!res && !m_lex->no_write_to_binlog && (!opt_readonly || thd->slave_thread))
{
/*
Presumably, OPTIMIZE and binlog writing doesn't require synchronization
......@@ -1406,7 +1406,7 @@ bool Sql_cmd_repair_table::execute(THD *thd)
&handler::ha_repair, &view_repair);
/* ! we write after unlocking the table */
if (!res && !m_lex->no_write_to_binlog && !opt_readonly)
if (!res && !m_lex->no_write_to_binlog && (!opt_readonly || thd->slave_thread))
{
/*
Presumably, REPAIR and binlog writing doesn't require synchronization
......
......@@ -6040,6 +6040,8 @@ int THD::decide_logging_format(TABLE_LIST *tables)
*/
DBUG_ASSERT(share->tmp_table);
flags&= ~HA_BINLOG_STMT_CAPABLE;
/* We can only use row logging */
set_current_stmt_binlog_format_row();
}
DBUG_PRINT("info", ("table: %s; ha_table_flags: 0x%llx",
......
......@@ -5217,7 +5217,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
err:
/* In RBR or readonly server we don't need to log CREATE TEMPORARY TABLE */
if (!result && create_info->tmp_table() &&
(thd->is_current_stmt_binlog_format_row() || opt_readonly))
(thd->is_current_stmt_binlog_format_row() || (opt_readonly && !thd->slave_thread)))
{
/* Note that table->s->table_creation_was_logged is not set! */
DBUG_RETURN(result);
......
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