Replication进阶(八) 半同步复制状态切换

半同步复制状态切换

一、简介

假设当前m-s处于半同步复制状态,这个状态在某些情况下可能会发生切换。

通过status而不是variables去查看当前复制状态

mysql> show global status like 'Rpl_semi_sync_master_status';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | ON    |
+-----------------------------+-------+
1 row in set (0.00 sec)

如果是ON则为半同步状态,如果是OFF,则是异步复制状态。

二、状态切换

状态切换可能是半同步切换到异步,异步切换到半同步两种。

半同步切换异步状态

如简介中所述,如果当前运行在半同步复制状态,在如下情况下会发生切换

  • 等待ack超时,被动切换

事务提交阶段需要等待slave返回的ack信息,并且通过rpl_semi_sync_master_wait_for_slave_count 设置ack slave的数量,通过rpl_semi_sync_master_timeout控制ack超时时间,当master无法在rpl_semi_sync_master_timeout时间内读取到ack信息时,则会触发半同步切换到异步的过程。这部分的代码见如下

  if (wait_result != 0)
      {
        /* This is a real wait timeout. */
        sql_print_warning("Timeout waiting for reply of binlog (file: %s, pos: %lu), "
                          "semi-sync up to file %s, position %lu.",
                          trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos,
                          reply_file_name_, (unsigned long)reply_file_pos_);
        rpl_semi_sync_master_wait_timeouts++;
        
        /* switch semi-sync off */
        switch_off();
      }
int ReplSemiSyncMaster::switch_off()
{
  const char *kWho = "ReplSemiSyncMaster::switch_off";

  function_enter(kWho);
  state_ = false;

  rpl_semi_sync_master_off_times++;
  wait_file_name_inited_   = false;
  reply_file_name_inited_  = false;
  sql_print_information("Semi-sync replication switched OFF.");

  /* signal waiting sessions */
  active_tranxs_->signal_waiting_sessions_all();

  return function_exit(kWho, 0);
}
  • 通过设置参数,主动切换

通过设置变量rpl_semi_sync_master_enabled可以手动控制状态切换

在简介中,假设当前M-S运行在半同步复制状态,可以通过如下设置进行切换

mysql> set global rpl_semi_sync_master_enabled=off;
Query OK, 0 rows affected (0.02 sec)

代码控制在

参数设置的接口

static MYSQL_SYSVAR_BOOL(enabled, rpl_semi_sync_master_enabled,
  PLUGIN_VAR_OPCMDARG,
 "Enable semi-synchronous replication master (disabled by default). ",
  NULL, 			// check
  &fix_rpl_semi_sync_master_enabled,	// update
  0);

修改半同步复制状态

static void fix_rpl_semi_sync_master_enabled(MYSQL_THD thd,
				      SYS_VAR *var,
				      void *ptr,
				      const void *val)
{
  *(char *)ptr= *(char *)val;
  if (rpl_semi_sync_master_enabled)
  {
    if (repl_semisync.enableMaster() != 0)
      rpl_semi_sync_master_enabled = false;
    else if (ack_receiver.start())
    {
      repl_semisync.disableMaster();
      rpl_semi_sync_master_enabled = false;
    }
  }
  else
  {
    if (repl_semisync.disableMaster() != 0)
      rpl_semi_sync_master_enabled = true;
    ack_receiver.stop();
  }

  return;
}

从on->off

int ReplSemiSyncMaster::disableMaster()
{
  /* Must have the lock when we do enable of disable. */
  lock();

  if (getMasterEnabled())
  {
    /* Switch off the semi-sync first so that waiting transaction will be
     * waken up.
     */
    switch_off();

    if ( active_tranxs_ && active_tranxs_->is_empty())
    {
      delete active_tranxs_;
      active_tranxs_ = NULL;
    }

    reply_file_name_inited_ = false;
    wait_file_name_inited_  = false;
    commit_file_name_inited_ = false;

    ack_container_.clear();

    set_master_enabled(false);
    sql_print_information("Semi-sync replication disabled on the master.");
  }

  unlock();

  return 0;
}

异步切换到半同步

如果初始状态为半同步,由于其他原因,被迫切换到异步复制,那么在某些条件下,可以自动从异步状态切换到半同步状态。

  • master-slave网络恢复,master可以正常的接受ack信息。
void ReplSemiSyncMaster::reportReplyBinlog(const char *log_file_name,
                                           my_off_t log_file_pos)
{
  const char *kWho = "ReplSemiSyncMaster::reportReplyBinlog";
  int   cmp;
  bool  can_release_threads = false;
  bool  need_copy_send_pos = true;

  function_enter(kWho);
  mysql_mutex_assert_owner(&LOCK_binlog_);

  if (!getMasterEnabled())
    goto l_end;

  if (!is_on())
    /* We check to see whether we can switch semi-sync ON. */
    try_switch_on(log_file_name, log_file_pos);

从代码中可以看出,如果参数rpl_semi_sync_master_enabled设置为on,并且当前状态不为on,则会尝试进行切换到半同步。

  • 如果m-s一开始就运行在异步环境,则可以通过参数设置切换到半同步状态

mysql> set global rpl_semi_sync_master_enabled=on;
Query OK, 0 rows affected (0.01 sec)

这个就没什么好说的了,常规操作。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值