Commit b2bc6dad authored by Kristian Nielsen's avatar Kristian Nielsen

MDEV-7145: Delayed replication, cleanup some code

The original MySQL patch left some refactoring todo's, possibly
because of known conflicts with other parallel development (like
info-repository feature perhaps).

This patch fixes those todos/refactorings.
Signed-off-by: default avatarKristian Nielsen <knielsen@knielsen-hq.org>
parent a9fb480f
......@@ -4400,7 +4400,7 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
}
/* Store where we are in the new file for the execution thread */
flush_relay_log_info(rli);
rli->flush();
DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_SUICIDE(););
......
......@@ -6402,7 +6402,7 @@ bool Rotate_log_event::write()
The NOTES below is a wrong comment which will disappear when 4.1 is merged.
This must only be called from the Slave SQL thread, since it calls
flush_relay_log_info().
Relay_log_info::flush().
@retval
0 ok
......@@ -6457,7 +6457,7 @@ int Rotate_log_event::do_update_pos(rpl_group_info *rgi)
(ulong) rli->group_master_log_pos));
mysql_mutex_unlock(&rli->data_lock);
rpl_global_gtid_slave_state->record_and_update_gtid(thd, rgi);
flush_relay_log_info(rli);
rli->flush();
/*
Reset thd->variables.option_bits and sql_mode etc, because this could
......@@ -8228,7 +8228,7 @@ void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
here, the master was sane.
This must only be called from the Slave SQL thread, since it calls
flush_relay_log_info().
Relay_log_info::flush().
*/
int Stop_log_event::do_update_pos(rpl_group_info *rgi)
......@@ -8248,7 +8248,7 @@ int Stop_log_event::do_update_pos(rpl_group_info *rgi)
{
rpl_global_gtid_slave_state->record_and_update_gtid(thd, rgi);
rli->inc_group_relay_log_pos(0, rgi);
flush_relay_log_info(rli);
rli->flush();
}
DBUG_RETURN(0);
}
......
......@@ -647,7 +647,7 @@ file '%s')", fname);
(ulong) mi->master_log_pos));
mi->rli.mi= mi;
if (init_relay_log_info(&mi->rli, slave_info_fname))
if (mi->rli.init(slave_info_fname))
goto err;
mi->inited = 1;
......
......@@ -110,19 +110,6 @@ Relay_log_info::~Relay_log_info()
}
/**
Wrapper around Relay_log_info::init(const char *).
@todo Remove this and replace all calls to it by calls to
Relay_log_info::init(const char *). /SVEN
*/
int init_relay_log_info(Relay_log_info* rli,
const char* info_fname)
{
return rli->init(info_fname);
}
/**
Read the relay_log.info file.
......@@ -135,7 +122,7 @@ int Relay_log_info::init(const char* info_fname)
char fname[FN_REFLEN+128];
const char* msg = 0;
int error = 0;
DBUG_ENTER("init_relay_log_info");
DBUG_ENTER("Relay_log_info::init");
if (inited) // Set if this function called
DBUG_RETURN(0);
......@@ -242,7 +229,7 @@ a file name for --relay-log-index option", opt_relaylog_index_name);
max_relay_log_size, 1, TRUE))
{
mysql_mutex_unlock(&data_lock);
sql_print_error("Failed when trying to open logs for '%s' in init_relay_log_info(). Error: %M", ln, my_errno);
sql_print_error("Failed when trying to open logs for '%s' in Relay_log_info::init(). Error: %M", ln, my_errno);
DBUG_RETURN(1);
}
}
......@@ -409,10 +396,10 @@ Failed to open the existing relay log info file '%s' (errno %d)",
/*
Now change the cache from READ to WRITE - must do this
before flush_relay_log_info
before Relay_log_info::flush()
*/
reinit_io_cache(&info_file, WRITE_CACHE,0L,0,1);
if ((error= flush_relay_log_info(this)))
if ((error= flush()))
{
msg= "Failed to flush relay log info file";
goto err;
......@@ -1108,10 +1095,10 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset,
Indeed, rli->inited==0 does not imply that they already are empty.
It could be that slave's info initialization partly succeeded :
for example if relay-log.info existed but *relay-bin*.*
have been manually removed, init_relay_log_info reads the old
relay-log.info and fills rli->master_log_*, then init_relay_log_info
have been manually removed, Relay_log_info::init() reads the old
relay-log.info and fills rli->master_log_*, then Relay_log_info::init()
checks for the existence of the relay log, this fails and
init_relay_log_info leaves rli->inited to 0.
Relay_log_info::init() leaves rli->inited to 0.
In that pathological case, rli->master_log_pos* will be properly reinited
at the next START SLAVE (as RESET SLAVE or CHANGE
MASTER, the callers of purge_relay_logs, will delete bogus *.info files
......@@ -1349,7 +1336,7 @@ void Relay_log_info::stmt_done(my_off_t event_master_log_pos, THD *thd,
}
DBUG_EXECUTE_IF("inject_crash_before_flush_rli", DBUG_SUICIDE(););
if (mi->using_gtid == Master_info::USE_GTID_NO)
flush_relay_log_info(this);
flush();
DBUG_EXECUTE_IF("inject_crash_after_flush_rli", DBUG_SUICIDE(););
}
DBUG_VOID_RETURN;
......@@ -2010,4 +1997,79 @@ bool rpl_sql_thread_info::cached_charset_compare(char *charset) const
DBUG_RETURN(0);
}
/**
Store the file and position where the slave's SQL thread are in the
relay log.
Notes:
- This function should be called either from the slave SQL thread,
or when the slave thread is not running. (It reads the
group_{relay|master}_log_{pos|name} and delay fields in the rli
object. These may only be modified by the slave SQL thread or by
a client thread when the slave SQL thread is not running.)
- If there is an active transaction, then we do not update the
position in the relay log. This is to ensure that we re-execute
statements if we die in the middle of an transaction that was
rolled back.
- As a transaction never spans binary logs, we don't have to handle
the case where we do a relay-log-rotation in the middle of the
transaction. If transactions could span several binlogs, we would
have to ensure that we do not delete the relay log file where the
transaction started before switching to a new relay log file.
- Error can happen if writing to file fails or if flushing the file
fails.
@param rli The object representing the Relay_log_info.
@todo Change the log file information to a binary format to avoid
calling longlong2str.
@return 0 on success, 1 on error.
*/
bool Relay_log_info::flush()
{
bool error=0;
DBUG_ENTER("Relay_log_info::flush()");
IO_CACHE *file = &info_file;
// 2*file name, 2*long long, 2*unsigned long, 6*'\n'
char buff[FN_REFLEN * 2 + 22 * 2 + 10 * 2 + 6], *pos;
my_b_seek(file, 0L);
pos= longlong10_to_str(LINES_IN_RELAY_LOG_INFO_WITH_DELAY, buff, 10);
*pos++='\n';
pos=strmov(pos, group_relay_log_name);
*pos++='\n';
pos=longlong10_to_str(group_relay_log_pos, pos, 10);
*pos++='\n';
pos=strmov(pos, group_master_log_name);
*pos++='\n';
pos=longlong10_to_str(group_master_log_pos, pos, 10);
*pos++='\n';
pos= longlong10_to_str(sql_delay, pos, 10);
*pos++= '\n';
if (my_b_write(file, (uchar*) buff, (size_t) (pos-buff)))
error=1;
if (flush_io_cache(file))
error=1;
if (sync_relayloginfo_period &&
!error &&
++sync_counter >= sync_relayloginfo_period)
{
if (my_sync(info_fd, MYF(MY_WME)))
error=1;
sync_counter= 0;
}
/*
Flushing the relay log is done by the slave I/O thread
or by the user on STOP SLAVE.
*/
DBUG_RETURN(error);
}
#endif
......@@ -42,7 +42,7 @@ class Rpl_filter;
Relay_log_info is initialized from the slave.info file if such
exists. Otherwise, data members are intialized with defaults. The
initialization is done with init_relay_log_info() call.
initialization is done with Relay_log_info::init() call.
The format of slave.info file:
......@@ -536,7 +536,7 @@ class Relay_log_info : public Slave_reporting_capability
MASTER_DELAY=X. Read by SQL thread and by client threads
executing SHOW SLAVE STATUS. Note: must not be written while the
slave SQL thread is running, since the SQL thread reads it without
a lock when executing flush_relay_log_info().
a lock when executing Relay_log_info::flush().
*/
int sql_delay;
......@@ -954,17 +954,6 @@ class rpl_sql_thread_info
};
/**
Reads the relay_log.info file.
@todo This is a wrapper around Relay_log_info::init(). It's only
kept for historical reasons. It would be good if we removed this
function and replaced all calls to it by calls to
Relay_log_info::init(). /SVEN
*/
int init_relay_log_info(Relay_log_info* rli, const char* info_fname);
extern struct rpl_slave_state *rpl_global_gtid_slave_state;
extern gtid_waiting rpl_global_gtid_waiting;
......
......@@ -738,7 +738,7 @@ int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock)
DBUG_PRINT("info",("Flushing relay-log info file."));
if (current_thd)
THD_STAGE_INFO(current_thd, stage_flushing_relay_log_info_file);
if (flush_relay_log_info(&mi->rli))
if (mi->rli.flush())
DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
if (my_sync(mi->rli.info_fd, MYF(MY_WME)))
......@@ -5124,7 +5124,7 @@ pthread_handler_t handle_slave_sql(void *arg)
{
ulong domain_count;
flush_relay_log_info(rli);
rli->flush();
if (mi->using_parallel())
{
/*
......@@ -6708,88 +6708,6 @@ MYSQL *rpl_connect_master(MYSQL *mysql)
}
#endif
/**
Store the file and position where the slave's SQL thread are in the
relay log.
Notes:
- This function should be called either from the slave SQL thread,
or when the slave thread is not running. (It reads the
group_{relay|master}_log_{pos|name} and delay fields in the rli
object. These may only be modified by the slave SQL thread or by
a client thread when the slave SQL thread is not running.)
- If there is an active transaction, then we do not update the
position in the relay log. This is to ensure that we re-execute
statements if we die in the middle of an transaction that was
rolled back.
- As a transaction never spans binary logs, we don't have to handle
the case where we do a relay-log-rotation in the middle of the
transaction. If transactions could span several binlogs, we would
have to ensure that we do not delete the relay log file where the
transaction started before switching to a new relay log file.
- Error can happen if writing to file fails or if flushing the file
fails.
@param rli The object representing the Relay_log_info.
@todo Change the log file information to a binary format to avoid
calling longlong2str.
@todo Move the member function into rpl_rli.cc and get rid of the
global function. /SVEN
@return 0 on success, 1 on error.
*/
bool flush_relay_log_info(Relay_log_info* rli)
{
return rli->flush();
}
bool Relay_log_info::flush()
{
bool error=0;
DBUG_ENTER("Relay_log_info::flush()");
IO_CACHE *file = &info_file;
// 2*file name, 2*long long, 2*unsigned long, 6*'\n'
char buff[FN_REFLEN * 2 + 22 * 2 + 10 * 2 + 6], *pos;
my_b_seek(file, 0L);
pos= longlong10_to_str(LINES_IN_RELAY_LOG_INFO_WITH_DELAY, buff, 10);
*pos++='\n';
pos=strmov(pos, group_relay_log_name);
*pos++='\n';
pos=longlong10_to_str(group_relay_log_pos, pos, 10);
*pos++='\n';
pos=strmov(pos, group_master_log_name);
*pos++='\n';
pos=longlong10_to_str(group_master_log_pos, pos, 10);
*pos++='\n';
pos= longlong10_to_str(sql_delay, pos, 10);
*pos++= '\n';
if (my_b_write(file, (uchar*) buff, (size_t) (pos-buff)))
error=1;
if (flush_io_cache(file))
error=1;
if (sync_relayloginfo_period &&
!error &&
++sync_counter >= sync_relayloginfo_period)
{
if (my_sync(info_fd, MYF(MY_WME)))
error=1;
sync_counter= 0;
}
/*
Flushing the relay log is done by the slave I/O thread
or by the user on STOP SLAVE.
*/
DBUG_RETURN(error);
}
/*
Called when we notice that the current "hot" log got rotated under our feet.
......@@ -7146,7 +7064,7 @@ static Log_event* next_event(rpl_group_info *rgi, ulonglong *event_size)
}
rli->event_relay_log_pos = BIN_LOG_HEADER_SIZE;
strmake_buf(rli->event_relay_log_name,rli->linfo.log_file_name);
flush_relay_log_info(rli);
rli->flush();
}
/*
......
......@@ -183,7 +183,6 @@ extern const char *relay_log_basename;
int init_slave();
int init_recovery(Master_info* mi, const char** errmsg);
void init_slave_skip_errors(const char* arg);
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);
......
......@@ -100,7 +100,7 @@ static int check_event_type(int type, Relay_log_info *rli)
/*
It is not meaningful to execute other events than row-events and
FD events. It would even be dangerous to execute Stop_log_event
and Rotate_log_event since they call flush_relay_log_info, which
and Rotate_log_event since they call Relay_log_info::flush(), which
is not allowed to call by other threads than the slave SQL
thread when the slave SQL thread is running.
*/
......
......@@ -494,7 +494,7 @@ static enum enum_binlog_checksum_alg get_binlog_checksum_value_at_connect(THD *
TODO
- Inform the slave threads that they should sync the position
in the binary log file with flush_relay_log_info.
in the binary log file with Relay_log_info::flush().
Now they sync is done for next read.
*/
......@@ -3818,7 +3818,7 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added)
in-memory value at restart (thus causing errors, as the old relay log does
not exist anymore).
*/
flush_relay_log_info(&mi->rli);
mi->rli.flush();
mysql_cond_broadcast(&mi->data_cond);
mysql_mutex_unlock(&mi->rli.data_lock);
......
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