From a85b8d3149600f7a55a22bf76b32aa949071a00d Mon Sep 17 00:00:00 2001 From: Abhinav Sharma Date: Tue, 1 Aug 2017 17:24:00 -0700 Subject: [PATCH] SBR support for binlog trx meta data Summary: Supporting binlog trx meta data for SBR. The meta data event is written right before every query event in a trx representing a statement. Squash with: D5220355 Reviewed By: tianx Differential Revision: D5530983 fbshipit-source-id: b6a490f --- .../suite/rpl/r/binlog_trx_meta_data.result | 9 ++--- .../suite/rpl/t/binlog_trx_meta_data.test | 34 ++++++++++++------- sql/binlog.cc | 32 +++++++++++------ sql/binlog.h | 3 +- 4 files changed, 49 insertions(+), 29 deletions(-) diff --git a/mysql-test/suite/rpl/r/binlog_trx_meta_data.result b/mysql-test/suite/rpl/r/binlog_trx_meta_data.result index ea7467f3be2d..3692b74333c5 100644 --- a/mysql-test/suite/rpl/r/binlog_trx_meta_data.result +++ b/mysql-test/suite/rpl/r/binlog_trx_meta_data.result @@ -7,10 +7,11 @@ set @save.binlog_trx_meta_data= @@global.binlog_trx_meta_data; set @@global.binlog_trx_meta_data= true; set @save.binlog_trx_meta_data= @@global.binlog_trx_meta_data; set @@global.binlog_trx_meta_data= true; -include/sync_slave_sql_with_master.inc -include/sync_slave_sql_with_master.inc meta count(*) -# /*::TRX_META_DATA::{"timestamps":[ts]}*/ 134 +# /*::TRX_META_DATA::{"timestamps":[ts]}*/ 301 meta count(*) -# /*::TRX_META_DATA::{"timestamps":[ts,ts]}*/ 134 +# /*::TRX_META_DATA::{"timestamps":[ts,ts]}*/ 301 +drop table t1; +set @@global.binlog_trx_meta_data= @save.binlog_trx_meta_data; +set @@global.binlog_trx_meta_data= @save.binlog_trx_meta_data; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/binlog_trx_meta_data.test b/mysql-test/suite/rpl/t/binlog_trx_meta_data.test index ed277c647a44..020ff43ac0d9 100644 --- a/mysql-test/suite/rpl/t/binlog_trx_meta_data.test +++ b/mysql-test/suite/rpl/t/binlog_trx_meta_data.test @@ -1,5 +1,4 @@ source include/master-slave.inc; -source include/have_binlog_format_row.inc; # Enable trx meta data connection master; @@ -12,15 +11,28 @@ set @@global.binlog_trx_meta_data= true; # Generate load connection master; -let $skip_cleanup= 1; -let $sync_with_master= 1; -let $databases=2; -let $iter=5; -source extra/rpl_tests/rpl_parallel_simple_load.test; +disable_result_log; +disable_query_log; +create table t1(a int) engine=innodb; +# the following loop will generate 300 meta data events, 1 for each statement +# the total number of meta data events will be 301, +1 for create stmt above +let $iter= 100; +while ($iter > 0) +{ + begin; + eval insert into t1 values($iter); + eval update t1 set a= $iter + 1; + delete from t1; + commit; + dec $iter; +} enable_result_log; +enable_query_log; +sync_slave_with_master; # Check binlogs for meta data connection master; +disable_query_log; let $MYSQLD_DATADIR = `select @@datadir`; let $MYSQLD_SECURE_FILE_DIR = `select @@secure_file_priv`; exec $MYSQL_BINLOG -v -v $MYSQLD_DATADIR/master-bin.0* | grep "::TRX_META_DATA::" | sed 's/\"[0-9]*\"/ts/g' > $MYSQLD_SECURE_FILE_DIR/meta_data.dat; @@ -43,16 +55,12 @@ select meta, count(*) from test.meta_data; drop table test.meta_data; set sql_log_bin=1; remove_file $MYSQLD_SECURE_FILE_DIR/meta_data.dat; - -# Consistency check -connection master; -let $include_silent=1; -source extra/rpl_tests/rpl_parallel_simple_load_consistency.test; -let $include_silent=; +enable_query_log; # Cleanup connection master; -source extra/rpl_tests/rpl_parallel_simple_load_cleanup.test; +drop table t1; +sync_slave_with_master; connection slave; set @@global.binlog_trx_meta_data= @save.binlog_trx_meta_data; connection master; diff --git a/sql/binlog.cc b/sql/binlog.cc index fd4657a610c8..9fd2f60bcf82 100644 --- a/sql/binlog.cc +++ b/sql/binlog.cc @@ -340,7 +340,8 @@ class binlog_cache_data void add_time_meta_data(THD *thd, ptree &meta_data_root); int finalize(THD *thd, Log_event *end_event); int flush(THD *thd, my_off_t *bytes, bool *wrote_xid, bool async); - int write_event(THD *thd, Log_event *event); + int write_event(THD *thd, Log_event *event, + bool write_meta_data_event= false); virtual ~binlog_cache_data() { @@ -981,7 +982,9 @@ static bool should_write_gtids(THD *thd) { return (!read_only || thd->variables.gtid_next.type == GTID_GROUP); } -int binlog_cache_data::write_event(THD *thd, Log_event *ev) +int binlog_cache_data::write_event(THD *thd, + Log_event *ev, + bool write_meta_data_event) { DBUG_ENTER("binlog_cache_data::write_event"); @@ -1001,6 +1004,11 @@ int binlog_cache_data::write_event(THD *thd, Log_event *ev) if (ev != NULL) { + // case: write meta data event before the real event + // see @opt_binlog_trx_meta_data + if (write_meta_data_event && write_trx_meta_data(thd)) + DBUG_RETURN(1); + DBUG_EXECUTE_IF("simulate_disk_full_at_flush_pending", {DBUG_SET("+d,simulate_file_write_error");}); if (ev->write(&cache_log) != 0) @@ -5830,7 +5838,9 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd, Write an event to the binary log. */ -bool MYSQL_BIN_LOG::write_event(Log_event *event_info, int force_cache_type) +bool MYSQL_BIN_LOG::write_event(Log_event *event_info, + int force_cache_type, + bool write_meta_data_event) { THD *thd= event_info->thd; bool error= 1; @@ -5980,7 +5990,7 @@ bool MYSQL_BIN_LOG::write_event(Log_event *event_info, int force_cache_type) /* Write the event. */ - if (cache_data->write_event(thd, event_info) || + if (cache_data->write_event(thd, event_info, write_meta_data_event) || DBUG_EVALUATE_IF("injecting_fault_writing", true, false)) goto err; @@ -8397,11 +8407,6 @@ int THD::binlog_write_table_map(TABLE *table, bool is_transactional, binlog_cache_data *cache_data= cache_mngr->get_binlog_cache_data(is_transactional); - // case: add meta data in the binlog - if (opt_binlog_trx_meta_data && - (error= cache_data->write_trx_meta_data(this))) - DBUG_RETURN(error); - if (binlog_rows_query && this->query()) { /* Write the Rows_query_log_event into binlog before the table map */ @@ -8411,7 +8416,8 @@ int THD::binlog_write_table_map(TABLE *table, bool is_transactional, DBUG_RETURN(error); } - if ((error= cache_data->write_event(this, &the_event))) + if ((error= cache_data->write_event(this, &the_event, + opt_binlog_trx_meta_data))) DBUG_RETURN(error); binlog_table_maps++; @@ -10233,7 +10239,11 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg, log event is written to the binary log, we pretend that no table maps were written. */ - int error= mysql_bin_log.write_event(&qinfo); + int error= mysql_bin_log.write_event(&qinfo, + /* default parameter */ + Log_event::EVENT_INVALID_CACHE, + /* write meta data before query? */ + opt_binlog_trx_meta_data); binlog_table_maps= 0; DBUG_RETURN(error); } diff --git a/sql/binlog.h b/sql/binlog.h index d86f7e778029..c703e3d1e88f 100644 --- a/sql/binlog.h +++ b/sql/binlog.h @@ -664,7 +664,8 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG int new_file(Format_description_log_event *extra_description_event); bool write_event(Log_event* event_info, - int force_cache_type = Log_event::EVENT_INVALID_CACHE); + int force_cache_type = Log_event::EVENT_INVALID_CACHE, + bool write_meta_data_event= false); bool write_cache(THD *thd, class binlog_cache_data *binlog_cache_data, bool async); int do_write_cache(IO_CACHE *cache);