GTID的变更时机

  1. mysql.gtid_executed:GTID的持久化介质,GTID模块初始化时,会读取这个表,作为gtid_executed 变量的初始值
  2. gtid_executed 变量:表示数据库执行了哪些GTID  ,This is the same as the value of the Executed_Gtid_Set column in the output of SHOW MASTER STATUS and SHOW SLAVE STATUS.
  3. gtid_purged变量:包含了mysql执行过的且没有在binlog文件存在的事务。gtid_purgedgtid_executed的一个子集。

 The set of GTIDs in the gtid_purged system variable contains the GTIDs of all the transactions that have been committed on the server, but do not exist in any binary log file on the server. gtid_purged is a subset of gtid_executed.

gtid_purged写入的策略:

  1. GTIDs of replicated transactions that were committed with binary logging disabled on the replica.  从库禁用binlog情况下,从库执行的已提交的事务时的GTID
  2. GTIDs of transactions that were written to a binary log file that has now been purged.在binlog文件在被清理时,已经写入binlog文件的GTID

  3. GTIDs that were added explicitly to the set by the statement SET @@GLOBAL.gtid_purged. 手工设置了参数

例如:An example use case for this action is when you are restoring a backup of one or more databases on a server, but you do not have the relevant binary logs containing the transactions on the server,In MySQL 5.7, you can only change the value of gtid_purged when gtid_executed (and therefore gtid_purged) is empty

我们在通过备份搭建从库时,我们需要手工设置set gtid_purged =‘’,前提是清空gtid_executed

变量gtid_executed and gtid_purged在mysql启动的时候被初始化。

 

前提是binlog打开,gtid打开的情况下讨论。

一,主库修改时机

1,mysql.gtid_executed什么时间被修改?

mysql重启或者binlog 切换时,它不是实时更新的。

相关函数(文件rpl_gtid.h):Gtid_state::save_gtids_of_last_binlog_into_table()

int save_gtids_of_last_binlog_into_table(bool on_rotation);
  /**
    Fetch gtids from gtid_executed table and store them into
    gtid_executed set.

    @retval
      0    OK
    @retval
      1    The table was not found.
    @retval
      -1   Error
  */

2,变量gtid_executed什么时间被修改?

在order commit的flush阶段生成GTID,在commit阶段才记入gtid_executed变量,是实时更新的。

源码:

void Gtid_state::update_gtids_impl_own_gtid_set(THD *thd, bool is_commit)
{
#ifdef HAVE_GTID_NEXT_LIST
  rpl_sidno prev_sidno= 0;
  Gtid_set::Gtid_iterator git(&thd->owned_gtid_set);
  Gtid g= git.get();
  while (g.sidno != 0)
  {
    if (g.sidno != prev_sidno)
      sid_locks.lock(g.sidno);
    owned_gtids.remove_gtid(g);
    git.next();
    g= git.get();
    if (is_commit)
      executed_gtids._add_gtid(g);
  }

  if (is_commit && !thd->owned_gtid_set.is_empty())
    thd->rpl_thd_ctx.session_gtids_ctx().
      notify_after_gtid_executed_update(thd);

  thd->variables.gtid_next.set_undefined();
  thd->owned_gtid.dbug_print(NULL,
                             "set owned_gtid (clear; old was gtid_set) "
                             "in update_gtids_impl");
  thd->clear_owned_gtids();
#else
  DBUG_ASSERT(0);
#endif
}

3,gtid_purged什么时间被修改的?

在清理binlog的时候进行修改,如purge或者过期时间到了,需要将丢失的GTID SETS 计入这个变量中,不是实时更新的。

对应源码函数(binlog.cc文件):MYSQL_BIN_LOGS::purge_logs

 
int MYSQL_BIN_LOG::purge_logs(const char *to_log,
                              bool included,
                              bool need_lock_index,
                              bool need_update_threads,
                              ulonglong *decrease_log_space,
                              bool auto_purge)
{...
 // Update gtid_state->lost_gtids
  if (!is_relay_log)
  {
    global_sid_lock->wrlock();
    error= init_gtid_sets(NULL,
                          const_cast<Gtid_set *>(gtid_state->get_lost_gtids()),
                          opt_master_verify_checksum,
                          false/*false=don't need lock*/,
                          NULL/*trx_parser*/, NULL/*gtid_partial_trx*/);
    global_sid_lock->unlock();
    if (error)
      goto err;
  }
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

二,从库修改时机

前提是binlog,log_state_update开启

此时mysql.gtid_executed和 gtid_purge不需要实时更新,可以通过binlog文件进行保存,修改时机也是主库一样的

 

三,其他情况下

1,reset master 

此时mysql.gtid_executed,变量gtid_executed和gtid_purge都会被清空,对应函数如下:

reset master 源码对应如下:

bool reset_master(THD* thd)
{
  bool ret= false;

  /*
    RESET MASTER command should ignore 'read-only' and 'super_read_only'
    options so that it can update 'mysql.gtid_executed' replication repository
    table.

    Please note that skip_readonly_check flag should be set even when binary log
    is not enabled, as RESET MASTER command will clear 'gtid_executed' table.
  */
...
{
    global_sid_lock->wrlock();
    ret= (gtid_state->clear(thd) != 0);   //执行gtid清理操作
    global_sid_lock->unlock();
  }
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

清理函数

int Gtid_state::clear(THD *thd)
{
  DBUG_ENTER("Gtid_state::clear()");
  int ret= 0;
  // the wrlock implies that no other thread can hold any of the mutexes
  sid_lock->assert_some_wrlock();
  lost_gtids.clear();   //清理gtid_purged
  executed_gtids.clear();   //清理gtid_executed
  gtids_only_in_table.clear();  //清理mysql.gtid_executed
  previous_gtids_logged.clear();
  /* Reset gtid_executed table. */
  if ((ret= gtid_table_persistor->reset(thd)) == 1)
  {
    /*
      Gtid table is not ready to be used, so failed to
      open it. Ignore the error.
    */
    thd->clear_error();
    ret= 0;
  }
  next_free_gno= 1;
  DBUG_RETURN(ret);
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值