From 872a953b228e93553ed056d8fa035ff06e884bc8 Mon Sep 17 00:00:00 2001 From: Monty Date: Wed, 15 Jul 2015 16:27:14 +0300 Subject: MDEV-8469 Add RESET MASTER TO x to allow specification of binlog file nr Other things: - Avoid calling init_and_set_log_file_name() when opening binary log. - Remove newlines early when reading from index file. - Ensure that reset_logs() will work even if thd is 0 (Can happen on startup) - Added thd to sart_slave_threads() for better error handling. --- mysql-test/r/create_drop_binlog.result | 12 +++ mysql-test/t/create_drop_binlog.test | 9 ++ sql/log.cc | 166 ++++++++++++++++++++------------- sql/log.h | 17 ++-- sql/mysqld.cc | 2 +- sql/rpl_mi.cc | 18 ++-- sql/rpl_rli.cc | 7 +- sql/slave.cc | 8 +- sql/slave.h | 3 +- sql/sql_lex.h | 1 + sql/sql_reload.cc | 2 +- sql/sql_repl.cc | 9 +- sql/sql_repl.h | 3 +- sql/sql_yacc.yy | 15 ++- sql/sys_vars.cc | 2 +- sql/wsrep_mysqld.cc | 13 +-- 16 files changed, 187 insertions(+), 100 deletions(-) diff --git a/mysql-test/r/create_drop_binlog.result b/mysql-test/r/create_drop_binlog.result index a1108890208..4a6fa7a8d14 100644 --- a/mysql-test/r/create_drop_binlog.result +++ b/mysql-test/r/create_drop_binlog.result @@ -333,3 +333,15 @@ Log_name Pos Event_type Server_id End_log_pos Info # # Gtid 1 # GTID #-#-# # # Query 1 # use `test`; DROP TABLE `t1` /* generated by server */ RESET MASTER; +RESET MASTER; +SHOW MASTER STATUS; +File Position Binlog_Do_DB Binlog_Ignore_DB +master-bin.000001 313 +RESET MASTER TO 100; +SHOW MASTER STATUS; +File Position Binlog_Do_DB Binlog_Ignore_DB +master-bin.000100 313 +RESET MASTER; +SHOW MASTER STATUS; +File Position Binlog_Do_DB Binlog_Ignore_DB +master-bin.000001 313 diff --git a/mysql-test/t/create_drop_binlog.test b/mysql-test/t/create_drop_binlog.test index 775c7bec12a..06fd1c6c1dd 100644 --- a/mysql-test/t/create_drop_binlog.test +++ b/mysql-test/t/create_drop_binlog.test @@ -160,3 +160,12 @@ DROP TABLE t1; --replace_regex /xid=[0-9]+/xid=XX/ /GTID [0-9]+-[0-9]+-[0-9]+/GTID #-#-#/ /Server.ver.*/VER/ SHOW BINLOG EVENTS; RESET MASTER; + +# Test RESET MASTER TO + +RESET MASTER; +SHOW MASTER STATUS; +RESET MASTER TO 100; +SHOW MASTER STATUS; +RESET MASTER; +SHOW MASTER STATUS; diff --git a/sql/log.cc b/sql/log.cc index 8550a43a9ac..42ba24d1acd 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -299,11 +299,12 @@ public: incident= FALSE; before_stmt_pos= MY_OFF_T_UNDEF; /* - The truncate function calls reinit_io_cache that calls my_b_flush_io_cache - which may increase disk_writes. This breaks the disk_writes use by the - binary log which aims to compute the ratio between in-memory cache usage - and disk cache usage. To avoid this undesirable behavior, we reset the - variable after truncating the cache. + The truncate function calls reinit_io_cache that calls + my_b_flush_io_cache which may increase disk_writes. This breaks + the disk_writes use by the binary log which aims to compute the + ratio between in-memory cache usage and disk cache usage. To + avoid this undesirable behavior, we reset the variable after + truncating the cache. */ cache_log.disk_writes= 0; DBUG_ASSERT(empty()); @@ -2407,13 +2408,13 @@ static void setup_windows_event_source() nonzero if not possible to get unique filename. */ -static int find_uniq_filename(char *name) +static int find_uniq_filename(char *name, ulong next_log_number) { uint i; char buff[FN_REFLEN], ext_buf[FN_REFLEN]; struct st_my_dir *dir_info; reg1 struct fileinfo *file_info; - ulong max_found= 0, next= 0, number= 0; + ulong max_found, next, number; size_t buf_length, length; char *start, *end; int error= 0; @@ -2433,6 +2434,7 @@ static int find_uniq_filename(char *name) DBUG_RETURN(1); } file_info= dir_info->dir_entry; + max_found= next_log_number ? next_log_number-1 : 0; for (i= dir_info->number_of_files ; i-- ; file_info++) { if (strncmp(file_info->name, start, length) == 0 && @@ -2444,7 +2446,7 @@ static int find_uniq_filename(char *name) my_dirend(dir_info); /* check if reached the maximum possible extension number */ - if (max_found == MAX_LOG_UNIQUE_FN_EXT) + if (max_found >= MAX_LOG_UNIQUE_FN_EXT) { sql_print_error("Log filename extension number exhausted: %06lu. \ Please fix this by archiving old logs and \ @@ -2505,14 +2507,18 @@ void MYSQL_LOG::init(enum_log_type log_type_arg, bool MYSQL_LOG::init_and_set_log_file_name(const char *log_name, const char *new_name, + ulong next_log_number, enum_log_type log_type_arg, enum cache_type io_cache_type_arg) { init(log_type_arg, io_cache_type_arg); - if (new_name && !strmov(log_file_name, new_name)) - return TRUE; - else if (!new_name && generate_new_name(log_file_name, log_name)) + if (new_name) + { + strmov(log_file_name, new_name); + } + else if (!new_name && generate_new_name(log_file_name, log_name, + next_log_number)) return TRUE; return FALSE; @@ -2545,7 +2551,8 @@ bool MYSQL_LOG::open( PSI_file_key log_file_key, #endif const char *log_name, enum_log_type log_type_arg, - const char *new_name, enum cache_type io_cache_type_arg) + const char *new_name, ulong next_log_number, + enum cache_type io_cache_type_arg) { char buff[FN_REFLEN]; MY_STAT f_stat; @@ -2564,7 +2571,13 @@ bool MYSQL_LOG::open( goto err; } - if (init_and_set_log_file_name(name, new_name, + /* + log_type is LOG_UNKNOWN if we should not generate a new name + This is only used when called from MYSQL_BINARY_LOG::open, which + has already updated log_file_name. + */ + if (log_type_arg != LOG_UNKNOWN && + init_and_set_log_file_name(name, new_name, next_log_number, log_type_arg, io_cache_type_arg)) goto err; @@ -2719,7 +2732,8 @@ void MYSQL_LOG::cleanup() } -int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name) +int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name, + ulong next_log_number) { fn_format(new_name, log_name, mysql_data_home, "", 4); if (log_type == LOG_BIN) @@ -2727,11 +2741,12 @@ int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name) if (!fn_ext(log_name)[0]) { if (DBUG_EVALUATE_IF("binlog_inject_new_name_error", TRUE, FALSE) || - find_uniq_filename(new_name)) + find_uniq_filename(new_name, next_log_number)) { THD *thd= current_thd; if (thd) - my_printf_error(ER_NO_UNIQUE_LOGFILE, ER_THD(thd, ER_NO_UNIQUE_LOGFILE), + my_printf_error(ER_NO_UNIQUE_LOGFILE, + ER_THD(thd, ER_NO_UNIQUE_LOGFILE), MYF(ME_FATALERROR), log_name); sql_print_error(ER_DEFAULT(ER_NO_UNIQUE_LOGFILE), log_name); return 1; @@ -2779,7 +2794,7 @@ void MYSQL_QUERY_LOG::reopen_file() #ifdef HAVE_PSI_INTERFACE m_log_file_key, #endif - save_name, log_type, 0, io_cache_type); + save_name, log_type, 0, 0, io_cache_type); my_free(save_name); mysql_mutex_unlock(&LOCK_log); @@ -3088,8 +3103,8 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, first change fn_format() to cut the file name if it's too long. */ const char *MYSQL_LOG::generate_name(const char *log_name, - const char *suffix, - bool strip_ext, char *buff) + const char *suffix, + bool strip_ext, char *buff) { if (!log_name || !log_name[0]) { @@ -3313,6 +3328,7 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg, bool MYSQL_BIN_LOG::open(const char *log_name, enum_log_type log_type_arg, const char *new_name, + ulong next_log_number, enum cache_type io_cache_type_arg, ulong max_size_arg, bool null_created_arg, @@ -3320,7 +3336,6 @@ bool MYSQL_BIN_LOG::open(const char *log_name, { File file= -1; xid_count_per_binlog *new_xid_list_entry= NULL, *b; - DBUG_ENTER("MYSQL_BIN_LOG::open"); DBUG_PRINT("enter",("log_type: %d",(int) log_type_arg)); @@ -3338,8 +3353,9 @@ bool MYSQL_BIN_LOG::open(const char *log_name, DBUG_RETURN(1); } - if (init_and_set_log_file_name(log_name, new_name, log_type_arg, - io_cache_type_arg)) + /* We need to calculate new log file name for purge to delete old */ + if (init_and_set_log_file_name(log_name, new_name, next_log_number, + log_type_arg, io_cache_type_arg)) { sql_print_error("MSYQL_BIN_LOG::open failed to generate new file name."); DBUG_RETURN(1); @@ -3352,13 +3368,15 @@ bool MYSQL_BIN_LOG::open(const char *log_name, DBUG_EVALUATE_IF("fault_injection_registering_index", 1, 0)) { /** - TODO: although this was introduced to appease valgrind - when injecting emulated faults using fault_injection_registering_index - it may be good to consider what actually happens when - open_purge_index_file succeeds but register or sync fails. - - Perhaps we might need the code below in MYSQL_LOG_BIN::cleanup - for "real life" purposes as well? + TODO: + Although this was introduced to appease valgrind when + injecting emulated faults using + fault_injection_registering_index it may be good to consider + what actually happens when open_purge_index_file succeeds but + register or sync fails. + + Perhaps we might need the code below in MYSQL_LOG_BIN::cleanup + for "real life" purposes as well? */ DBUG_EXECUTE_IF("fault_injection_registering_index", { if (my_b_inited(&purge_index_file)) @@ -3381,7 +3399,9 @@ bool MYSQL_BIN_LOG::open(const char *log_name, #ifdef HAVE_PSI_INTERFACE m_key_file_log, #endif - log_name, log_type_arg, new_name, io_cache_type_arg)) + log_name, + LOG_UNKNOWN, /* Don't generate new name */ + 0, 0, io_cache_type_arg)) { #ifdef HAVE_REPLICATION close_purge_index_file(); @@ -3823,7 +3843,10 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name, error= !index_file.error ? LOG_INFO_EOF : LOG_INFO_IO; break; } - + if (fname[length-1] != '\n') + continue; // Not a log entry + fname[length-1]= 0; // Remove end \n + // extend relative paths and match against full path if (normalize_binlog_name(full_fname, fname, is_relay_log)) { @@ -3834,11 +3857,10 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name, // if the log entry matches, null string matching anything if (!log_name || - (log_name_len == fname_len-1 && full_fname[log_name_len] == '\n' && + (log_name_len == fname_len && !memcmp(full_fname, full_log_name, log_name_len))) { DBUG_PRINT("info", ("Found log file entry")); - full_fname[fname_len-1]= 0; // remove last \n linfo->index_file_start_offset= offset; linfo->index_file_offset = my_b_tell(&index_file); break; @@ -3923,8 +3945,10 @@ err: The new index file will only contain this file. - @param thd Thread - @param create_new_log 1 if we should start writing to a new log file + @param thd Thread id. This can be zero in case of resetting + relay logs + @param create_new_log 1 if we should start writing to a new log file + @param next_log_number min number of next log file to use, if possible. @note If not called from slave thread, write start event to new log @@ -3936,7 +3960,8 @@ err: */ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log, - rpl_gtid *init_state, uint32 init_state_len) + rpl_gtid *init_state, uint32 init_state_len, + ulong next_log_number) { LOG_INFO linfo; bool error=0; @@ -3969,7 +3994,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log, mysql_mutex_unlock(&LOCK_xid_list); } - DEBUG_SYNC(thd, "reset_logs_after_set_reset_master_pending"); + DEBUG_SYNC_C_IF_THD(thd, "reset_logs_after_set_reset_master_pending"); /* We need to get both locks to be sure that no one is trying to write to the index log file. @@ -4052,7 +4077,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log, { uint errcode= purge_log_get_error_code(err); sql_print_error("Failed to locate old binlog or relay log files"); - my_message(errcode, ER_THD(thd, errcode), MYF(0)); + my_message(errcode, ER_THD_OR_DEFAULT(thd, errcode), MYF(0)); error= 1; goto err; } @@ -4063,10 +4088,12 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log, { if (my_errno == ENOENT) { - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_LOG_PURGE_NO_FILE, - ER_THD(thd, ER_LOG_PURGE_NO_FILE), - linfo.log_file_name); + if (thd) + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_LOG_PURGE_NO_FILE, + ER_THD(thd, ER_LOG_PURGE_NO_FILE), + linfo.log_file_name); + sql_print_information("Failed to delete file '%s'", linfo.log_file_name); my_errno= 0; @@ -4074,13 +4101,14 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log, } else { - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_BINLOG_PURGE_FATAL_ERR, - "a problem with deleting %s; " - "consider examining correspondence " - "of your binlog index file " - "to the actual binlog files", - linfo.log_file_name); + if (thd) + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_BINLOG_PURGE_FATAL_ERR, + "a problem with deleting %s; " + "consider examining correspondence " + "of your binlog index file " + "to the actual binlog files", + linfo.log_file_name); error= 1; goto err; } @@ -4103,10 +4131,11 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log, { if (my_errno == ENOENT) { - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_LOG_PURGE_NO_FILE, - ER_THD(thd, ER_LOG_PURGE_NO_FILE), - index_file_name); + if (thd) + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_LOG_PURGE_NO_FILE, + ER_THD(thd, ER_LOG_PURGE_NO_FILE), + index_file_name); sql_print_information("Failed to delete file '%s'", index_file_name); my_errno= 0; @@ -4114,19 +4143,21 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log, } else { - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_BINLOG_PURGE_FATAL_ERR, - "a problem with deleting %s; " - "consider examining correspondence " - "of your binlog index file " - "to the actual binlog files", - index_file_name); + if (thd) + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_BINLOG_PURGE_FATAL_ERR, + "a problem with deleting %s; " + "consider examining correspondence " + "of your binlog index file " + "to the actual binlog files", + index_file_name); error= 1; goto err; } } if (create_new_log && !open_index_file(index_file_name, 0, FALSE)) - if ((error= open(save_name, log_type, 0, io_cache_type, max_size, 0, FALSE))) + if ((error= open(save_name, log_type, 0, next_log_number, + io_cache_type, max_size, 0, FALSE))) goto err; my_free((void *) save_name); @@ -4947,7 +4978,7 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock) We have to do this here and not in open as we want to store the new file name in the current binary log file. */ - if ((error= generate_new_name(new_name, name))) + if ((error= generate_new_name(new_name, name, 0))) goto end; new_name_ptr=new_name; @@ -5009,14 +5040,15 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock) binlog_checksum_options= checksum_alg_reset; } /* - Note that at this point, log_state != LOG_CLOSED (important for is_open()). + Note that at this point, log_state != LOG_CLOSED + (important for is_open()). */ /* new_file() is only used for rotation (in FLUSH LOGS or because size > max_binlog_size or max_relay_log_size). - If this is a binary log, the Format_description_log_event at the beginning of - the new file should have created=0 (to distinguish with the + If this is a binary log, the Format_description_log_event at the + beginning of the new file should have created=0 (to distinguish with the Format_description_log_event written at server startup, which should trigger temp tables deletion on slaves. */ @@ -5028,7 +5060,7 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock) { /* reopen the binary log file. */ file_to_open= new_name_ptr; - error= open(old_name, log_type, new_name_ptr, io_cache_type, + error= open(old_name, log_type, new_name_ptr, 0, io_cache_type, max_size, 1, FALSE); } @@ -9192,7 +9224,7 @@ int TC_LOG_BINLOG::open(const char *opt_name) if (using_heuristic_recover()) { /* generate a new binlog to mask a corrupted one */ - open(opt_name, LOG_BIN, 0, WRITE_CACHE, max_binlog_size, 0, TRUE); + open(opt_name, LOG_BIN, 0, 0, WRITE_CACHE, max_binlog_size, 0, TRUE); cleanup(); return 1; } diff --git a/sql/log.h b/sql/log.h index e097e3bacab..73faf8cfce9 100644 --- a/sql/log.h +++ b/sql/log.h @@ -313,19 +313,22 @@ public: #endif const char *log_name, enum_log_type log_type, - const char *new_name, + const char *new_name, ulong next_file_number, enum cache_type io_cache_type_arg); bool init_and_set_log_file_name(const char *log_name, const char *new_name, + ulong next_log_number, enum_log_type log_type_arg, enum cache_type io_cache_type_arg); void init(enum_log_type log_type_arg, enum cache_type io_cache_type_arg); void close(uint exiting); inline bool is_open() { return log_state != LOG_CLOSED; } - const char *generate_name(const char *log_name, const char *suffix, + const char *generate_name(const char *log_name, + const char *suffix, bool strip_ext, char *buff); - int generate_new_name(char *new_name, const char *log_name); + int generate_new_name(char *new_name, const char *log_name, + ulong next_log_number); protected: /* LOCK_log is inited by init_pthread_objects() */ mysql_mutex_t LOCK_log; @@ -366,7 +369,7 @@ public: key_file_slow_log, #endif generate_name(log_name, "-slow.log", 0, buf), - LOG_NORMAL, 0, WRITE_CACHE); + LOG_NORMAL, 0, 0, WRITE_CACHE); } bool open_query_log(const char *log_name) { @@ -376,7 +379,7 @@ public: key_file_query_log, #endif generate_name(log_name, ".log", 0, buf), - LOG_NORMAL, 0, WRITE_CACHE); + LOG_NORMAL, 0, 0, WRITE_CACHE); } private: @@ -707,6 +710,7 @@ public: bool open(const char *log_name, enum_log_type log_type, const char *new_name, + ulong next_log_number, enum cache_type io_cache_type_arg, ulong max_size, bool null_created, @@ -780,7 +784,8 @@ public: int purge_index_entry(THD *thd, ulonglong *decrease_log_space, bool need_mutex); bool reset_logs(THD* thd, bool create_new_log, - rpl_gtid *init_state, uint32 init_state_len); + rpl_gtid *init_state, uint32 init_state_len, + ulong next_log_number); void close(uint exiting); void clear_inuse_flag_when_closing(File file); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 692af10052f..5cd9d19131b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5292,7 +5292,7 @@ static int init_server_components() * but to be able to have mysql_mutex_assert_owner() in code, * we do it anyway */ mysql_mutex_lock(mysql_bin_log.get_log_lock()); - if (mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0, + if (mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0, 0, WRITE_CACHE, max_binlog_size, 0, TRUE)) unireg_abort(1); mysql_mutex_unlock(mysql_bin_log.get_log_lock()); diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index e347376762d..02104af8cd3 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -1127,12 +1127,13 @@ bool Master_info_index::init_all_master_info() if (!opt_skip_slave_start) { - if (start_slave_threads(1 /* need mutex */, - 0 /* no wait for start*/, - mi, - buf_master_info_file, - buf_relay_log_info_file, - SLAVE_IO | SLAVE_SQL)) + if (start_slave_threads(current_thd, + 1 /* need mutex */, + 0 /* no wait for start*/, + mi, + buf_master_info_file, + buf_relay_log_info_file, + SLAVE_IO | SLAVE_SQL)) { sql_print_error("Failed to create slave threads for connection '%.*s'", (int) connection_name.length, @@ -1455,7 +1456,7 @@ bool Master_info_index::start_all_slaves(THD *thd) if (error < 0) // fatal error break; } - else + else if (thd) push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_SLAVE_STARTED, ER_THD(thd, ER_SLAVE_STARTED), (int) mi->connection_name.length, @@ -1471,6 +1472,8 @@ bool Master_info_index::start_all_slaves(THD *thd) Start all slaves that was not running. + @param thread id from user + @return TRUE Error FALSE Everything ok. @@ -1481,6 +1484,7 @@ bool Master_info_index::stop_all_slaves(THD *thd) bool result= FALSE; DBUG_ENTER("warn_if_slave_running"); mysql_mutex_assert_owner(&LOCK_active_mi); + DBUG_ASSERT(thd); for (uint i= 0; i< master_info_hash.records; ++i) { diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index e70a436585c..aba568ee317 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -228,7 +228,7 @@ a file name for --relay-log-index option", opt_relaylog_index_name); but a destructor will take care of that */ if (rli->relay_log.open_index_file(buf_relaylog_index_name, ln, TRUE) || - rli->relay_log.open(ln, LOG_BIN, 0, SEQ_READ_APPEND, + rli->relay_log.open(ln, LOG_BIN, 0, 0, SEQ_READ_APPEND, mi->rli.max_relay_log_size, 1, TRUE)) { mysql_mutex_unlock(&rli->data_lock); @@ -1076,6 +1076,9 @@ void Relay_log_info::close_temporary_tables() /* purge_relay_logs() + @param rli Relay log information + @param thd thread id. May be zero during startup + NOTES Assumes to have a run lock on rli and that no slave thread are running. */ @@ -1131,7 +1134,7 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset, rli->cur_log_fd= -1; } - if (rli->relay_log.reset_logs(thd, !just_reset, NULL, 0)) + if (rli->relay_log.reset_logs(thd, !just_reset, NULL, 0, 0)) { *errmsg = "Failed during log reset"; error=1; diff --git a/sql/slave.cc b/sql/slave.cc index 78b0da2faa3..0fad20d77af 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -430,7 +430,8 @@ int init_slave() if (active_mi->host[0] && !opt_skip_slave_start) { - if (start_slave_threads(1 /* need mutex */, + if (start_slave_threads(0, /* No active thd */ + 1 /* need mutex */, 0 /* no wait for start*/, active_mi, master_info_file, @@ -887,7 +888,8 @@ int start_slave_thread( started the threads that were not previously running */ -int start_slave_threads(bool need_slave_mutex, bool wait_for_start, +int start_slave_threads(THD *thd, + bool need_slave_mutex, bool wait_for_start, Master_info* mi, const char* master_info_fname, const char* slave_info_fname, int thread_mask) { @@ -933,7 +935,7 @@ int start_slave_threads(bool need_slave_mutex, bool wait_for_start, mi->rli.group_master_log_pos); strmake(mi->master_log_name, mi->rli.group_master_log_name, sizeof(mi->master_log_name)-1); - purge_relay_logs(&mi->rli, NULL, 0, &errmsg); + purge_relay_logs(&mi->rli, thd, 0, &errmsg); mi->rli.group_master_log_pos= mi->master_log_pos; strmake(mi->rli.group_master_log_name, mi->master_log_name, sizeof(mi->rli.group_master_log_name)-1); diff --git a/sql/slave.h b/sql/slave.h index 15e320623cc..a519229fac1 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -176,7 +176,8 @@ bool flush_relay_log_info(Relay_log_info* rli); int register_slave_on_master(MYSQL* mysql); int terminate_slave_threads(Master_info* mi, int thread_mask, bool skip_lock = 0); -int start_slave_threads(bool need_slave_mutex, bool wait_for_start, +int start_slave_threads(THD *thd, + bool need_slave_mutex, bool wait_for_start, Master_info* mi, const char* master_info_fname, const char* slave_info_fname, int thread_mask); /* diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 56f9bedc980..09a3d5e2585 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -2489,6 +2489,7 @@ public: USER_RESOURCES mqh; LEX_RESET_SLAVE reset_slave_info; ulonglong type; + ulong next_binlog_file_number; /* The following is used by KILL */ killed_state kill_signal; killed_type kill_type; diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index 6fc0e0024af..e6c8e0777b8 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -334,7 +334,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options, { DBUG_ASSERT(thd); tmp_write_to_binlog= 0; - if (reset_master(thd, NULL, 0)) + if (reset_master(thd, NULL, 0, thd->lex->next_binlog_file_number)) { /* NOTE: my_error() has been already called by reset_master(). */ result= 1; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 5b748c04096..f6f444c4b60 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -3110,7 +3110,8 @@ int start_slave(THD* thd , Master_info* mi, bool net_report) ER_THD(thd, ER_UNTIL_COND_IGNORED)); if (!slave_errno) - slave_errno = start_slave_threads(0 /*no mutex */, + slave_errno = start_slave_threads(thd, + 0 /*no mutex */, 1 /* wait for start */, mi, master_info_file_tmp, @@ -3772,7 +3773,8 @@ err: @retval 0 success @retval 1 error */ -int reset_master(THD* thd, rpl_gtid *init_state, uint32 init_state_len) +int reset_master(THD* thd, rpl_gtid *init_state, uint32 init_state_len, + ulong next_log_number) { if (!mysql_bin_log.is_open()) { @@ -3782,7 +3784,8 @@ int reset_master(THD* thd, rpl_gtid *init_state, uint32 init_state_len) return 1; } - if (mysql_bin_log.reset_logs(thd, 1, init_state, init_state_len)) + if (mysql_bin_log.reset_logs(thd, 1, init_state, init_state_len, + next_log_number)) return 1; RUN_HOOK(binlog_transmit, after_reset_master, (thd, 0 /* flags */)); return 0; diff --git a/sql/sql_repl.h b/sql/sql_repl.h index a9fdce9e5e2..774e43c0a87 100644 --- a/sql/sql_repl.h +++ b/sql/sql_repl.h @@ -46,7 +46,8 @@ int stop_slave(THD* thd, Master_info* mi, bool net_report); bool change_master(THD* thd, Master_info* mi, bool *master_info_added); bool mysql_show_binlog_events(THD* thd); int reset_slave(THD *thd, Master_info* mi); -int reset_master(THD* thd, rpl_gtid *init_state, uint32 init_state_len); +int reset_master(THD* thd, rpl_gtid *init_state, uint32 init_state_len, + ulong next_log_number); bool purge_master_logs(THD* thd, const char* to_log); bool purge_master_logs_before_date(THD* thd, time_t purge_time); bool log_in_use(const char* log_name); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 55041b1e172..811ee4f97d5 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -13037,7 +13037,12 @@ reset_option: SLAVE { Lex->type|= REFRESH_SLAVE; } optional_connection_name slave_reset_options { } - | MASTER_SYM { Lex->type|= REFRESH_MASTER; } + | MASTER_SYM + { + Lex->type|= REFRESH_MASTER; + Lex->next_binlog_file_number= 0; + } + master_reset_options | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE;} ; @@ -13046,6 +13051,14 @@ slave_reset_options: | ALL { Lex->reset_slave_info.all= true; } ; +master_reset_options: + /* empty */ {} + | TO_SYM ulong_num + { + Lex->next_binlog_file_number = $2; + } + ; + purge: PURGE { diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 2cc87a6913f..0a04d20ae4b 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1715,7 +1715,7 @@ Sys_var_gtid_binlog_state::global_update(THD *thd, set_var *var) struct gtid_binlog_state_data *data= (struct gtid_binlog_state_data *)var->save_result.ptr; mysql_mutex_unlock(&LOCK_global_system_variables); - res= (0 != reset_master(thd, data->list, data->list_len)); + res= (reset_master(thd, data->list, data->list_len, 0) != 0); mysql_mutex_lock(&LOCK_global_system_variables); my_free(data->list); my_free(data); diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 9f725977d06..057a4d448ba 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -502,12 +502,13 @@ static void wsrep_synced_cb(void* app_ctx) wsrep_restart_slave_activated= FALSE; mysql_mutex_lock(&LOCK_active_mi); - if ((rcode = start_slave_threads(1 /* need mutex */, - 0 /* no wait for start*/, - active_mi, - master_info_file, - relay_log_info_file, - SLAVE_SQL))) + if ((rcode = start_slave_threads(0, + 1 /* need mutex */, + 0 /* no wait for start*/, + active_mi, + master_info_file, + relay_log_info_file, + SLAVE_SQL))) { WSREP_WARN("Failed to create slave threads: %d", rcode); } -- cgit v1.2.1