diff options
author | Michael Widenius <monty@mariadb.org> | 2019-10-21 17:17:09 +0300 |
---|---|---|
committer | Michael Widenius <monty@mariadb.org> | 2019-10-21 17:17:09 +0300 |
commit | 06d2e1d828140d887adb68b05c85d5107baf816c (patch) | |
tree | fa3cbcadb16c80c0163d44bfdd6ef418aa8004f8 | |
parent | 7def2877e3d7bd5335a0a53c20c01948407ab775 (diff) | |
download | mariadb-git-06d2e1d828140d887adb68b05c85d5107baf816c.tar.gz |
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.
-rw-r--r-- | mysql-test/suite/binlog/r/read_only.result | 21 | ||||
-rw-r--r-- | mysql-test/suite/binlog/r/read_only_statement.result | 21 | ||||
-rw-r--r-- | mysql-test/suite/binlog/t/read_only.inc | 7 | ||||
-rw-r--r-- | mysql-test/suite/rpl/r/rpl_read_only2.result | 53 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_read_only2.test | 30 | ||||
-rw-r--r-- | sql/sql_admin.cc | 6 | ||||
-rw-r--r-- | sql/sql_class.cc | 2 | ||||
-rw-r--r-- | sql/sql_table.cc | 2 |
8 files changed, 135 insertions, 7 deletions
diff --git a/mysql-test/suite/binlog/r/read_only.result b/mysql-test/suite/binlog/r/read_only.result index aa1893b56a3..8aaad55684b 100644 --- a/mysql-test/suite/binlog/r/read_only.result +++ b/mysql-test/suite/binlog/r/read_only.result @@ -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; diff --git a/mysql-test/suite/binlog/r/read_only_statement.result b/mysql-test/suite/binlog/r/read_only_statement.result index aa1893b56a3..8aaad55684b 100644 --- a/mysql-test/suite/binlog/r/read_only_statement.result +++ b/mysql-test/suite/binlog/r/read_only_statement.result @@ -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; diff --git a/mysql-test/suite/binlog/t/read_only.inc b/mysql-test/suite/binlog/t/read_only.inc index 75cd4a5dfb3..37f1cb3b2b8 100644 --- a/mysql-test/suite/binlog/t/read_only.inc +++ b/mysql-test/suite/binlog/t/read_only.inc @@ -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 diff --git a/mysql-test/suite/rpl/r/rpl_read_only2.result b/mysql-test/suite/rpl/r/rpl_read_only2.result new file mode 100644 index 00000000000..c457f49e67d --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_read_only2.result @@ -0,0 +1,53 @@ +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 diff --git a/mysql-test/suite/rpl/t/rpl_read_only2.test b/mysql-test/suite/rpl/t/rpl_read_only2.test new file mode 100644 index 00000000000..da825c8fc7f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_read_only2.test @@ -0,0 +1,30 @@ +--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 diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index 297733a00a7..dde194053b9 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -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 diff --git a/sql/sql_class.cc b/sql/sql_class.cc index f79d8828fcd..9875f0cd14a 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -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", diff --git a/sql/sql_table.cc b/sql/sql_table.cc index ebf268fe8c8..8eb0b078bd1 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -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); |