Description:
I found that in mysql_binlog_send, every call to Log_event::read_log_event is protected by the global LOCK_log mutex, even we are dumping the old binlog file, this is not reasonable, it makes the TPS not so stable.
So I suggest to optimize this mutex lock, if we are not reading the current binlog file, log_lock is not required, if we are reading the flushed part of the file, log_lock is not required.
How to repeat:
N/A
Suggested fix:
in binlog.cc
/**
Call fsync() to sync the file to disk.
*/
std::pair<bool, bool>
MYSQL_BIN_LOG::sync_binlog_file(bool force)
{
bool synced= false;
unsigned int sync_period= get_sync_period();
if (srv_flush_log_at_trx_commit == 3) sync_period = 0;
if (force || (sync_period && ++sync_counter >= sync_period))
{
sync_counter= 0;
if (mysql_file_sync(log_file.file, MYF(MY_WME)))
return std::make_pair(true, synced);
if (is_relay_log == 0)
{
// remember the log file index & log file length
......
}
synced= true;
}
return std::make_pair(false, synced);
}
in rpl_master.cc
if (pos > BIN_LOG_HEADER_SIZE)
{
/* reset transmit packet for the event read from binary log
file */
if (reset_transmit_packet(thd, flags, &ev_offset, &errmsg,
observe_transmission))
GOTO_ERR;
/*
Try to find a Format_description_log_event at the beginning of
the binlog
*/
if (!(error = Log_event::read_log_event(&log, packet, (is behind the last position ? NULL : log_lock), 0)))
{
DBUG_PRINT("info", ("read_log_event returned 0 on line %d", __LINE__));
/*
The packet has offsets equal to the normal offsets in a
binlog event + ev_offset (the first ev_offset characters are
the header (default \0)).
*/
while (!net->error && net->vio != 0 && !thd->killed)
{
Log_event_type event_type= UNKNOWN_EVENT;
bool goto_next_binlog= false;
/* reset the transmit packet for the event read from binary log
file */
if (reset_transmit_packet(thd, flags, &ev_offset, &errmsg,
observe_transmission))
GOTO_ERR;
DBUG_EXECUTE_IF("semi_sync_3-way_deadlock",
{
const char act[]= "now wait_for signal.rotate_finished no_clear_event";
DBUG_ASSERT(!debug_sync_set_action(current_thd,
STRING_WITH_LEN(act)));
};);
bool is_active_binlog= false;
while (!(error= Log_event::read_log_event(&log, packet, (is behind the last position ? NULL : log_lock),
current_checksum_alg,
log_file_name,
&is_active_binlog)))
{
DBUG_PRINT("info", ("read_log_event returned 0 on line %d", __LINE__));
#ifndef DBUG_OFF
if (max_binlog_dump_events && !left_events--)
{
net_flush(net);
errmsg = "Debugging binlog dump abort";
my_errno= ER_UNKNOWN_ERROR;
GOTO_ERR;
}
#endif