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: Kristian Nielsen <knielsen@knielsen-hq.org>
This commit is contained in:
parent
a9fb480fd6
commit
b2bc6dadee
@ -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;
|
||||
|
104
sql/rpl_rli.cc
104
sql/rpl_rli.cc
@ -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 @@ private:
|
||||
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 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
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;
|
||||
|
||||
|
88
sql/slave.cc
88
sql/slave.cc
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user