diff --git a/plugin/semisync/semisync_master_plugin.cc b/plugin/semisync/semisync_master_plugin.cc index affc063..5c97cda 100644 --- a/plugin/semisync/semisync_master_plugin.cc +++ b/plugin/semisync/semisync_master_plugin.cc @@ -46,8 +46,11 @@ static inline bool is_semi_sync_dump() C_MODE_START int repl_semi_report_binlog_update(Binlog_storage_param *param, - const char *log_file, - my_off_t log_pos) + const char *dir_path, + const char *prev_log_file, + my_off_t prev_log_pos, + const char *log_file, + my_off_t log_pos) { int error= 0; @@ -74,6 +77,14 @@ int repl_semi_report_binlog_sync(Binlog_storage_param *param, return 0; } +int repl_semi_report_binlog_before_init(Binlog_storage_param *param, + const char * server_uuid, + PSI_file_key * key_file_binlog_index, + const char * log_bin_index) +{ + return 0; +} + int repl_semi_report_before_dml(Trans_param *param, int& out) { return 0; @@ -417,8 +428,9 @@ Trans_observer trans_observer = { Binlog_storage_observer storage_observer = { sizeof(Binlog_storage_observer), // len - repl_semi_report_binlog_update, // report_update - repl_semi_report_binlog_sync, // after_sync + repl_semi_report_binlog_update, // report_update + repl_semi_report_binlog_sync, // after_sync + repl_semi_report_binlog_before_init, // before_binlog_init }; Binlog_transmit_observer transmit_observer = { diff --git a/sql/binlog.cc b/sql/binlog.cc index 078cec9..5fa5476 100644 --- a/sql/binlog.cc +++ b/sql/binlog.cc @@ -3844,9 +3844,7 @@ read_gtids_and_update_trx_parser_from_relaylog( @retval TRUNCATED The file was truncated before the end of the first Previous_gtids_log_event. */ -enum enum_read_gtids_from_binlog_status -{ GOT_GTIDS, GOT_PREVIOUS_GTIDS, NO_GTIDS, ERROR, TRUNCATED }; -static enum_read_gtids_from_binlog_status +enum_read_gtids_from_binlog_status read_gtids_from_binlog(const char *filename, Gtid_set *all_gtids, Gtid_set *prev_gtids, Gtid *first_gtid, Sid_map* sid_map, @@ -3861,7 +3859,7 @@ read_gtids_from_binlog(const char *filename, Gtid_set *all_gtids, */ Format_description_log_event fd_ev(BINLOG_VERSION), *fd_ev_p= &fd_ev; if (!fd_ev.is_valid()) - DBUG_RETURN(ERROR); + DBUG_RETURN(READ_BINLOG_ERROR); File file; IO_CACHE log; @@ -3927,9 +3925,9 @@ read_gtids_from_binlog(const char *filename, Gtid_set *all_gtids, Previous_gtids_log_event *prev_gtids_ev= (Previous_gtids_log_event *)ev; if (all_gtids != NULL && prev_gtids_ev->add_to_set(all_gtids) != 0) - ret= ERROR, done= true; + ret= READ_BINLOG_ERROR, done= true; else if (prev_gtids != NULL && prev_gtids_ev->add_to_set(prev_gtids) != 0) - ret= ERROR, done= true; + ret= READ_BINLOG_ERROR, done= true; #ifndef DBUG_OFF char* prev_buffer= prev_gtids_ev->get_str(NULL, NULL); DBUG_PRINT("info", ("Got Previous_gtids from file '%s': Gtid_set='%s'.", @@ -3974,7 +3972,7 @@ read_gtids_from_binlog(const char *filename, Gtid_set *all_gtids, "The first global transaction identifier was read, but " "no other information regarding identifiers existing " "on the previous log files was found."); - ret= ERROR, done= true; + ret= READ_BINLOG_ERROR, done= true; break; } else @@ -3998,13 +3996,13 @@ read_gtids_from_binlog(const char *filename, Gtid_set *all_gtids, Gtid_log_event *gtid_ev= (Gtid_log_event *)ev; rpl_sidno sidno= gtid_ev->get_sidno(sid_map); if (sidno < 0) - ret= ERROR, done= true; + ret= READ_BINLOG_ERROR, done= true; else { if (all_gtids) { if (all_gtids->ensure_sidno(sidno) != RETURN_STATUS_OK) - ret= ERROR, done= true; + ret= READ_BINLOG_ERROR, done= true; all_gtids->_add_gtid(sidno, gtid_ev->get_gno()); DBUG_PRINT("info", ("Got Gtid from file '%s': Gtid(%d, %lld).", filename, sidno, gtid_ev->get_gno())); @@ -4174,7 +4172,7 @@ bool MYSQL_BIN_LOG::find_first_log_not_in_gtid_set(char *binlog_file_name, binlog_previous_gtid_set.get_sid_map(), opt_master_verify_checksum, is_relay_log)) { - case ERROR: + case READ_BINLOG_ERROR: *errmsg= "Error reading header of binary log while looking for " "the oldest binary log that contains any GTID that is not in " "the given gtid set"; @@ -4333,7 +4331,7 @@ bool MYSQL_BIN_LOG::init_gtid_sets(Gtid_set *all_gtids, Gtid_set *lost_gtids, NULL/* first_gtid */, sid_map, verify_checksum, is_relay_log)) { - case ERROR: + case READ_BINLOG_ERROR: { error= 1; goto end; @@ -4499,7 +4497,7 @@ bool MYSQL_BIN_LOG::init_gtid_sets(Gtid_set *all_gtids, Gtid_set *lost_gtids, &first_gtid, sid_map, verify_checksum, is_relay_log)) { - case ERROR: + case READ_BINLOG_ERROR: { error= 1; /*FALLTHROUGH*/ @@ -7775,6 +7773,15 @@ int MYSQL_BIN_LOG::open_binlog(const char *opt_name) DBUG_ASSERT(total_ha_2pc > 1 || (1 == total_ha_2pc && opt_bin_log)); DBUG_ASSERT(opt_name && opt_name[0]); + int ret= RUN_HOOK(binlog_storage, before_binlog_init, + (NULL, server_uuid, &key_file_binlog_index, log_bin_index)); + + if (ret) + { + sql_print_information("RUN_HOOK before_binlog_init ret %d", ret); + unireg_abort(1); + } + if (!my_b_inited(&index_file)) { /* There was a failure to open the index file, can't open the binlog */ @@ -8908,6 +8915,12 @@ int MYSQL_BIN_LOG::ordered_commit(THD *thd, bool all, bool skip_commit) } THD *wait_queue= NULL, *final_queue= NULL; + + std::string dir_path= string(log_file_name, dirname_length(log_file_name)); + const char *prev_file_name= log_file_name + dirname_length(log_file_name); + my_off_t prev_log_pos= my_b_tell(&log_file); + const char *file_name_ptr= log_file_name + dirname_length(log_file_name); + mysql_mutex_t *leave_mutex_before_commit_stage= NULL; my_off_t flush_end_pos= 0; bool update_binlog_end_pos_after_sync; @@ -8941,10 +8954,9 @@ int MYSQL_BIN_LOG::ordered_commit(THD *thd, bool all, bool skip_commit) */ if (flush_error == 0) { - const char *file_name_ptr= log_file_name + dirname_length(log_file_name); DBUG_ASSERT(flush_end_pos != 0); if (RUN_HOOK(binlog_storage, after_flush, - (thd, file_name_ptr, flush_end_pos))) + (thd, dir_path.c_str(), prev_file_name, prev_log_pos, file_name_ptr, flush_end_pos))) { sql_print_error("Failed to run 'after_flush' hooks"); flush_error= ER_ERROR_ON_WRITE; diff --git a/sql/binlog.h b/sql/binlog.h index 3b048cb..b2b471e 100644 --- a/sql/binlog.h +++ b/sql/binlog.h @@ -1057,4 +1057,15 @@ inline bool normalize_binlog_name(char *to, const char *from, bool is_relay_log) end: DBUG_RETURN(error); } + +enum enum_read_gtids_from_binlog_status +{ GOT_GTIDS, GOT_PREVIOUS_GTIDS, NO_GTIDS, READ_BINLOG_ERROR, TRUNCATED }; + +enum_read_gtids_from_binlog_status +read_gtids_from_binlog(const char *filename, Gtid_set *all_gtids, + Gtid_set *prev_gtids, Gtid *first_gtid, + Gtid *last_gtid, + Sid_map *sid_map, + bool verify_checksum); + #endif /* BINLOG_H_INCLUDED */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index eedd63b..c0401a0 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3570,8 +3570,13 @@ int flush_auto_options(const char* fname) @todo consider to implement sql-query-able persistent storage by WL#5279. @return Return 0 or 1 if an error occurred. */ -static int init_server_auto_options() +static int init_server_auto_options(bool generate_uuid = true) { + if (strlen(server_uuid) > 0) + { + sql_print_information("server_uuid exists [%s]", server_uuid ); + return 0; + } bool flush= false; char fname[FN_REFLEN]; char *name= (char *)"auto"; @@ -3643,7 +3648,7 @@ static int init_server_auto_options() } strcpy(server_uuid, uuid); } - else + else if (generate_uuid) { DBUG_PRINT("info", ("generating server_uuid")); flush= TRUE; @@ -4648,6 +4653,16 @@ int mysqld_main(int argc, char **argv) Service.SetSlowStarting(slow_start_timeout); #endif + // init server_uuid before init_server_components + if (init_server_auto_options(false)) + { + sql_print_error("Initialization of the server's UUID failed because it could" + " not be read from the auto.cnf file. If this is a new" + " server, the initialization failed because it was not" + " possible to generate a new UUID."); + unireg_abort(MYSQLD_ABORT_EXIT); + } + if (init_server_components()) unireg_abort(MYSQLD_ABORT_EXIT); @@ -4655,7 +4670,7 @@ int mysqld_main(int argc, char **argv) Each server should have one UUID. We will create it automatically, if it does not exist. */ - if (init_server_auto_options()) + if (init_server_auto_options(true)) { sql_print_error("Initialization of the server's UUID failed because it could" " not be read from the auto.cnf file. If this is a new" diff --git a/sql/replication.h b/sql/replication.h index 0a1124b..df37b4b 100644 --- a/sql/replication.h +++ b/sql/replication.h @@ -330,9 +330,15 @@ typedef struct Binlog_storage_observer { @retval 1 Failure */ int (*after_flush)(Binlog_storage_param *param, + const char *dir_path, + const char *prev_log_file, my_off_t prev_log_pos, const char *log_file, my_off_t log_pos); int (*after_sync)(Binlog_storage_param *param, const char *log_file, my_off_t log_pos); + int (*before_binlog_init)(Binlog_storage_param *param, + const char *server_uuid, + PSI_file_key *key_file_binlog_index, + const char *log_bin_index ); } Binlog_storage_observer; /** diff --git a/sql/rpl_handler.cc b/sql/rpl_handler.cc index e5ea51b..036301b 100644 --- a/sql/rpl_handler.cc +++ b/sql/rpl_handler.cc @@ -561,6 +561,9 @@ int Trans_delegate::after_rollback(THD *thd, bool all) } int Binlog_storage_delegate::after_flush(THD *thd, + const char *dir_path, + const char *prev_log_file, + my_off_t prev_log_pos, const char *log_file, my_off_t log_pos) { @@ -571,7 +574,21 @@ int Binlog_storage_delegate::after_flush(THD *thd, param.server_id= thd->server_id; int ret= 0; - FOREACH_OBSERVER(ret, after_flush, thd, (¶m, log_file, log_pos)); + FOREACH_OBSERVER(ret, after_flush, thd, (¶m, dir_path, prev_log_file, prev_log_pos, log_file, log_pos)); + DBUG_RETURN(ret); +} + +int Binlog_storage_delegate::before_binlog_init(THD *thd, + const char *server_uuid, + PSI_file_key *key_file_binlog_index, + const char *log_bin_index) +{ + DBUG_ENTER("Binlog_storage_delegate::before_binlog_init"); + Binlog_storage_param param; + param.server_id= thd ? thd->server_id : 0; + + int ret= 0; + FOREACH_OBSERVER(ret, before_binlog_init, thd, (¶m, server_uuid, key_file_binlog_index, log_bin_index)); DBUG_RETURN(ret); } diff --git a/sql/rpl_handler.h b/sql/rpl_handler.h index 97921e8..ddd57fd 100644 --- a/sql/rpl_handler.h +++ b/sql/rpl_handler.h @@ -235,10 +235,17 @@ public: {} typedef Binlog_storage_observer Observer; - int after_flush(THD *thd, const char *log_file, + int after_flush(THD *thd, + const char *dir_path, + const char *prev_log_file, + my_off_t prev_log_pos, + const char *log_file, my_off_t log_pos); int after_sync(THD *thd, const char *log_file, my_off_t log_pos); + int before_binlog_init(THD *thd, const char *server_uuid, + PSI_file_key *key_file_binlog_index, + const char *log_bin_index); }; #ifdef HAVE_REPLICATION