diff --git a/mysql-test/suite/rpl/r/bug88057.result b/mysql-test/suite/rpl/r/bug88057.result new file mode 100644 index 0000000..c278263 --- /dev/null +++ b/mysql-test/suite/rpl/r/bug88057.result @@ -0,0 +1,89 @@ +include/rpl_init.inc [topology=1->2->3] +Warnings: +Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. +Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. +Warnings: +Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. +Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. +### +# Create table on server 1 +##### +[connection server_1] +CREATE TABLE t1(a INT NOT NULL) ENGINE=innodb; +### +# Turn table into black hole on server 2 +##### +include/sync_slave_sql_with_master.inc +SET sql_log_bin = 0; +ALTER TABLE t1 ENGINE = blackhole; +SET sql_log_bin = 1; +### +# Generate insert, update, delete on server 1 +##### +[connection server_1] +INSERT INTO t1 (a) values (1), (2), (3); +ALTER TABLE t1 ADD PRIMARY KEY pk_t1 (a); +UPDATE t1 SET a = 22 WHERE a = 2; +DELETE FROM t1 WHERE a = 3; +SELECT * FROM t1; +a +1 +22 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; CREATE TABLE t1(a INT NOT NULL) ENGINE=innodb +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Rows_query # # # INSERT INTO t1 (a) values (1), (2), (3) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; ALTER TABLE t1 ADD PRIMARY KEY pk_t1 (a) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Rows_query # # # UPDATE t1 SET a = 22 WHERE a = 2 +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Update_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Rows_query # # # DELETE FROM t1 WHERE a = 3 +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Delete_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ +### +# Sync server 2 with server 1 +##### +include/sync_slave_sql_with_master.inc +SELECT * FROM t1; +a +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000001 # Query # # use `test`; CREATE TABLE t1(a INT NOT NULL) ENGINE=innodb +slave-bin.000001 # Query # # BEGIN +slave-bin.000001 # Rows_query # # # INSERT INTO t1 (a) values (1), (2), (3) +slave-bin.000001 # Table_map # # table_id: # (test.t1) +slave-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +slave-bin.000001 # Xid # # COMMIT /* XID */ +slave-bin.000001 # Query # # use `test`; ALTER TABLE t1 ADD PRIMARY KEY pk_t1 (a) +slave-bin.000001 # Query # # BEGIN +slave-bin.000001 # Rows_query # # # UPDATE t1 SET a = 22 WHERE a = 2 +slave-bin.000001 # Table_map # # table_id: # (test.t1) +slave-bin.000001 # Update_rows # # table_id: # flags: STMT_END_F +slave-bin.000001 # Xid # # COMMIT /* XID */ +slave-bin.000001 # Query # # BEGIN +slave-bin.000001 # Rows_query # # # DELETE FROM t1 WHERE a = 3 +slave-bin.000001 # Table_map # # table_id: # (test.t1) +slave-bin.000001 # Delete_rows # # table_id: # flags: STMT_END_F +slave-bin.000001 # Xid # # COMMIT /* XID */ +### +# Sync server 3 with server 2 +##### +include/sync_slave_sql_with_master.inc +SELECT * FROM t1; +a +1 +22 +### +# Cleanup +##### +[connection server_1] +DROP TABLE t1; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/bug88057.cnf b/mysql-test/suite/rpl/t/bug88057.cnf new file mode 100644 index 0000000..1934f5c --- /dev/null +++ b/mysql-test/suite/rpl/t/bug88057.cnf @@ -0,0 +1,29 @@ +!include ../my.cnf + +[mysqld.1] +enforce-gtid-consistency=ON +gtid-mode=ON +master-info-repository=TABLE +relay-log-info-repository=TABLE +binlog-rows-query-log-events= ON +log-slave-updates + +[mysqld.2] +enforce-gtid-consistency=ON +gtid-mode=ON +master-info-repository=TABLE +relay-log-info-repository=TABLE +binlog-rows-query-log-events= ON +log-slave-updates + +[mysqld.3] +enforce-gtid-consistency=ON +gtid-mode=ON +master-info-repository=TABLE +relay-log-info-repository=TABLE +binlog-rows-query-log-events= ON +log-slave-updates + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket diff --git a/mysql-test/suite/rpl/t/bug88057.test b/mysql-test/suite/rpl/t/bug88057.test new file mode 100644 index 0000000..5dcf3b5 --- /dev/null +++ b/mysql-test/suite/rpl/t/bug88057.test @@ -0,0 +1,67 @@ +# +# Bug 88057 test case. +# +# Test if some_engine->blackhole->some_engine topology works good if +# binlog-rows-query-log-events = ON +# +--source include/have_binlog_format_row.inc +--source include/not_group_replication_plugin.inc +--source include/have_gtid.inc +--source include/have_innodb.inc +--source include/have_blackhole.inc + +--let $rpl_topology = 1->2->3 +--let $use_gtids = 1 +--source include/rpl_init.inc + +--echo ### +--echo # Create table on server 1 +--echo ##### +--let $rpl_connection_name = server_1 +--source include/rpl_connection.inc +CREATE TABLE t1(a INT NOT NULL) ENGINE=innodb; + +--echo ### +--echo # Turn table into black hole on server 2 +--echo ##### +--let $sync_slave_connection = server_2 +--source include/sync_slave_sql_with_master.inc +SET sql_log_bin = 0; +ALTER TABLE t1 ENGINE = blackhole; +SET sql_log_bin = 1; + +--echo ### +--echo # Generate insert, update, delete on server 1 +--echo ##### +--let $rpl_connection_name = server_1 +--source include/rpl_connection.inc +INSERT INTO t1 (a) values (1), (2), (3); +ALTER TABLE t1 ADD PRIMARY KEY pk_t1 (a); +UPDATE t1 SET a = 22 WHERE a = 2; +DELETE FROM t1 WHERE a = 3; +SELECT * FROM t1; +--source include/show_binlog_events.inc + +--echo ### +--echo # Sync server 2 with server 1 +--echo ##### +--let $sync_slave_connection = server_2 +--source include/sync_slave_sql_with_master.inc +SELECT * FROM t1; +--source include/show_binlog_events.inc + +--echo ### +--echo # Sync server 3 with server 2 +--echo ##### +--let $sync_slave_connection = server_3 +--source include/sync_slave_sql_with_master.inc +SELECT * FROM t1; + +--echo ### +--echo # Cleanup +--echo ##### +--let $rpl_connection_name = server_1 +--source include/rpl_connection.inc +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/storage/blackhole/ha_blackhole.cc b/storage/blackhole/ha_blackhole.cc index f0db538..c4670ca 100644 --- a/storage/blackhole/ha_blackhole.cc +++ b/storage/blackhole/ha_blackhole.cc @@ -18,15 +18,23 @@ #include "probes_mysql.h" #include "ha_blackhole.h" #include "sql_class.h" // THD, SYSTEM_THREAD_SLAVE_* +#include "rpl_rli.h" // THD::rli_slave::rows_query_ev static PSI_memory_key bh_key_memory_blackhole_share; -static bool is_slave_applier(THD *thd) +static inline bool is_slave_applier(const THD &thd) { - return thd->system_thread == SYSTEM_THREAD_SLAVE_SQL || - thd->system_thread == SYSTEM_THREAD_SLAVE_WORKER; + return thd.system_thread == SYSTEM_THREAD_SLAVE_SQL || + thd.system_thread == SYSTEM_THREAD_SLAVE_WORKER; } +static inline bool pretend_for_slave(const THD &thd) +{ + return is_slave_applier(thd) && + (thd.rli_slave->rows_query_ev || thd.query().str == NULL); +} + + /* Static declarations for handlerton */ static handler *blackhole_create_handler(handlerton *hton, @@ -120,7 +128,7 @@ int ha_blackhole::update_row(const uchar *old_data, uchar *new_data) { DBUG_ENTER("ha_blackhole::update_row"); THD *thd= ha_thd(); - if (is_slave_applier(thd) && thd->query().str == NULL) + if (pretend_for_slave(*thd)) DBUG_RETURN(0); DBUG_RETURN(HA_ERR_WRONG_COMMAND); } @@ -129,7 +137,7 @@ int ha_blackhole::delete_row(const uchar *buf) { DBUG_ENTER("ha_blackhole::delete_row"); THD *thd= ha_thd(); - if (is_slave_applier(thd) && thd->query().str == NULL) + if (pretend_for_slave(*thd)) DBUG_RETURN(0); DBUG_RETURN(HA_ERR_WRONG_COMMAND); } @@ -148,7 +156,7 @@ int ha_blackhole::rnd_next(uchar *buf) MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, TRUE); THD *thd= ha_thd(); - if (is_slave_applier(thd) && thd->query().str == NULL) + if (pretend_for_slave(*thd)) rc= 0; else rc= HA_ERR_END_OF_FILE; @@ -239,7 +247,7 @@ int ha_blackhole::index_read_map(uchar * buf, const uchar * key, DBUG_ENTER("ha_blackhole::index_read"); MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); THD *thd= ha_thd(); - if (is_slave_applier(thd) && thd->query().str == NULL) + if (pretend_for_slave(*thd)) rc= 0; else rc= HA_ERR_END_OF_FILE; @@ -257,7 +265,7 @@ int ha_blackhole::index_read_idx_map(uchar * buf, uint idx, const uchar * key, DBUG_ENTER("ha_blackhole::index_read_idx"); MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); THD *thd= ha_thd(); - if (is_slave_applier(thd) && thd->query().str == NULL) + if (pretend_for_slave(*thd)) rc= 0; else rc= HA_ERR_END_OF_FILE; @@ -274,7 +282,7 @@ int ha_blackhole::index_read_last_map(uchar * buf, const uchar * key, DBUG_ENTER("ha_blackhole::index_read_last"); MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); THD *thd= ha_thd(); - if (is_slave_applier(thd) && thd->query().str == NULL) + if (pretend_for_slave(*thd)) rc= 0; else rc= HA_ERR_END_OF_FILE;