Bug #73903 Optimize the log_lock mutex for mysql_binlog_send call

Submitted: 12 Sep 2014 8:34 Modified: 30 Oct 2014 23:55
Reporter: Fangxin Flou (OCA) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Cluster: Replication Severity:S5 (Performance)
Version:All OS:Any
Assigned to: CPU Architecture:Any
Tags: binlog

[12 Sep 2014 8:34] Fangxin Flou
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
[14 Sep 2014 15:08] zhai weixiang
LOCK_log is removed completely from dump thread in MySQL 5.7
[30 Oct 2014 23:55] Fangxin Flou
LOCK_log is removed completely from dump thread in MySQL 5.7

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.040 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.