Skip to content
Permalink
Browse files
Changed from using LOCK_log to LOCK_binlog_end_pos for binary log
Part of MDEV-13073 AliSQL Optimize performance of semisync

The idea it to use a dedicated lock detecting if there is new data in
the master's binary log instead of the overused LOCK_log.

Changes:
- Use dedicated COND variables for the relay and binary log signaling.
  This was needed as we where the old 'update_cond' variable was used
  with different mutex's, which could cause deadlocks.
   - Relay log uses now COND_relay_log_updated and LOCK_log
   - Binary log uses now COND_bin_log_updated and LOCK_binlog_end_pos
- Renamed signal_cnt to relay_signal_cnt (as we now have two signals)
- Added some missing error handling in MYSQL_BIN_LOG::new_file_impl()
- Reformatted some comments with old style
- Renamed m_key_LOCK_binlog_end_pos to key_LOCK_binlog_end_pos
- Changed 'signal_update()' to update_binlog_end_pos() which works for
  both relay and binary log
  • Loading branch information
montywi committed Dec 18, 2017
1 parent ea37c12 commit 13770ed
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 83 deletions.
@@ -62,7 +62,9 @@ where event_name like "%MYSQL_BIN_LOG%"
and event_name not like "%MYSQL_BIN_LOG::COND_xid_list"
order by event_name;
EVENT_NAME COUNT_STAR
wait/synch/cond/sql/MYSQL_BIN_LOG::COND_bin_log_updated MANY
wait/synch/cond/sql/MYSQL_BIN_LOG::COND_queue_busy NONE
wait/synch/cond/sql/MYSQL_BIN_LOG::COND_relay_log_updated NONE
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_binlog_background_thread MANY
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_binlog_end_pos MANY
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_index MANY
@@ -81,7 +83,9 @@ where event_name like "%MYSQL_RELAY_LOG%"
and event_name not like "%MYSQL_RELAY_LOG::update_cond"
order by event_name;
EVENT_NAME COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT
wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_bin_log_updated 0 0 0 0 0
wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_queue_busy 0 0 0 0 0
wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_relay_log_updated 0 0 0 0 0
wait/synch/mutex/sql/MYSQL_RELAY_LOG::LOCK_index 0 0 0 0 0
connection slave;
"============ Performance schema on slave ============"
@@ -142,7 +146,9 @@ where event_name like "%MYSQL_BIN_LOG%"
and event_name not like "%MYSQL_BIN_LOG::COND_xid_list"
order by event_name;
EVENT_NAME COUNT_STAR
wait/synch/cond/sql/MYSQL_BIN_LOG::COND_bin_log_updated NONE
wait/synch/cond/sql/MYSQL_BIN_LOG::COND_queue_busy NONE
wait/synch/cond/sql/MYSQL_BIN_LOG::COND_relay_log_updated NONE
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_binlog_background_thread MANY
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_binlog_end_pos MANY
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_index MANY
@@ -184,6 +190,8 @@ where event_name like "%MYSQL_RELAY_LOG%"
and event_name not like "%MYSQL_RELAY_LOG::update_cond"
order by event_name;
EVENT_NAME COUNT_STAR
wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_bin_log_updated NONE
wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_queue_busy NONE
wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_relay_log_updated MANY
wait/synch/mutex/sql/MYSQL_RELAY_LOG::LOCK_index MANY
include/stop_slave.inc
@@ -3211,7 +3211,7 @@ MYSQL_BIN_LOG::MYSQL_BIN_LOG(uint *sync_period)
group_commit_trigger_lock_wait(0),
sync_period_ptr(sync_period), sync_counter(0),
state_file_deleted(false), binlog_state_recover_done(false),
is_relay_log(0), signal_cnt(0),
is_relay_log(0), relay_signal_cnt(0),
checksum_alg_reset(BINLOG_CHECKSUM_ALG_UNDEF),
relay_log_checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF),
description_event_for_exec(0), description_event_for_queue(0),
@@ -3281,7 +3281,8 @@ void MYSQL_BIN_LOG::cleanup()
mysql_mutex_destroy(&LOCK_xid_list);
mysql_mutex_destroy(&LOCK_binlog_background_thread);
mysql_mutex_destroy(&LOCK_binlog_end_pos);
mysql_cond_destroy(&update_cond);
mysql_cond_destroy(&COND_relay_log_updated);
mysql_cond_destroy(&COND_bin_log_updated);
mysql_cond_destroy(&COND_queue_busy);
mysql_cond_destroy(&COND_xid_list);
mysql_cond_destroy(&COND_binlog_background_thread);
@@ -3316,7 +3317,8 @@ void MYSQL_BIN_LOG::init_pthread_objects()
mysql_mutex_setflags(&LOCK_index, MYF_NO_DEADLOCK_DETECTION);
mysql_mutex_init(key_BINLOG_LOCK_xid_list,
&LOCK_xid_list, MY_MUTEX_INIT_FAST);
mysql_cond_init(m_key_update_cond, &update_cond, 0);
mysql_cond_init(m_key_relay_log_update, &COND_relay_log_updated, 0);
mysql_cond_init(m_key_bin_log_update, &COND_bin_log_updated, 0);
mysql_cond_init(m_key_COND_queue_busy, &COND_queue_busy, 0);
mysql_cond_init(key_BINLOG_COND_xid_list, &COND_xid_list, 0);

@@ -3327,7 +3329,7 @@ void MYSQL_BIN_LOG::init_pthread_objects()
mysql_cond_init(key_BINLOG_COND_binlog_background_thread_end,
&COND_binlog_background_thread_end, 0);

mysql_mutex_init(m_key_LOCK_binlog_end_pos, &LOCK_binlog_end_pos,
mysql_mutex_init(key_LOCK_binlog_end_pos, &LOCK_binlog_end_pos,
MY_MUTEX_INIT_SLOW);
}

@@ -3802,6 +3804,11 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
close_purge_index_file();
#endif

/* Notify the io thread that binlog is rotated to a new file */
if (is_relay_log)
signal_relay_log_update();
else
update_binlog_end_pos();
DBUG_RETURN(0);

err:
@@ -5112,7 +5119,12 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock)
new file name in the current binary log file.
*/
if ((error= generate_new_name(new_name, name, 0)))
{
#ifdef ENABLE_AND_FIX_HANG
close_on_error= TRUE;
#endif
goto end;
}
new_name_ptr=new_name;

if (log_type == LOG_BIN)
@@ -5143,13 +5155,20 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock)
}
bytes_written += r.data_written;
}
/*
Update needs to be signalled even if there is no rotate event
log rotation should give the waiting thread a signal to
discover EOF and move on to the next log.
*/
signal_update();
}

/*
Update needs to be signalled even if there is no rotate event
log rotation should give the waiting thread a signal to
discover EOF and move on to the next log.
*/
if ((error= flush_io_cache(&log_file)))
{
close_on_error= TRUE;
goto end;
}
update_binlog_end_pos();

old_name=name;
name=0; // Don't free name
close_flag= LOG_CLOSE_TO_BE_OPENED | LOG_CLOSE_INDEX;
@@ -5231,7 +5250,6 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock)
close(LOG_CLOSE_INDEX);
sql_print_error(fatal_log_error, new_name_ptr, errno);
}

mysql_mutex_unlock(&LOCK_index);
if (need_lock)
mysql_mutex_unlock(&LOCK_log);
@@ -5280,7 +5298,7 @@ bool MYSQL_BIN_LOG::append_no_lock(Log_event* ev)
if (my_b_append_tell(&log_file) > max_size)
error= new_file_without_locking();
err:
signal_update(); // Safe as we don't call close
update_binlog_end_pos();
DBUG_RETURN(error);
}

@@ -5341,7 +5359,7 @@ bool MYSQL_BIN_LOG::write_event_buffer(uchar* buf, uint len)
err:
my_safe_afree(ebuf, len);
if (!error)
signal_update();
update_binlog_end_pos();
DBUG_RETURN(error);
}

@@ -6341,6 +6359,7 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate)
{
my_off_t offset= my_b_tell(file);
bool check_purge= false;
DBUG_ASSERT(!is_relay_log);

if (!error)
{
@@ -6366,14 +6385,13 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate)
}
else
{
/* update binlog_end_pos so it can be read by dump thread
*
* note: must be _after_ the RUN_HOOK(after_flush) or else
* semi-sync-plugin might not have put the transaction into
* it's list before dump-thread tries to send it
*/
/*
update binlog_end_pos so it can be read by dump thread
note: must be _after_ the RUN_HOOK(after_flush) or else
semi-sync might not have put the transaction into
it's list before dump-thread tries to send it
*/
update_binlog_end_pos(offset);

if ((error= rotate(false, &check_purge)))
check_purge= false;
}
@@ -7099,7 +7117,7 @@ bool MYSQL_BIN_LOG::write_incident(THD *thd)
if (!(error= write_incident_already_locked(thd)) &&
!(error= flush_and_sync(0)))
{
signal_update();
update_binlog_end_pos();
if ((error= rotate(false, &check_purge)))
check_purge= false;
}
@@ -7140,7 +7158,7 @@ MYSQL_BIN_LOG::write_binlog_checkpoint_event_already_locked(const char *name_arg
*/
if (!write_event(&ev) && !flush_and_sync(0))
{
signal_update();
update_binlog_end_pos();
}
else
{
@@ -7839,12 +7857,12 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
first= false;
}

/* update binlog_end_pos so it can be read by dump thread
*
* note: must be _after_ the RUN_HOOK(after_flush) or else
* semi-sync-plugin might not have put the transaction into
* it's list before dump-thread tries to send it
*/
/*
update binlog_end_pos so it can be read by dump thread
Note: must be _after_ the RUN_HOOK(after_flush) or else
semi-sync might not have put the transaction into
it's list before dump-thread tries to send it
*/
update_binlog_end_pos(commit_offset);

if (any_error)
@@ -8228,10 +8246,10 @@ void MYSQL_BIN_LOG::wait_for_update_relay_log(THD* thd)
DBUG_ENTER("wait_for_update_relay_log");

mysql_mutex_assert_owner(&LOCK_log);
thd->ENTER_COND(&update_cond, &LOCK_log,
thd->ENTER_COND(&COND_relay_log_updated, &LOCK_log,
&stage_slave_has_read_all_relay_log,
&old_stage);
mysql_cond_wait(&update_cond, &LOCK_log);
mysql_cond_wait(&COND_relay_log_updated, &LOCK_log);
thd->EXIT_COND(&old_stage);
DBUG_VOID_RETURN;
}
@@ -8252,6 +8270,24 @@ void MYSQL_BIN_LOG::wait_for_update_relay_log(THD* thd)
LOCK_log is released by the caller.
*/

int MYSQL_BIN_LOG::wait_for_update_bin_log(THD* thd,
const struct timespec *timeout)
{
int ret= 0;
DBUG_ENTER("wait_for_update_bin_log");

thd_wait_begin(thd, THD_WAIT_BINLOG);
mysql_mutex_assert_owner(&LOCK_binlog_end_pos);
if (!timeout)
mysql_cond_wait(&COND_bin_log_updated, &LOCK_binlog_end_pos);
else
ret= mysql_cond_timedwait(&COND_bin_log_updated, &LOCK_binlog_end_pos,
const_cast<struct timespec *>(timeout));
thd_wait_end(thd);
DBUG_RETURN(ret);
}


int MYSQL_BIN_LOG::wait_for_update_binlog_end_pos(THD* thd,
struct timespec *timeout)
{
@@ -8261,9 +8297,9 @@ int MYSQL_BIN_LOG::wait_for_update_binlog_end_pos(THD* thd,
thd_wait_begin(thd, THD_WAIT_BINLOG);
mysql_mutex_assert_owner(get_binlog_end_pos_lock());
if (!timeout)
mysql_cond_wait(&update_cond, get_binlog_end_pos_lock());
mysql_cond_wait(&COND_bin_log_updated, get_binlog_end_pos_lock());
else
ret= mysql_cond_timedwait(&update_cond, get_binlog_end_pos_lock(),
ret= mysql_cond_timedwait(&COND_bin_log_updated, get_binlog_end_pos_lock(),
timeout);
thd_wait_end(thd);
DBUG_RETURN(ret);
@@ -8308,7 +8344,8 @@ void MYSQL_BIN_LOG::close(uint exiting)
relay_log_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
write_event(&s);
bytes_written+= s.data_written;
signal_update();
flush_io_cache(&log_file);
update_binlog_end_pos();

/*
When we shut down server, write out the binlog state to a separate
@@ -8527,14 +8564,6 @@ bool flush_error_log()
return result;
}

void MYSQL_BIN_LOG::signal_update()
{
DBUG_ENTER("MYSQL_BIN_LOG::signal_update");
signal_cnt++;
mysql_cond_broadcast(&update_cond);
DBUG_VOID_RETURN;
}

#ifdef _WIN32
static void print_buffer_to_nt_eventlog(enum loglevel level, char *buff,
size_t length, size_t buffLen)

0 comments on commit 13770ed

Please sign in to comment.