本節(jié)將集中討論下面三種Gtid更新的時機,這部分相當重要,后面的故障案列會和這節(jié)有關(guān)。下面先來看一下他們的定義
- mysql.gtid_executed表:Gtid持久化的介質(zhì),Mysql啟動階段會讀取這個表來獲取gtid_executed變量的值。
- gtid_executed變量(show global variables):Mysql數(shù)據(jù)庫已經(jīng)執(zhí)行了哪些Gtid事務(wù),處于內(nèi)存中。show slave status中的Executed_Gtid_Set也取自這里。
- gtid_purged變量(show global variables):由于binlog文件的刪除(如purge binary logfiles或者超過expire_logs_days設(shè)置)已經(jīng)丟失的Gtid事務(wù),同時在搭建備庫的我們使用set global gtid_purged變量來提示Mysql哪些Gtid事務(wù)我已經(jīng)執(zhí)行過了。
這也是我們DBA通常能夠觀察到的幾種Gtid,有了前文的描述我們知道其中mysql.gtid_executed表是一種Gtid持久化的介質(zhì),而gtid_executed變量和gtid_purged變量則對應(yīng)
了Gtid_state中的executed_gtids和lost_gtids內(nèi)存數(shù)據(jù)。他們分別表示Mysql數(shù)據(jù)庫執(zhí)行了哪些Gtid事務(wù),有哪些Gtid事務(wù)由于binlog文件的刪除已經(jīng)丟失了。
其次我們先來達成一個共識gtid_executed變量一定是實時更新的不管主庫和從庫。我們的討論分為主庫,從庫和通用從源碼的角度進行詳細討論。并且約定都是打開Gtid的情況下。最后給出最終總結(jié)。
一、主庫修改時機
(1) binlog關(guān)閉
不生成Gtid,mysql.gtid_executed表/gtid_executed變量/gtid_purged變量均不更新。
(2) binlog打開
-
mysql.gtid_executed表修改時機
在binlog發(fā)生切換(rotate)的時候保存直到上一個binlog文件執(zhí)行過的全部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 中我們在隨后的部分討論這個函數(shù)邏輯。
-
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中我們在隨后的部分討論這個函數(shù)邏輯。
-
gtid_purged變量修改時機
在Mysql觸發(fā)的清理binlog的情況下,比如purge binary logs to或者超過參數(shù)expire_logs_days設(shè)置的天數(shù)后自動刪除,需要將丟失的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函數(shù)是一個及其重要的函數(shù),主要用在:
- Mysql啟動時候初始化整個Gtid_state中的各種Gtid_set。
- Mysql刪除binlog(如purge binary logfiles或者超過expire_logs_days設(shè)置)后需要確認gtid_purged變量(及Gtid_state.lost_gtids)的值的時候。
隨后我會單獨一節(jié)來講解Mysql Gtid模塊的初始化還會講解這個函數(shù)。
二、主庫修改時機源碼函數(shù)分析
這里就對上面提到的主要邏輯函數(shù)進行分析
- Gtid_state::save_gtids_of_last_binlog_into_table函數(shù)邏輯
logged_gtids_last_binlog.add_interval_memory(PREALLOCATED_INTERVAL_COUNT, iv); //這里構(gòu)建一個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) != //將當前執(zhí)行過的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(>ids_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函數(shù)代碼片段
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函數(shù)代碼片段
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這個函數(shù)稍后
//詳細討論
global_sid_lock->unlock();
if (error)
goto err;
}
三、從庫修改時機
(1) binlog關(guān)閉或者binlog開啟參數(shù)log_slave_updates關(guān)閉的情況
將他們放到一起因為他們的表現(xiàn)完全一樣。
-
mysql.gtid_executed表修改時機
前面已經(jīng)說過這種情況下從庫沒有辦法通過binlog來持久化sql_thread執(zhí)行過的Gtid事務(wù),只能通過實時更新mysql.gtid_executed表來保存,所以必須要要實時將Gtid持久化到mysql.gtid_executed表中。實際上實時保存mysql.gtid_executed發(fā)生在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來記錄已經(jīng)執(zhí)行過的Gtid事務(wù),所以gtid_purged變量實時更新
其更改處于整個ha_commit_trans的結(jié)尾如下:
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開啟同時參數(shù)log_slave_updates開啟的情況
這種情況sql_thread執(zhí)行過的Gtid事務(wù)可以通過binlog進行維護,所以mysql.gtid_executed表和gtid_purged變量不需要實時更新。
-
mysql.gtid_executed表修改時機
和主庫一致。及在進行日志切換的時候進行更新,不做討論
-
gtid_executed變量修改時機
和主庫一樣實時更新,不做討論
-
gtid_purged變量修改時機
和主庫一致,binlog刪除時更新,不做討論
四、從庫修改時機源碼函數(shù)分析
- commit_owned_gtids函數(shù)邏輯:
//如果 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 事務(wù)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 函數(shù)邏輯片段
這個函數(shù)是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關(guān)閉了
//如果binlog關(guān)閉則使用 executed_gtids這樣提高性能前面的注釋說了
{
lost_gtids._add_gtid(thd->owned_gtid); //寫入lost_gtids也就是更新參數(shù)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的時候,設(shè)置本表
棧幀如下:
#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的時候,設(shè)置本變量
棧幀同上 - 在mysql啟動的時候初始化設(shè)置gtid_executed變量,這個將在后面章節(jié)詳細描述描述步驟。
gtid_purged變量修改時機
-
在reset master的時候清空本變量
棧幀同上 -
在set global gitd_purged的時候,設(shè)置本變量
棧幀同上 - 在mysql啟動的時候初始化設(shè)置gtid_executed變量,這個將在后面章節(jié)詳細描述描述步驟。
六、通用更改時機源碼函數(shù)分析
- Gtid_state::clear函數(shù)邏輯
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函數(shù)邏輯
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);
}
七、本節(jié)小結(jié)
為了方便這里將上面的重點文字描述進行提取,去掉源碼部分,方便大家閱讀
主庫修改時機
(1) binlog關(guān)閉
不生成Gtid,mysql.gtid_executed表/gtid_executed變量/gtid_purged變量均不更新。
(2) binlog打開
- mysql.gtid_executed表修改時機
在binlog發(fā)生切換(rotate)的時候保存直到上一個binlog文件執(zhí)行過的全部Gtid,它不是實時更新的。 - gtid_executed變量修改時機
如前文所述ordered_commit flush階段生成Gtid,在commit階段才計入gtid_executed變量,它是實時更新的。 - gtid_purged變量修改時機
在Mysql觸發(fā)的清理binlog的情況下,比如purge binary logs to或者超過參數(shù)expire_logs_days設(shè)置的天數(shù)后自動刪除,需要將丟失的Gtid計入這個變量中。
從庫修改時機
(1) binlog關(guān)閉或者binlog開啟參數(shù)log_slave_updates關(guān)閉的情況
- mysql.gtid_executed表修改時機
實時將Gtid持久化到mysql.gtid_executed表中。 - gtid_executed變量修改時機
它是實時更新的。 - gtid_purged變量修改時機
由于壓根沒有binlog來記錄已經(jīng)執(zhí)行過的Gtid事務(wù),所以gtid_purged變量實時更新
(2) binlog開啟同時參數(shù)log_slave_updates開啟的情況
- mysql.gtid_executed表修改時機
進行日志切換的時候進行更新,同主庫。 - gtid_executed變量修改時機
實時更新,同主庫。 - gtid_purged變量修改時機
binlog刪除時更新,同主庫。
通用修改時機
mysql.gtid_executed表修改時機
1、在reset master的時候清空本表。
2、在set global gitd_purged的時候,設(shè)置本表。gtid_executed變量修改時機
1、在reset master的時候清空本變量。
2、在set global gitd_purged的時候,設(shè)置本變量。
3、在mysql啟動的時候初始化設(shè)置gtid_executed變量。gtid_purged變量修改時機
1、在reset master的時候清空本變量。
2、在set global gitd_purged的時候,設(shè)置本變量。
3、在mysql啟動的時候初始化設(shè)置gtid_executed變量。
此外reset master命令除了完整上述功能還會清理binlog,重新初始化binlog從序號1開始。而set global gitd_purged參數(shù)一般只有在reset master后使用,用于搭建Gtid從庫或者處理Gtid從庫故障。
學習完本節(jié)至少能學習到:
- 1、主庫和從庫對于mysql.gtid_executed表,gtid_executed變量,gitd_purged變量
在各種情況下的修改時機 - 2、reset master做了什么關(guān)于Gtid相關(guān)的工作
- 3、set global gitd_purged做了什么關(guān)于Gtid相關(guān)的工作
作者微信:
