Mysql 5.7 Gtid内部学习(五) mysql.gtid_executed表/gtid_executed变量/gtid_purged变量的更改时机

本节将集中讨论下面三种Gtid更新的时机,这部分相当重要,后面的故障案列会和这节有关。下面先来看一下他们的定义

  • mysql.gtid_executed表:Gtid持久化的介质,Mysql启动阶段会读取这个表来获取gtid_executed变量的值。
  • gtid_executed变量(show global variables):Mysql数据库已经执行了哪些Gtid事务,处于内存中。show slave status中的Executed_Gtid_Set也取自这里。
  • gtid_purged变量(show global variables):由于binlog文件的删除(如purge binary logfiles或者超过expire_logs_days设置)已经丢失的Gtid事务,同时在搭建备库的我们使用set global gtid_purged变量来提示Mysql哪些Gtid事务我已经执行过了。

这也是我们DBA通常能够观察到的几种Gtid,有了前文的描述我们知道其中mysql.gtid_executed表是一种Gtid持久化的介质,而gtid_executed变量和gtid_purged变量则对应
了Gtid_state中的executed_gtids和lost_gtids内存数据。他们分别表示Mysql数据库执行了哪些Gtid事务,有哪些Gtid事务由于binlog文件的删除已经丢失了。
其次我们先来达成一个共识gtid_executed变量一定是实时更新的不管主库和从库。我们的讨论分为主库,从库和通用从源码的角度进行详细讨论。并且约定都是打开Gtid的情况下。最后给出最终总结。

一、主库修改时机

(1) binlog关闭

不生成Gtid,mysql.gtid_executed表/gtid_executed变量/gtid_purged变量均不更新。

(2) binlog打开

  • mysql.gtid_executed表修改时机

在binlog发生切换(rotate)的时候保存直到上一个binlog文件执行过的全部Gtid,它不是实时更新的。
栈帧如下:

#0  Gtid_table_persistor::save (this=0x2f9f9c0, gtid_set=0x7ffff03595a0) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_persist.cc:425
#1  0x0000000001803dbe in Gtid_state::save (this=0x2ff8bb0, gtid_set=0x7ffff03595a0) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_state.cc:796
#2  0x0000000001803f62 in Gtid_state::save_gtids_of_last_binlog_into_table (this=0x2ff8bb0, on_rotation=true)
    at /root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_state.cc:835
#3  0x000000000185266d in MYSQL_BIN_LOG::new_file_impl (this=0x2dffc80, need_lock_log=false, extra_description_event=0x0)
    at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:6751
#4  0x00000000018520a7 in MYSQL_BIN_LOG::new_file_without_locking (this=0x2dffc80, extra_description_event=0x0)
    at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:6636
#5  0x0000000001853e67 in MYSQL_BIN_LOG::rotate (this=0x2dffc80, force_rotate=true, check_purge=0x7ffff0359c4b)
    at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:7292

其主要逻辑在Gtid_state::save_gtids_of_last_binlog_into_table 中我们在随后的部分讨论这个函数逻辑。

  • gtid_executed变量修改时机

如前文所述ordered_commit flush阶段生成Gtid,在commit阶段才计入gtid_executed变量,它是实时更新的。
栈帧如下:

#0  Gtid_set::_add_gtid (this=0x2ff8d38, sidno=1, gno=16) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid.h:1135
#1  0x0000000001804576 in Gtid_set::_add_gtid (this=0x2ff8d38, gtid=...) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid.h:1166
#2  0x00000000018024ba in Gtid_state::update_gtids_impl (this=0x2ff8bb0, thd=0x7fff2c000b70, is_commit=true)
    at /root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_state.cc:304
#3  0x00000000018020df in Gtid_state::update_on_commit (this=0x2ff8bb0, thd=0x7fff2c000b70) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_state.cc:148
#4  0x00000000018573d4 in MYSQL_BIN_LOG::process_commit_stage_queue (this=0x2dffc80, thd=0x7fff2c000b70, first=0x7fff2c000b70)
    at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:8646
#5  0x0000000001858b51 in MYSQL_BIN_LOG::ordered_commit (this=0x2dffc80, thd=0x7fff2c000b70, all=false, skip_commit=false)
    at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:9304

其主要逻辑在Gtid_state::update_gtids_impl中我们在随后的部分讨论这个函数逻辑。

  • gtid_purged变量修改时机

在Mysql触发的清理binlog的情况下,比如purge binary logs to或者超过参数expire_logs_days设置的天数后自动删除,需要将丢失的Gtid计入这个变量中。
栈帧如下:

#0  MYSQL_BIN_LOG::init_gtid_sets (this=0x2e00280, all_gtids=0x0, lost_gtids=0x2fcaee8, verify_checksum=false, need_lock=false, trx_parser=0x0, gtid_partial_trx=0x0, is_server_starting=false)
    at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:4333
#1  0x0000000001850b8e in MYSQL_BIN_LOG::purge_logs (this=0x2e00280, to_log=0x7fff57a74ad0 "/root/mysql5.7.14/percona-server-5.7.14-7/mysql-test/var/mysqld.1/test.000202", included=false, need_lock_index=true,
    need_update_threads=true, decrease_log_space=0x0, auto_purge=false) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:6036
#2  0x0000000001848ecf in purge_master_logs (thd=0x7fff49200dc0, to_log=0x7fff492051a8 "test.000202") at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:2815

其主要逻辑在MYSQL_BIN_LOG::purge_logs中,我们随后查看其代码片段,同时MYSQL_BIN_LOG::init_gtid_sets函数是一个及其重要的函数,主要用在:

  • Mysql启动时候初始化整个Gtid_state中的各种Gtid_set。
  • Mysql删除binlog(如purge binary logfiles或者超过expire_logs_days设置)后需要确认gtid_purged变量(及Gtid_state.lost_gtids)的值的时候。

随后我会单独一节来讲解Mysql Gtid模块的初始化还会讲解这个函数。

二、主库修改时机源码函数分析

这里就对上面提到的主要逻辑函数进行分析

  • Gtid_state::save_gtids_of_last_binlog_into_table函数逻辑
logged_gtids_last_binlog.add_interval_memory(PREALLOCATED_INTERVAL_COUNT, iv); //这里构建一个logged_gtids_last_binlog集合来保存切换后需要写入表和previous_gtids_logged的Gtid
  /*
    logged_gtids_last_binlog= executed_gtids - previous_gtids_logged -
                              gtids_only_in_table
  */
  global_sid_lock->wrlock();//
  ret= (logged_gtids_last_binlog.add_gtid_set(&executed_gtids) !=  //将当前执行过的Gtid全部加入logged_gtids_last_binlog 列如:executed_gtids start=1, end=27
        RETURN_STATUS_OK);
  if (!ret)
  {
    logged_gtids_last_binlog.remove_gtid_set(&previous_gtids_logged); //获得上一个binlog文件包含的全部Gtid,并且做一个差集 列如:previous_gtids_logged 为start=1, end=25
                                                                      //做完差集后logged_gtids_last_binlog为start=26, end=27
    logged_gtids_last_binlog.remove_gtid_set(&gtids_only_in_table);//此处主库一定为空,除非异常情况
    if (!logged_gtids_last_binlog.is_empty())
    {
      /* Prepare previous_gtids_logged for next binlog on binlog rotation */
      if (on_rotation)
        ret= previous_gtids_logged.add_gtid_set(&logged_gtids_last_binlog);//将这个start=26, end=27的Gtid集合加入到previous_gtids_logged中,这样previous_gtids_logged也完整了
      global_sid_lock->unlock();
      /* Save set of GTIDs of the last binlog into gtid_executed table */
      if (!ret)
        ret= save(&logged_gtids_last_binlog);//将这个start=26, end=27的Gtid集合写入到表mysql.gtid_executed表中
    }
  • Gtid_state::update_gtids_impl函数代码片段
while (g.sidno != 0)
    {
      if (g.sidno != prev_sidno)
        sid_locks.lock(g.sidno);
      owned_gtids.remove_gtid(g); //从owned_gtid中去掉
      git.next();
      g= git.get();
      if (is_commit)
        executed_gtids._add_gtid(g);//将这个Gtid加入到executed_gtids
    }
  • MYSQL_BIN_LOG::purge_logs函数代码片段
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*/);//这里我看到将gtid_state->lost_gtids直接传入给了init_gtid_sets
                                                                        //init_gtid_sets会做正向查找获得gtid_state->lost_gtids这个函数稍后
                                                                        //详细讨论
    global_sid_lock->unlock();
    if (error)
      goto err;
  }

三、从库修改时机

(1) binlog关闭或者binlog开启参数log_slave_updates关闭的情况

将他们放到一起因为他们的表现完全一样。

  • mysql.gtid_executed表修改时机

前面已经说过这种情况下从库没有办法通过binlog来持久化sql_thread执行过的Gtid事务,只能通过实时更新mysql.gtid_executed表来保存,所以必须要要实时将Gtid持久化到mysql.gtid_executed表中。实际上实时保存mysql.gtid_executed发生在commit的preper阶段之前,也就是最开始。但是对于主库来讲由于还没有生成Gtid,那么则不能写入
栈帧如下:

#0  commit_owned_gtids (thd=0x7fffec000970, all=false, need_clear_owned_gtid_ptr=0x7ffff08bf2cb) at /mysql/mysql-5.7.17/sql/handler.cc:1571
#1  0x0000000000f465c3 in ha_commit_trans (thd=0x7fffec000970, all=false, ignore_global_read_lock=false) at /mysql/mysql-5.7.17/sql/handler.cc:1669
#2  0x0000000001686f0d in trans_commit_stmt (thd=0x7fffec000970) at /mysql/mysql-5.7.17/sql/transaction.cc:458
#3  0x000000000180fb16 in rows_event_stmt_cleanup (rli=0x3937d30, thd=0x7fffec000970) at /mysql/mysql-5.7.17/sql/log_event.cc:11124
#4  0x000000000180f801 in Rows_log_event::do_apply_event (this=0x7fffec018020, rli=0x3937d30) at /mysql/mysql-5.7.17/sql/log_event.cc:11026
#5  0x00000000017f7b7b in Log_event::apply_event (this=0x7fffec018020, rli=0x3937d30) at /mysql/mysql-5.7.17/sql/log_event.cc:3324
#6  0x00000000018690a6 in apply_event_and_update_pos (ptr_ev=0x7ffff08bf830, thd=0x7fffec000970, rli=0x3937d30) at /mysql/mysql-5.7.17/sql/rpl_slave.cc:4702
#7  0x000000000186a75e in exec_relay_log_event (thd=0x7fffec000970, rli=0x3937d30) at /mysql/mysql-5.7.17/sql/rpl_slave.cc:5212
#8  0x0000000001870d07 in handle_slave_sql (arg=0x38cc1c0) at /mysql/mysql-5.7.17/sql/rpl_slave.cc:7320

其主要逻辑包含在commit_owned_gtids中。

  • gtid_executed变量修改时机

这个和主库一样实时更新,不做讨论。

  • gtid_purged变量修改时机

由于压根没有binlog来记录已经执行过的Gtid事务,所以gtid_purged变量实时更新
其更改处于整个ha_commit_trans的结尾如下:

if (need_clear_owned_gtid)
  {
    thd->server_status&= ~SERVER_STATUS_IN_TRANS;
    /*
      Release the owned GTID when binlog is disabled, or binlog is
      enabled and log_slave_updates is disabled with slave SQL thread
      or slave worker thread.
    */
    if (error)
      gtid_state->update_on_rollback(thd);
    else
      gtid_state->update_on_commit(thd);
  }

栈帧如下(这个栈帧取值5.7.17):

#0  Gtid_set::_add_gtid (this=0x2f9ef40, sidno=2, gno=33083) at /mysql/mysql-5.7.17/sql/rpl_gtid.h:1136
#1  0x00000000017e9990 in Gtid_set::_add_gtid (this=0x2f9ef40, gtid=...) at /mysql/mysql-5.7.17/sql/rpl_gtid.h:1167
#2  0x00000000017e906e in Gtid_state::update_gtids_impl_own_gtid (this=0x2f9eca0, thd=0x7fffec000970, is_commit=true) at /mysql/mysql-5.7.17/sql/rpl_gtid_state.cc:939
#3  0x00000000017e6f3f in Gtid_state::update_gtids_impl (this=0x2f9eca0, thd=0x7fffec000970, is_commit=true) at /mysql/mysql-5.7.17/sql/rpl_gtid_state.cc:240
#4  0x00000000017e6d25 in Gtid_state::update_on_commit (this=0x2f9eca0, thd=0x7fffec000970) at /mysql/mysql-5.7.17/sql/rpl_gtid_state.cc:201
#5  0x0000000000f46d46 in ha_commit_trans (thd=0x7fffec000970, all=true, ignore_global_read_lock=false) at /mysql/mysql-5.7.17/sql/handler.cc:1846
#6  0x000000000168676b in trans_commit (thd=0x7fffec000970) at /mysql/mysql-5.7.17/sql/transaction.cc:239
#7  0x0000000001802aaa in Xid_log_event::do_commit (this=0x7fffec013c60, thd_arg=0x7fffec000970) at /mysql/mysql-5.7.17/sql/log_event.cc:6824
#8  0x00000000018034d7 in Xid_apply_log_event::do_apply_event (this=0x7fffec013ca8, rli=0x3937d30) at /mysql/mysql-5.7.17/sql/log_event.cc:7049

当然其处理逻辑在Gtid_state::update_gtids_impl_own_gtid中。

(2)binlog开启同时参数log_slave_updates开启的情况

这种情况sql_thread执行过的Gtid事务可以通过binlog进行维护,所以mysql.gtid_executed表和gtid_purged变量不需要实时更新。

  • mysql.gtid_executed表修改时机

和主库一致。及在进行日志切换的时候进行更新,不做讨论

  • gtid_executed变量修改时机

和主库一样实时更新,不做讨论

  • gtid_purged变量修改时机

和主库一致,binlog删除时更新,不做讨论

四、从库修改时机源码函数分析

  • commit_owned_gtids函数逻辑:
//如果 binlog 没有开启包括(log_bin=0 和 sql_log_bin =0 )或者 开启了binlog 但是slave线程并且slave update 没有开启,都会记录gtid到表
//但是这里要注意一点在主库上如果binlog不开启那么thd->owned_gtid.sidno ==0 因为这个时候Gtid都没有生成,生成阶段为order_commit的commit阶段
  if ((!opt_bin_log || (thd->slave_thread && !opt_log_slave_updates)) &&
      (all || !thd->in_multi_stmt_transaction_mode()) && //all 代表是否是显示begin 事务in_multi_stmt_transaction_mode则相反
      !thd->is_operating_gtid_table_implicitly && //是否是GTID_NEXT方式 flase
      !thd->is_operating_substatement_implicitly)//是否是子语句 flase
  {
    /*
      If the binary log is disabled for this thread (either by
      log_bin=0 or sql_log_bin=0 or by log_slave_updates=0 for a
      slave thread), then the statement will not be written to
      the binary log. In this case, we should save its GTID into
      mysql.gtid_executed table and @@GLOBAL.GTID_EXECUTED as it
      did when binlog is enabled.
    */
    if (thd->owned_gtid.sidno > 0)
    {
      error= gtid_state->save(thd);//就是这里进行了mysql.gtid_executed表的实时更新
      *need_clear_owned_gtid_ptr= true;
    }
    else if (thd->owned_gtid.sidno == THD::OWNED_SIDNO_ANONYMOUS)
      *need_clear_owned_gtid_ptr= true;
  }
  • Gtid_state::update_gtids_impl_own_gtid 函数逻辑片段
    这个函数是5.7.17的,5.7.14没有逻辑放到了Gtid_state::update_gtids_impl中
if (is_commit)
  {
    DBUG_EXECUTE_IF(
      "rpl_gtid_update_on_commit_simulate_out_of_memory",
      DBUG_SET("+d,rpl_gtid_get_free_interval_simulate_out_of_memory"););
    /*
      Any session adds transaction owned GTID into global executed_gtids.

      If binlog is disabled, we report @@GLOBAL.GTID_PURGED from
      executed_gtids, since @@GLOBAL.GTID_PURGED and @@GLOBAL.GTID_EXECUTED
      are always same, so we did not save gtid into lost_gtids for every
      transaction for improving performance.

      If binlog is enabled and log_slave_updates is disabled, slave
      SQL thread or slave worker thread adds transaction owned GTID
      into global executed_gtids, lost_gtids and gtids_only_in_table.
    */
    executed_gtids._add_gtid(thd->owned_gtid); //加入executed_gtids集合
    thd->rpl_thd_ctx.session_gtids_ctx().
      notify_after_gtid_executed_update(thd);
    if (thd->slave_thread && opt_bin_log && !opt_log_slave_updates)//如果是slave线程同时binlog开启了并且log_slave_updates关闭了
                                                                   //如果binlog关闭则使用 executed_gtids这样提高性能前面的注释说了
    {
      lost_gtids._add_gtid(thd->owned_gtid);  //写入lost_gtids也就是更新参数gtid_purged变量
      gtids_only_in_table._add_gtid(thd->owned_gtid);
    }
  }

五、通用更改时机

mysql.gtid_executed表修改时机
  • 在reset master的时候清空本表
    栈帧如下:
#0  Gtid_table_persistor::delete_all (this=0x2f9f9c0, table=0x7fff2c0116a0) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_persist.cc:795
#1  0x000000000180a4ef in Gtid_table_persistor::reset (this=0x2f9f9c0, thd=0x7fff2c000b70) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_persist.cc:689
#2  0x0000000001801f2e in Gtid_state::clear (this=0x2ff8bb0, thd=0x7fff2c000b70) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_state.cc:36
#3  0x000000000184fee6 in MYSQL_BIN_LOG::reset_logs (this=0x2dffe80, thd=0x7fff2c000b70, delete_only=false)
    at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:5586
#4  0x0000000001872308 in reset_master (thd=0x7fff2c000b70) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_master.cc:587

其主要逻辑在Gtid_state::clear中。

  • 在set global gitd_purged的时候,设置本表
    栈帧如下:
#0  Gtid_table_persistor::save (this=0x2f9f9c0, gtid_set=0x7ffff0359a70) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_persist.cc:425
#1  0x000000000180400a in Gtid_state::save (this=0x2ff8bb0, gtid_set=0x7ffff0359a70) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_state.cc:796
#2  0x0000000001803c25 in Gtid_state::add_lost_gtids (this=0x2ff8bb0, gtid_set=0x7ffff0359a70) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/rpl_gtid_state.cc:737
#3  0x00000000016778f3 in Sys_var_gtid_purged::global_update (this=0x2de9fe0, thd=0x7fff2c000b70, var=0x7fff2c006630)
    at /root/mysql5.7.14/percona-server-5.7.14-7/sql/sys_vars.cc:5888
#4  0x00000000014d5cd1 in sys_var::update (this=0x2de9fe0, thd=0x7fff2c000b70, var=0x7fff2c006630) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/set_var.cc:184
#5  0x00000000014d74ee in set_var::update (this=0x7fff2c006630, thd=0x7fff2c000b70) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/set_var.cc:812
#6  0x00000000014d6d1a in sql_set_variables (thd=0x7fff2c000b70, var_list=0x7fff2c003528) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/set_var.cc:669

其主要逻辑在Gtid_state::add_lost_gtids中。

gtid_executed变量修改时机
  • 在reset master的时候清空本变量
    栈帧同上
  • 在set global gitd_purged的时候,设置本变量
    栈帧同上
  • 在mysql启动的时候初始化设置gtid_executed变量,这个将在后面章节详细描述描述步骤。
gtid_purged变量修改时机
  • 在reset master的时候清空本变量
    栈帧同上
  • 在set global gitd_purged的时候,设置本变量
    栈帧同上
  • 在mysql启动的时候初始化设置gtid_executed变量,这个将在后面章节详细描述描述步骤。

六、通用更改时机源码函数分析

  • Gtid_state::clear函数逻辑
int Gtid_state::clear(THD *thd)
{
 ....
  // 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();//清空only in table Gtid set
  previous_gtids_logged.clear();//清空 previous gtids logged Gtid set
  /* Reset gtid_executed table. */
  if ((ret= gtid_table_persistor->reset(thd)) == 1)//此处清空mysql.gtid_executed表
  {
    /*
      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);
}
  • Gtid_state::add_lost_gtids函数逻辑
enum_return_status Gtid_state::add_lost_gtids(const Gtid_set *gtid_set)
{
  ......
  if (save(gtid_set)) //此处将set gtid_purge的值加入到mysql.gtid_executed表中
    RETURN_REPORTED_ERROR;
  PROPAGATE_REPORTED_ERROR(gtids_only_in_table.add_gtid_set(gtid_set));
  PROPAGATE_REPORTED_ERROR(lost_gtids.add_gtid_set(gtid_set));//此处将set gtid_purge的值加入到gtid_purge变量中
  PROPAGATE_REPORTED_ERROR(executed_gtids.add_gtid_set(gtid_set));//此处将set gtid_purge的值加入到gtid_executed变量中
  lock_sidnos(gtid_set);
  broadcast_sidnos(gtid_set);
  unlock_sidnos(gtid_set);
  DBUG_RETURN(RETURN_STATUS_OK);
}

七、本节小结

为了方便这里将上面的重点文字描述进行提取,去掉源码部分,方便大家阅读

主库修改时机

(1) binlog关闭

不生成Gtid,mysql.gtid_executed表/gtid_executed变量/gtid_purged变量均不更新。

(2) binlog打开
  • mysql.gtid_executed表修改时机
    在binlog发生切换(rotate)的时候保存直到上一个binlog文件执行过的全部Gtid,它不是实时更新的。
  • gtid_executed变量修改时机
    如前文所述ordered_commit flush阶段生成Gtid,在commit阶段才计入gtid_executed变量,它是实时更新的。
  • gtid_purged变量修改时机
    在Mysql触发的清理binlog的情况下,比如purge binary logs to或者超过参数expire_logs_days设置的天数后自动删除,需要将丢失的Gtid计入这个变量中。

从库修改时机

(1) binlog关闭或者binlog开启参数log_slave_updates关闭的情况
  • mysql.gtid_executed表修改时机
    实时将Gtid持久化到mysql.gtid_executed表中。
  • gtid_executed变量修改时机
    它是实时更新的。
  • gtid_purged变量修改时机
    由于压根没有binlog来记录已经执行过的Gtid事务,所以gtid_purged变量实时更新
(2) binlog开启同时参数log_slave_updates开启的情况
  • mysql.gtid_executed表修改时机
    进行日志切换的时候进行更新,同主库。
  • gtid_executed变量修改时机
    实时更新,同主库。
  • gtid_purged变量修改时机
    binlog删除时更新,同主库。

通用修改时机

  • mysql.gtid_executed表修改时机
    1、在reset master的时候清空本表。
    2、在set global gitd_purged的时候,设置本表。
  • gtid_executed变量修改时机
    1、在reset master的时候清空本变量。
    2、在set global gitd_purged的时候,设置本变量。
    3、在mysql启动的时候初始化设置gtid_executed变量。
  • gtid_purged变量修改时机
    1、在reset master的时候清空本变量。
    2、在set global gitd_purged的时候,设置本变量。
    3、在mysql启动的时候初始化设置gtid_executed变量。

此外reset master命令除了完整上述功能还会清理binlog,重新初始化binlog从序号1开始。而set global gitd_purged参数一般只有在reset master后使用,用于搭建Gtid从库或者处理Gtid从库故障。

学习完本节至少能学习到:

  • 1、主库和从库对于mysql.gtid_executed表,gtid_executed变量,gitd_purged变量
    在各种情况下的修改时机
  • 2、reset master做了什么关于Gtid相关的工作
  • 3、set global gitd_purged做了什么关于Gtid相关的工作

作者微信:

微信.jpg

时间: 2024-10-25 15:15:10

Mysql 5.7 Gtid内部学习(五) mysql.gtid_executed表/gtid_executed变量/gtid_purged变量的更改时机的相关文章

Mysql 5.7 Gtid内部学习(四) mysql.gtid_executed表Previous gtid Event的改变

之所以把mysql.gtid_executed表的作用和Previous gtid Event的改变放到一起进行描述是因为它们后面文章探讨的基础.这部分使用到了我自己使用C语言写的原生binlog解析工具infobin. 百度云盘下载如下:http://pan.baidu.com/s/1jHIWUN0 一.Gtid event 为什么要先描述什么是Gtid event呢?因为后面会用到,实际上在中其核心元素就是一个形如: 31704d8a-da74-11e7-b6bf-52540a7d243:1

Mysql 5.7 Gtid内部学习(一) 导读

Mysql Gtid特性是5.6加入的一个强大的特性,它的目的在于使用Gtid的Mysql能够在整个复制环境中能够自动的切换,而不像以前需要指定文件和位置,这也一定是未来发展的方向,我们熟知的MGR也是基于Gtid的,所以了解Gtid的原理也是必要的. Gtid的维护是完全自动的,但是实际使用上确实有较多的坑,也导致很多朋友对Gtid还是觉得畏惧,本系列文章将从Gtid模块的源码出发分析,并且给出总结,然后结合运维和案例进行综合的解析,我希望抛砖引玉让希望了解源码的朋友也有所收获,但是能力有限特

Mysql 5.7 Gtid内部学习(八) Gtid带来的运维改变

依托前文的解析来讲5.7中 Gtid带来的运维改变,我想理解应该是更加深刻,这节主要讨论以下几个部分: 如何跳过一个事务 mysqldump导出行为的改变 5.7中搭建基于Gtid的主从 5.7中Gtid的主从的切换 5.7中在线改变Gtid模式 一.如何跳过一个事务 和传统基于位置的主从不同,如果从库报错我们需要获得从库执行的最后一个事务,方法有如下: show slave status \G 中的 Executed_Gtid_Set. show global variables like '

Mysql 5.7 Gtid内部学习(十) 实际案例(二)

本案例是我真实遇到过的一个坑,也在前文中不止一次的提到,当时也是非常纳闷,其实知道原因后只能说为什么会这么坑. 一.触发条件 本案列我测试过4个版本 percona Mysql 5.7.14 官方社区 Mysql 5.7.17 percona Mysql 5.7.19 percona Mysql 5.7.15 其中percona Mysql 5.7.14和官方社区 Mysql 5.7.17有这个问题.其他版本未知 已知percona Mysql 5.7.14或者官方社区 Mysql 5.7.17

Mysql 5.7 Gtid内部学习(二) Gtid相关内部数据结构

1. Gtid基本格式 单个Gtid: e859a28b-b66d-11e7-8371-000c291f347d:1 前一部分是server_uuid,后面一部分是执行事务的唯一标志,通常是自增的.内部使用Gtid这种数据结构表示,后面会描述. 区间Gtid: e859a28b-b66d-11e7-8371-000c291f347d:1-5 前一部分是server_uuid,后面一部分是执行事务的唯一标志集合,在内部使用Gtid_set中某个Sidno对应的Interval节点表示,后面会描述.

Mysql 5.7 Gtid内部学习(九) 实际案例(一)

本案例是一个朋友的案例他也写了出来如下:https://mp.weixin.qq.com/s/XSnFkuYzIlGWMaXIl-oPeQ 但是和他交流后他也准备改因为分析有一些小问题. 一.触发条件 binlog_gtid_simple_recovery=false. 5.7.6以上版本. Gtid 关闭或者Gtid中途开启有大量的未开启Gtid的binlog. 二.本案例回顾 版本:MySQL版本 5.7.19. 故障为:大概每半小时发生一次故障,整个Mysql压力巨大,很多简单的操作都相应

Mysql 5.7 Gtid内部学习(三) Gtid和Last_commt/sequnce_number的生成时机

一.Gtid生成类型 这里首先使用源码的解释给出三种类型: AUTOMATIC_GROUP GTID_GROUP ANONYMOUS_GROUP 其中AUTOMATIC_GROUP通常用于主库开启Gtid的情况,GTID_GROUP通常用于备库和使用了GTID_NEXT的情况下. 源码中有详细解释如下: /** Specifies that the GTID has not been generated yet; it will be generated on commit. It will d

[MySQL 5.6] GTID内部实现、运维变化及存在的bug

由于之前没太多深入关注gtid,这里给自己补补课,本文是我看文档和代码的整理记录. 本文的主要目的是记下跟gtid相关的backtrace,用于以后的问题排查.另外也会讨论目前在MySQL5.6.11版本中存在的bug. 本文讨论的内容包括 一.主库上的gtid产生及记录 二.备库如何使用GTID复制 三.主备运维的变化 四.MySQL5.6.11存在的bug 前言:什么是GTID 什么是GTID呢, 简而言之,就是全局事务ID(global transaction identifier ),最

浅析MySQL的用户和权限学习总结

一.关于MySQL权限的几点常识: 1.MySQL的权限系统主要用来验证用户的操作权限. 2.在MySQL内部,权限信息存放在MySQL数据库的granttable里.当mysql启动后,granttable里的信息会写入内存. 3.MySQL 使用user name 加 host name 来作为标识符. 通过这种标识符,可以用来区分不同host上的相同的user name. 4.MySQL 权限控制有2种策略: 1)根据密码是否正确来控制客户端的连接. 2)假设可以正常connect,ser