Commit 872a953b authored by Monty's avatar Monty

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.
parent df0498fd
...@@ -333,3 +333,15 @@ Log_name Pos Event_type Server_id End_log_pos Info ...@@ -333,3 +333,15 @@ Log_name Pos Event_type Server_id End_log_pos Info
# # Gtid 1 # GTID #-#-# # # Gtid 1 # GTID #-#-#
# # Query 1 # use `test`; DROP TABLE `t1` /* generated by server */ # # Query 1 # use `test`; DROP TABLE `t1` /* generated by server */
RESET MASTER; 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
...@@ -160,3 +160,12 @@ DROP TABLE t1; ...@@ -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/ --replace_regex /xid=[0-9]+/xid=XX/ /GTID [0-9]+-[0-9]+-[0-9]+/GTID #-#-#/ /Server.ver.*/VER/
SHOW BINLOG EVENTS; SHOW BINLOG EVENTS;
RESET MASTER; RESET MASTER;
# Test RESET MASTER TO
RESET MASTER;
SHOW MASTER STATUS;
RESET MASTER TO 100;
SHOW MASTER STATUS;
RESET MASTER;
SHOW MASTER STATUS;
...@@ -299,11 +299,12 @@ public: ...@@ -299,11 +299,12 @@ public:
incident= FALSE; incident= FALSE;
before_stmt_pos= MY_OFF_T_UNDEF; before_stmt_pos= MY_OFF_T_UNDEF;
/* /*
The truncate function calls reinit_io_cache that calls my_b_flush_io_cache The truncate function calls reinit_io_cache that calls
which may increase disk_writes. This breaks the disk_writes use by the my_b_flush_io_cache which may increase disk_writes. This breaks
binary log which aims to compute the ratio between in-memory cache usage the disk_writes use by the binary log which aims to compute the
and disk cache usage. To avoid this undesirable behavior, we reset the ratio between in-memory cache usage and disk cache usage. To
variable after truncating the cache. avoid this undesirable behavior, we reset the variable after
truncating the cache.
*/ */
cache_log.disk_writes= 0; cache_log.disk_writes= 0;
DBUG_ASSERT(empty()); DBUG_ASSERT(empty());
...@@ -2407,13 +2408,13 @@ static void setup_windows_event_source() ...@@ -2407,13 +2408,13 @@ static void setup_windows_event_source()
nonzero if not possible to get unique filename. 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; uint i;
char buff[FN_REFLEN], ext_buf[FN_REFLEN]; char buff[FN_REFLEN], ext_buf[FN_REFLEN];
struct st_my_dir *dir_info; struct st_my_dir *dir_info;
reg1 struct fileinfo *file_info; reg1 struct fileinfo *file_info;
ulong max_found= 0, next= 0, number= 0; ulong max_found, next, number;
size_t buf_length, length; size_t buf_length, length;
char *start, *end; char *start, *end;
int error= 0; int error= 0;
...@@ -2433,6 +2434,7 @@ static int find_uniq_filename(char *name) ...@@ -2433,6 +2434,7 @@ static int find_uniq_filename(char *name)
DBUG_RETURN(1); DBUG_RETURN(1);
} }
file_info= dir_info->dir_entry; 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++) for (i= dir_info->number_of_files ; i-- ; file_info++)
{ {
if (strncmp(file_info->name, start, length) == 0 && if (strncmp(file_info->name, start, length) == 0 &&
...@@ -2444,7 +2446,7 @@ static int find_uniq_filename(char *name) ...@@ -2444,7 +2446,7 @@ static int find_uniq_filename(char *name)
my_dirend(dir_info); my_dirend(dir_info);
/* check if reached the maximum possible extension number */ /* 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. \ sql_print_error("Log filename extension number exhausted: %06lu. \
Please fix this by archiving old logs and \ Please fix this by archiving old logs and \
...@@ -2505,14 +2507,18 @@ void MYSQL_LOG::init(enum_log_type log_type_arg, ...@@ -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, bool MYSQL_LOG::init_and_set_log_file_name(const char *log_name,
const char *new_name, const char *new_name,
ulong next_log_number,
enum_log_type log_type_arg, enum_log_type log_type_arg,
enum cache_type io_cache_type_arg) enum cache_type io_cache_type_arg)
{ {
init(log_type_arg, io_cache_type_arg); init(log_type_arg, io_cache_type_arg);
if (new_name && !strmov(log_file_name, new_name)) if (new_name)
return TRUE; {
else if (!new_name && generate_new_name(log_file_name, log_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 TRUE;
return FALSE; return FALSE;
...@@ -2545,7 +2551,8 @@ bool MYSQL_LOG::open( ...@@ -2545,7 +2551,8 @@ bool MYSQL_LOG::open(
PSI_file_key log_file_key, PSI_file_key log_file_key,
#endif #endif
const char *log_name, enum_log_type log_type_arg, 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]; char buff[FN_REFLEN];
MY_STAT f_stat; MY_STAT f_stat;
...@@ -2564,7 +2571,13 @@ bool MYSQL_LOG::open( ...@@ -2564,7 +2571,13 @@ bool MYSQL_LOG::open(
goto err; 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)) log_type_arg, io_cache_type_arg))
goto err; goto err;
...@@ -2719,7 +2732,8 @@ void MYSQL_LOG::cleanup() ...@@ -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); fn_format(new_name, log_name, mysql_data_home, "", 4);
if (log_type == LOG_BIN) if (log_type == LOG_BIN)
...@@ -2727,11 +2741,12 @@ int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name) ...@@ -2727,11 +2741,12 @@ int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
if (!fn_ext(log_name)[0]) if (!fn_ext(log_name)[0])
{ {
if (DBUG_EVALUATE_IF("binlog_inject_new_name_error", TRUE, FALSE) || 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; THD *thd= current_thd;
if (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); MYF(ME_FATALERROR), log_name);
sql_print_error(ER_DEFAULT(ER_NO_UNIQUE_LOGFILE), log_name); sql_print_error(ER_DEFAULT(ER_NO_UNIQUE_LOGFILE), log_name);
return 1; return 1;
...@@ -2779,7 +2794,7 @@ void MYSQL_QUERY_LOG::reopen_file() ...@@ -2779,7 +2794,7 @@ void MYSQL_QUERY_LOG::reopen_file()
#ifdef HAVE_PSI_INTERFACE #ifdef HAVE_PSI_INTERFACE
m_log_file_key, m_log_file_key,
#endif #endif
save_name, log_type, 0, io_cache_type); save_name, log_type, 0, 0, io_cache_type);
my_free(save_name); my_free(save_name);
mysql_mutex_unlock(&LOCK_log); mysql_mutex_unlock(&LOCK_log);
...@@ -3088,8 +3103,8 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, ...@@ -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. 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 *MYSQL_LOG::generate_name(const char *log_name,
const char *suffix, const char *suffix,
bool strip_ext, char *buff) bool strip_ext, char *buff)
{ {
if (!log_name || !log_name[0]) if (!log_name || !log_name[0])
{ {
...@@ -3313,6 +3328,7 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg, ...@@ -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, bool MYSQL_BIN_LOG::open(const char *log_name,
enum_log_type log_type_arg, enum_log_type log_type_arg,
const char *new_name, const char *new_name,
ulong next_log_number,
enum cache_type io_cache_type_arg, enum cache_type io_cache_type_arg,
ulong max_size_arg, ulong max_size_arg,
bool null_created_arg, bool null_created_arg,
...@@ -3320,7 +3336,6 @@ bool MYSQL_BIN_LOG::open(const char *log_name, ...@@ -3320,7 +3336,6 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
{ {
File file= -1; File file= -1;
xid_count_per_binlog *new_xid_list_entry= NULL, *b; xid_count_per_binlog *new_xid_list_entry= NULL, *b;
DBUG_ENTER("MYSQL_BIN_LOG::open"); DBUG_ENTER("MYSQL_BIN_LOG::open");
DBUG_PRINT("enter",("log_type: %d",(int) log_type_arg)); DBUG_PRINT("enter",("log_type: %d",(int) log_type_arg));
...@@ -3338,8 +3353,9 @@ bool MYSQL_BIN_LOG::open(const char *log_name, ...@@ -3338,8 +3353,9 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (init_and_set_log_file_name(log_name, new_name, log_type_arg, /* We need to calculate new log file name for purge to delete old */
io_cache_type_arg)) 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."); sql_print_error("MSYQL_BIN_LOG::open failed to generate new file name.");
DBUG_RETURN(1); DBUG_RETURN(1);
...@@ -3352,13 +3368,15 @@ bool MYSQL_BIN_LOG::open(const char *log_name, ...@@ -3352,13 +3368,15 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
DBUG_EVALUATE_IF("fault_injection_registering_index", 1, 0)) DBUG_EVALUATE_IF("fault_injection_registering_index", 1, 0))
{ {
/** /**
TODO: although this was introduced to appease valgrind TODO:
when injecting emulated faults using fault_injection_registering_index Although this was introduced to appease valgrind when
it may be good to consider what actually happens when injecting emulated faults using
open_purge_index_file succeeds but register or sync fails. fault_injection_registering_index it may be good to consider
what actually happens when open_purge_index_file succeeds but
Perhaps we might need the code below in MYSQL_LOG_BIN::cleanup register or sync fails.
for "real life" purposes as well?
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", { DBUG_EXECUTE_IF("fault_injection_registering_index", {
if (my_b_inited(&purge_index_file)) if (my_b_inited(&purge_index_file))
...@@ -3381,7 +3399,9 @@ bool MYSQL_BIN_LOG::open(const char *log_name, ...@@ -3381,7 +3399,9 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
#ifdef HAVE_PSI_INTERFACE #ifdef HAVE_PSI_INTERFACE
m_key_file_log, m_key_file_log,
#endif #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 #ifdef HAVE_REPLICATION
close_purge_index_file(); close_purge_index_file();
...@@ -3823,7 +3843,10 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name, ...@@ -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; error= !index_file.error ? LOG_INFO_EOF : LOG_INFO_IO;
break; 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 // extend relative paths and match against full path
if (normalize_binlog_name(full_fname, fname, is_relay_log)) 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, ...@@ -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 the log entry matches, null string matching anything
if (!log_name || 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))) !memcmp(full_fname, full_log_name, log_name_len)))
{ {
DBUG_PRINT("info", ("Found log file entry")); 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_start_offset= offset;
linfo->index_file_offset = my_b_tell(&index_file); linfo->index_file_offset = my_b_tell(&index_file);
break; break;
...@@ -3923,8 +3945,10 @@ err: ...@@ -3923,8 +3945,10 @@ err:
The new index file will only contain this file. The new index file will only contain this file.
@param thd Thread @param thd Thread id. This can be zero in case of resetting
@param create_new_log 1 if we should start writing to a new log file 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 @note
If not called from slave thread, write start event to new log If not called from slave thread, write start event to new log
...@@ -3936,7 +3960,8 @@ err: ...@@ -3936,7 +3960,8 @@ err:
*/ */
bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log, 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; LOG_INFO linfo;
bool error=0; bool error=0;
...@@ -3969,7 +3994,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log, ...@@ -3969,7 +3994,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log,
mysql_mutex_unlock(&LOCK_xid_list); 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 We need to get both locks to be sure that no one is trying to
write to the index log file. write to the index log file.
...@@ -4052,7 +4077,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log, ...@@ -4052,7 +4077,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log,
{ {
uint errcode= purge_log_get_error_code(err); uint errcode= purge_log_get_error_code(err);
sql_print_error("Failed to locate old binlog or relay log files"); 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; error= 1;
goto err; goto err;
} }
...@@ -4063,10 +4088,12 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log, ...@@ -4063,10 +4088,12 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log,
{ {
if (my_errno == ENOENT) if (my_errno == ENOENT)
{ {
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, if (thd)
ER_LOG_PURGE_NO_FILE, push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_THD(thd, ER_LOG_PURGE_NO_FILE), ER_LOG_PURGE_NO_FILE,
linfo.log_file_name); ER_THD(thd, ER_LOG_PURGE_NO_FILE),
linfo.log_file_name);
sql_print_information("Failed to delete file '%s'", sql_print_information("Failed to delete file '%s'",
linfo.log_file_name); linfo.log_file_name);
my_errno= 0; my_errno= 0;
...@@ -4074,13 +4101,14 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log, ...@@ -4074,13 +4101,14 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log,
} }
else else
{ {
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, if (thd)
ER_BINLOG_PURGE_FATAL_ERR, push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
"a problem with deleting %s; " ER_BINLOG_PURGE_FATAL_ERR,
"consider examining correspondence " "a problem with deleting %s; "
"of your binlog index file " "consider examining correspondence "
"to the actual binlog files", "of your binlog index file "
linfo.log_file_name); "to the actual binlog files",
linfo.log_file_name);
error= 1; error= 1;
goto err; goto err;
} }
...@@ -4103,10 +4131,11 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log, ...@@ -4103,10 +4131,11 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log,
{ {
if (my_errno == ENOENT) if (my_errno == ENOENT)
{ {
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, if (thd)
ER_LOG_PURGE_NO_FILE, push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_THD(thd, ER_LOG_PURGE_NO_FILE), ER_LOG_PURGE_NO_FILE,
index_file_name); ER_THD(thd, ER_LOG_PURGE_NO_FILE),
index_file_name);
sql_print_information("Failed to delete file '%s'", sql_print_information("Failed to delete file '%s'",
index_file_name); index_file_name);
my_errno= 0; my_errno= 0;
...@@ -4114,19 +4143,21 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log, ...@@ -4114,19 +4143,21 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log,
} }
else else
{ {
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, if (thd)
ER_BINLOG_PURGE_FATAL_ERR, push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
"a problem with deleting %s; " ER_BINLOG_PURGE_FATAL_ERR,
"consider examining correspondence " "a problem with deleting %s; "
"of your binlog index file " "consider examining correspondence "
"to the actual binlog files", "of your binlog index file "
index_file_name); "to the actual binlog files",
index_file_name);
error= 1; error= 1;
goto err; goto err;
} }
} }
if (create_new_log && !open_index_file(index_file_name, 0, FALSE)) 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; goto err;
my_free((void *) save_name); my_free((void *) save_name);
...@@ -4947,7 +4978,7 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock) ...@@ -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 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. 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; goto end;
new_name_ptr=new_name; new_name_ptr=new_name;
...@@ -5009,14 +5040,15 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock) ...@@ -5009,14 +5040,15 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock)
binlog_checksum_options= checksum_alg_reset; 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 > new_file() is only used for rotation (in FLUSH LOGS or because size >
max_binlog_size or max_relay_log_size). max_binlog_size or max_relay_log_size).
If this is a binary log, the Format_description_log_event at the beginning of If this is a binary log, the Format_description_log_event at the
the new file should have created=0 (to distinguish with the beginning of the new file should have created=0 (to distinguish with the
Format_description_log_event written at server startup, which should Format_description_log_event written at server startup, which should
trigger temp tables deletion on slaves. trigger temp tables deletion on slaves.
*/ */
...@@ -5028,7 +5060,7 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock) ...@@ -5028,7 +5060,7 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock)
{ {
/* reopen the binary log file. */ /* reopen the binary log file. */
file_to_open= new_name_ptr; 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); max_size, 1, FALSE);
} }
...@@ -9192,7 +9224,7 @@ int TC_LOG_BINLOG::open(const char *opt_name) ...@@ -9192,7 +9224,7 @@ int TC_LOG_BINLOG::open(const char *opt_name)
if (using_heuristic_recover()) if (using_heuristic_recover())
{ {
/* generate a new binlog to mask a corrupted one */ /* 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(); cleanup();
return 1; return 1;
} }
......
...@@ -313,19 +313,22 @@ public: ...@@ -313,19 +313,22 @@ public:
#endif #endif
const char *log_name, const char *log_name,
enum_log_type log_type, enum_log_type log_type,
const char *new_name, const char *new_name, ulong next_file_number,
enum cache_type io_cache_type_arg); enum cache_type io_cache_type_arg);
bool init_and_set_log_file_name(const char *log_name, bool init_and_set_log_file_name(const char *log_name,
const char *new_name, const char *new_name,
ulong next_log_number,
enum_log_type log_type_arg, enum_log_type log_type_arg,
enum cache_type io_cache_type_arg); enum cache_type io_cache_type_arg);
void init(enum_log_type log_type_arg, void init(enum_log_type log_type_arg,
enum cache_type io_cache_type_arg); enum cache_type io_cache_type_arg);
void close(uint exiting); void close(uint exiting);
inline bool is_open() { return log_state != LOG_CLOSED; } 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); 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: protected:
/* LOCK_log is inited by init_pthread_objects() */ /* LOCK_log is inited by init_pthread_objects() */
mysql_mutex_t LOCK_log; mysql_mutex_t LOCK_log;
...@@ -366,7 +369,7 @@ public: ...@@ -366,7 +369,7 @@ public:
key_file_slow_log, key_file_slow_log,
#endif #endif
generate_name(log_name, "-slow.log", 0, buf), 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) bool open_query_log(const char *log_name)
{ {
...@@ -376,7 +379,7 @@ public: ...@@ -376,7 +379,7 @@ public:
key_file_query_log, key_file_query_log,
#endif #endif
generate_name(log_name, ".log", 0, buf), generate_name(log_name, ".log", 0, buf),
LOG_NORMAL, 0, WRITE_CACHE); LOG_NORMAL, 0, 0, WRITE_CACHE);
} }
private: private:
...@@ -707,6 +710,7 @@ public: ...@@ -707,6 +710,7 @@ public:
bool open(const char *log_name, bool open(const char *log_name,
enum_log_type log_type, enum_log_type log_type,
const char *new_name, const char *new_name,
ulong next_log_number,
enum cache_type io_cache_type_arg, enum cache_type io_cache_type_arg,
ulong max_size, ulong max_size,
bool null_created, bool null_created,
...@@ -780,7 +784,8 @@ public: ...@@ -780,7 +784,8 @@ public:
int purge_index_entry(THD *thd, ulonglong *decrease_log_space, int purge_index_entry(THD *thd, ulonglong *decrease_log_space,
bool need_mutex); bool need_mutex);
bool reset_logs(THD* thd, bool create_new_log, 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 close(uint exiting);
void clear_inuse_flag_when_closing(File file); void clear_inuse_flag_when_closing(File file);
......
...@@ -5292,7 +5292,7 @@ static int init_server_components() ...@@ -5292,7 +5292,7 @@ static int init_server_components()
* but to be able to have mysql_mutex_assert_owner() in code, * but to be able to have mysql_mutex_assert_owner() in code,
* we do it anyway */ * we do it anyway */
mysql_mutex_lock(mysql_bin_log.get_log_lock()); 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)) WRITE_CACHE, max_binlog_size, 0, TRUE))
unireg_abort(1); unireg_abort(1);
mysql_mutex_unlock(mysql_bin_log.get_log_lock()); mysql_mutex_unlock(mysql_bin_log.get_log_lock());
......
...@@ -1127,12 +1127,13 @@ bool Master_info_index::init_all_master_info() ...@@ -1127,12 +1127,13 @@ bool Master_info_index::init_all_master_info()
if (!opt_skip_slave_start) if (!opt_skip_slave_start)
{ {
if (start_slave_threads(1 /* need mutex */, if (start_slave_threads(current_thd,
0 /* no wait for start*/, 1 /* need mutex */,
mi, 0 /* no wait for start*/,
buf_master_info_file, mi,
buf_relay_log_info_file, buf_master_info_file,
SLAVE_IO | SLAVE_SQL)) buf_relay_log_info_file,
SLAVE_IO | SLAVE_SQL))
{ {
sql_print_error("Failed to create slave threads for connection '%.*s'", sql_print_error("Failed to create slave threads for connection '%.*s'",
(int) connection_name.length, (int) connection_name.length,
...@@ -1455,7 +1456,7 @@ bool Master_info_index::start_all_slaves(THD *thd) ...@@ -1455,7 +1456,7 @@ bool Master_info_index::start_all_slaves(THD *thd)
if (error < 0) // fatal error if (error < 0) // fatal error
break; break;
} }
else else if (thd)
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_SLAVE_STARTED, ER_THD(thd, ER_SLAVE_STARTED), ER_SLAVE_STARTED, ER_THD(thd, ER_SLAVE_STARTED),
(int) mi->connection_name.length, (int) mi->connection_name.length,
...@@ -1471,6 +1472,8 @@ bool Master_info_index::start_all_slaves(THD *thd) ...@@ -1471,6 +1472,8 @@ bool Master_info_index::start_all_slaves(THD *thd)
Start all slaves that was not running. Start all slaves that was not running.
@param thread id from user
@return @return
TRUE Error TRUE Error
FALSE Everything ok. FALSE Everything ok.
...@@ -1481,6 +1484,7 @@ bool Master_info_index::stop_all_slaves(THD *thd) ...@@ -1481,6 +1484,7 @@ bool Master_info_index::stop_all_slaves(THD *thd)
bool result= FALSE; bool result= FALSE;
DBUG_ENTER("warn_if_slave_running"); DBUG_ENTER("warn_if_slave_running");
mysql_mutex_assert_owner(&LOCK_active_mi); mysql_mutex_assert_owner(&LOCK_active_mi);
DBUG_ASSERT(thd);
for (uint i= 0; i< master_info_hash.records; ++i) for (uint i= 0; i< master_info_hash.records; ++i)
{ {
......
...@@ -228,7 +228,7 @@ a file name for --relay-log-index option", opt_relaylog_index_name); ...@@ -228,7 +228,7 @@ a file name for --relay-log-index option", opt_relaylog_index_name);
but a destructor will take care of that but a destructor will take care of that
*/ */
if (rli->relay_log.open_index_file(buf_relaylog_index_name, ln, TRUE) || 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)) mi->rli.max_relay_log_size, 1, TRUE))
{ {
mysql_mutex_unlock(&rli->data_lock); mysql_mutex_unlock(&rli->data_lock);
...@@ -1076,6 +1076,9 @@ void Relay_log_info::close_temporary_tables() ...@@ -1076,6 +1076,9 @@ void Relay_log_info::close_temporary_tables()
/* /*
purge_relay_logs() purge_relay_logs()
@param rli Relay log information
@param thd thread id. May be zero during startup
NOTES NOTES
Assumes to have a run lock on rli and that no slave thread are running. 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, ...@@ -1131,7 +1134,7 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset,
rli->cur_log_fd= -1; 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"; *errmsg = "Failed during log reset";
error=1; error=1;
......
...@@ -430,7 +430,8 @@ int init_slave() ...@@ -430,7 +430,8 @@ int init_slave()
if (active_mi->host[0] && !opt_skip_slave_start) 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*/, 0 /* no wait for start*/,
active_mi, active_mi,
master_info_file, master_info_file,
...@@ -887,7 +888,8 @@ int start_slave_thread( ...@@ -887,7 +888,8 @@ int start_slave_thread(
started the threads that were not previously running 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, Master_info* mi, const char* master_info_fname,
const char* slave_info_fname, int thread_mask) const char* slave_info_fname, int thread_mask)
{ {
...@@ -933,7 +935,7 @@ int start_slave_threads(bool need_slave_mutex, bool wait_for_start, ...@@ -933,7 +935,7 @@ int start_slave_threads(bool need_slave_mutex, bool wait_for_start,
mi->rli.group_master_log_pos); mi->rli.group_master_log_pos);
strmake(mi->master_log_name, mi->rli.group_master_log_name, strmake(mi->master_log_name, mi->rli.group_master_log_name,
sizeof(mi->master_log_name)-1); 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; mi->rli.group_master_log_pos= mi->master_log_pos;
strmake(mi->rli.group_master_log_name, mi->master_log_name, strmake(mi->rli.group_master_log_name, mi->master_log_name,
sizeof(mi->rli.group_master_log_name)-1); sizeof(mi->rli.group_master_log_name)-1);
......
...@@ -176,7 +176,8 @@ bool flush_relay_log_info(Relay_log_info* rli); ...@@ -176,7 +176,8 @@ bool flush_relay_log_info(Relay_log_info* rli);
int register_slave_on_master(MYSQL* mysql); int register_slave_on_master(MYSQL* mysql);
int terminate_slave_threads(Master_info* mi, int thread_mask, int terminate_slave_threads(Master_info* mi, int thread_mask,
bool skip_lock = 0); 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, Master_info* mi, const char* master_info_fname,
const char* slave_info_fname, int thread_mask); const char* slave_info_fname, int thread_mask);
/* /*
......
...@@ -2489,6 +2489,7 @@ public: ...@@ -2489,6 +2489,7 @@ public:
USER_RESOURCES mqh; USER_RESOURCES mqh;
LEX_RESET_SLAVE reset_slave_info; LEX_RESET_SLAVE reset_slave_info;
ulonglong type; ulonglong type;
ulong next_binlog_file_number;
/* The following is used by KILL */ /* The following is used by KILL */
killed_state kill_signal; killed_state kill_signal;
killed_type kill_type; killed_type kill_type;
......
...@@ -334,7 +334,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options, ...@@ -334,7 +334,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options,
{ {
DBUG_ASSERT(thd); DBUG_ASSERT(thd);
tmp_write_to_binlog= 0; 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(). */ /* NOTE: my_error() has been already called by reset_master(). */
result= 1; result= 1;
......
...@@ -3110,7 +3110,8 @@ int start_slave(THD* thd , Master_info* mi, bool net_report) ...@@ -3110,7 +3110,8 @@ int start_slave(THD* thd , Master_info* mi, bool net_report)
ER_THD(thd, ER_UNTIL_COND_IGNORED)); ER_THD(thd, ER_UNTIL_COND_IGNORED));
if (!slave_errno) if (!slave_errno)
slave_errno = start_slave_threads(0 /*no mutex */, slave_errno = start_slave_threads(thd,
0 /*no mutex */,
1 /* wait for start */, 1 /* wait for start */,
mi, mi,
master_info_file_tmp, master_info_file_tmp,
...@@ -3772,7 +3773,8 @@ err: ...@@ -3772,7 +3773,8 @@ err:
@retval 0 success @retval 0 success
@retval 1 error @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()) if (!mysql_bin_log.is_open())
{ {
...@@ -3782,7 +3784,8 @@ int reset_master(THD* thd, rpl_gtid *init_state, uint32 init_state_len) ...@@ -3782,7 +3784,8 @@ int reset_master(THD* thd, rpl_gtid *init_state, uint32 init_state_len)
return 1; 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; return 1;
RUN_HOOK(binlog_transmit, after_reset_master, (thd, 0 /* flags */)); RUN_HOOK(binlog_transmit, after_reset_master, (thd, 0 /* flags */));
return 0; return 0;
......
...@@ -46,7 +46,8 @@ int stop_slave(THD* thd, Master_info* mi, bool net_report); ...@@ -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 change_master(THD* thd, Master_info* mi, bool *master_info_added);
bool mysql_show_binlog_events(THD* thd); bool mysql_show_binlog_events(THD* thd);
int reset_slave(THD *thd, Master_info* mi); 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(THD* thd, const char* to_log);
bool purge_master_logs_before_date(THD* thd, time_t purge_time); bool purge_master_logs_before_date(THD* thd, time_t purge_time);
bool log_in_use(const char* log_name); bool log_in_use(const char* log_name);
......
...@@ -13037,7 +13037,12 @@ reset_option: ...@@ -13037,7 +13037,12 @@ reset_option:
SLAVE { Lex->type|= REFRESH_SLAVE; } SLAVE { Lex->type|= REFRESH_SLAVE; }
optional_connection_name optional_connection_name
slave_reset_options { } 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;} | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE;}
; ;
...@@ -13046,6 +13051,14 @@ slave_reset_options: ...@@ -13046,6 +13051,14 @@ slave_reset_options:
| ALL { Lex->reset_slave_info.all= true; } | ALL { Lex->reset_slave_info.all= true; }
; ;
master_reset_options:
/* empty */ {}
| TO_SYM ulong_num
{
Lex->next_binlog_file_number = $2;
}
;
purge: purge:
PURGE PURGE
{ {
......
...@@ -1715,7 +1715,7 @@ Sys_var_gtid_binlog_state::global_update(THD *thd, set_var *var) ...@@ -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 *data=
(struct gtid_binlog_state_data *)var->save_result.ptr; (struct gtid_binlog_state_data *)var->save_result.ptr;
mysql_mutex_unlock(&LOCK_global_system_variables); 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); mysql_mutex_lock(&LOCK_global_system_variables);
my_free(data->list); my_free(data->list);
my_free(data); my_free(data);
......
...@@ -502,12 +502,13 @@ static void wsrep_synced_cb(void* app_ctx) ...@@ -502,12 +502,13 @@ static void wsrep_synced_cb(void* app_ctx)
wsrep_restart_slave_activated= FALSE; wsrep_restart_slave_activated= FALSE;
mysql_mutex_lock(&LOCK_active_mi); mysql_mutex_lock(&LOCK_active_mi);
if ((rcode = start_slave_threads(1 /* need mutex */, if ((rcode = start_slave_threads(0,
0 /* no wait for start*/, 1 /* need mutex */,
active_mi, 0 /* no wait for start*/,
master_info_file, active_mi,
relay_log_info_file, master_info_file,
SLAVE_SQL))) relay_log_info_file,
SLAVE_SQL)))
{ {
WSREP_WARN("Failed to create slave threads: %d", rcode); WSREP_WARN("Failed to create slave threads: %d", rcode);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment