summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Widenius <monty@mariadb.org>2019-10-21 17:17:09 +0300
committerMichael Widenius <monty@mariadb.org>2019-10-21 17:17:09 +0300
commit06d2e1d828140d887adb68b05c85d5107baf816c (patch)
treefa3cbcadb16c80c0163d44bfdd6ef418aa8004f8
parent7def2877e3d7bd5335a0a53c20c01948407ab775 (diff)
downloadmariadb-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.result21
-rw-r--r--mysql-test/suite/binlog/r/read_only_statement.result21
-rw-r--r--mysql-test/suite/binlog/t/read_only.inc7
-rw-r--r--mysql-test/suite/rpl/r/rpl_read_only2.result53
-rw-r--r--mysql-test/suite/rpl/t/rpl_read_only2.test30
-rw-r--r--sql/sql_admin.cc6
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_table.cc2
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);