真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Mysql5.7Gtid內(nèi)部學(xué)習(xí)(六)Mysql啟動(dòng)初始化Gtid模塊

簡(jiǎn)書(shū)地址:
http://www.jianshu.com/p/fc836446cde0

本節(jié)也是一個(gè)重頭戲,后面的故障案例也和本節(jié)有關(guān)。本節(jié)將詳細(xì)介紹Gtid模塊的初始化,以及什么時(shí)候讀取了我們前文提及的兩個(gè)Gtid持久化介質(zhì):

清水網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、APP開(kāi)發(fā)、響應(yīng)式網(wǎng)站設(shè)計(jì)等網(wǎng)站項(xiàng)目制作,到程序開(kāi)發(fā),運(yùn)營(yíng)維護(hù)。創(chuàng)新互聯(lián)2013年至今到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。

  • binlog文件
  • MySQL.gtid_executed表

此外也會(huì)描述他們的讀取方式。
同時(shí)分析這個(gè)步驟我也將在重點(diǎn)步驟分為兩種情況來(lái)分別討論:

  1. 主庫(kù)開(kāi)啟Gtid開(kāi)啟binlog。
  2. 從庫(kù)開(kāi)啟Gtid開(kāi)啟binlog不開(kāi)啟log_slave_updates參數(shù)。

因?yàn)檫@兩種使我們通常設(shè)置的方式,下面簡(jiǎn)稱主庫(kù)從庫(kù)。

一、初始化Gtid 模塊全局變量?jī)?nèi)存空間

首先初始化Gtid 幾個(gè)Global 內(nèi)存空間包括 Gtid_state\Sid_map\gtid_table_persistor
這個(gè)調(diào)用由mysqld.cc調(diào)入gtid_server_init()。

 if (init_server_components())
    unireg_abort(MYSQLD_ABORT_EXIT); 

其中init_server_components()會(huì)初始化很多模塊Gtid只是其中很小的一個(gè),Innodb就在這里初始化。

gtid_server_init()函數(shù)片段如下:

(!(global_sid_lock= new Checkable_rwlock(
#ifdef HAVE_PSI_INTERFACE
                                             key_rwlock_global_sid_lock
#endif
                                            )) ||
     !(gtid_mode_lock= new Checkable_rwlock(
#ifdef HAVE_PSI_INTERFACE
                                            key_rwlock_gtid_mode_lock
#endif
                                           )) ||
     !(global_sid_map= new Sid_map(global_sid_lock)) || //new一個(gè)內(nèi)存Sid_map內(nèi)存空間出來(lái)
     !(gtid_state= new Gtid_state(global_sid_lock, global_sid_map))||//new一個(gè)內(nèi)存Gtid_state內(nèi)存空間出來(lái)
     !(gtid_table_persistor= new Gtid_table_persistor()));//new一個(gè)內(nèi)存Gtid_table_persistor內(nèi)存空間出來(lái) 

二、初始化獲得本數(shù)據(jù)庫(kù)的server_uuid

這個(gè)初始化過(guò)程在前文提到了,無(wú)非就是通過(guò)my.cnf獲得server_uuid,如果沒(méi)有則重新生成,具體可以參考一下前文這里不再過(guò)多描述。

 if (init_server_auto_options())
  {
    sql_print_error("Initialization of the server's UUID failed because it could"
                    " not be read from the auto.cnf file. If this is a new"
                    " server, the initialization failed because it was not"
                    " possible to generate a new UUID.");
    unireg_abort(MYSQLD_ABORT_EXIT);
  } 

三、初始化Gtid_state全局結(jié)構(gòu)

 global_sid_lock->rdlock();
  int gtid_ret= gtid_state->init();//將server_uuid對(duì)應(yīng)的sid(Uuid)和sidno加入到
Sid_map中。
  global_sid_lock->unlock();

  if (gtid_ret)
    unireg_abort(MYSQLD_ABORT_EXIT); 

其實(shí)本步驟也是完成了sidno的加入Sid_map中,有興趣的可以參考int Gtid_state::init()函數(shù)邏輯非常簡(jiǎn)單。

四、讀取mysql.gtid_executed表

這一步開(kāi)始讀取我們的第一個(gè)Gtid持久化介質(zhì)mysql.gtid_executed表,其最終調(diào)用為Gtid_table_persistor::fetch_gtids(Gtid_set *gtid_set)其原理為一行一行的讀取mysql.gtid_executed表的內(nèi)容加入到Gtid_state.executed_gtids中,我們來(lái)看源碼:

 // Initialize executed_gtids from mysql.gtid_executed table.
  if (gtid_state->read_gtid_executed_from_table() == -1)
    unireg_abort(1); 

Gtid_state::read_gtid_executed_from_table只是一層簡(jiǎn)單的封裝如下:

int Gtid_state::read_gtid_executed_from_table()
{
  return gtid_table_persistor->fetch_gtids(&executed_gtids);
} 

接下來(lái)看看Gtid_table_persistor::fetch_gtids(Gtid_set *gtid_set)函數(shù)邏輯片段

 if ((err= table->file->ha_rnd_init(true)))
  {
    ret= -1;
    goto end;
  }

  while(!(err= table->file->ha_rnd_next(table->record[0]))) //開(kāi)始一行一行讀取數(shù)據(jù)
  {
    /* Store the gtid into the gtid_set */

    /**
      @todo:
      - take only global_sid_lock->rdlock(), and take
        gtid_state->sid_lock for each iteration.
      - Add wrapper around Gtid_set::add_gno_interval and call that
        instead.
    */
    global_sid_lock->wrlock();
    if (gtid_set->add_gtid_text(encode_gtid_text(table).c_str()) !=  //此處將讀取到的一行Gtid區(qū)間加入到Gtid_state.executed_gtids中。
        RETURN_STATUS_OK)
    {
      global_sid_lock->unlock();
      break;
    }
    global_sid_lock->unlock();
  } 

完成本步驟過(guò)后Gtid_state.executed_gtids將設(shè)置,主庫(kù)和從庫(kù)的設(shè)置不同

  • 主庫(kù)因?yàn)閙ysql.gtid_executed只包含上一個(gè)binlog的全部Gtid所以,它不包含最新binlog的Gtid,所以在第七步還需要修正這個(gè)值。
  • 從庫(kù)因?yàn)閙ysql.gtid_executed會(huì)實(shí)時(shí)更新,因此它包含了全部的Gtid。

五、定義中間變量和獲得指針

本步驟是一個(gè)非關(guān)鍵步驟但是定義了一些中間變量而且定義了4個(gè)指針來(lái)分別獲得Gtid_state四個(gè)內(nèi)存變量的地址,方便操作。

 if (opt_bin_log) //如果binlog開(kāi)啟
  {
    /*
      Initialize GLOBAL.GTID_EXECUTED and GLOBAL.GTID_PURGED from
      gtid_executed table and binlog files during server startup.
    */
    Gtid_set *executed_gtids=
      const_cast(gtid_state->get_executed_gtids());//獲得Gtid_state.executed_gtids的指針
    Gtid_set *lost_gtids=
      const_cast(gtid_state->get_lost_gtids());//獲得gtid_state.get_lost_gtids的指針
    Gtid_set *gtids_only_in_table=
      const_cast(gtid_state->get_gtids_only_in_table());//獲得gtid_state.get_lost_gtids的指針
    Gtid_set *previous_gtids_logged=
      const_cast(gtid_state->get_previous_gtids_logged());//獲得gtid_state.previous_gtids_logged的指針

    Gtid_set purged_gtids_from_binlog(global_sid_map, global_sid_lock);//定義臨時(shí)變量用于存儲(chǔ)從binlog中掃描到已經(jīng)丟棄的Gtid事物。
    Gtid_set gtids_in_binlog(global_sid_map, global_sid_lock);//定義中間變量binlog中包含的所有Gtid事物包括丟棄的。
    Gtid_set gtids_in_binlog_not_in_table(global_sid_map, global_sid_lock);//定義中間變量沒(méi)有存放在表中而在binlog中存在過(guò)的Gtid事物,
//顯然主庫(kù)包含這樣一個(gè)集合,因?yàn)橹鲙?kù)的gtids_in_binlog>gtids_only_in_table,而從庫(kù)同樣也不包含這樣一個(gè)集合因?yàn)閺膸?kù)的全部Gtid事物都在表中。 

六、讀取binlog文件

本步驟將會(huì)讀取我們提及的第二個(gè)Gtid持久化介質(zhì)binlog,其讀取方式為先反向讀取獲得 gtids_in_binlog然后正向讀取獲得 purged_gtids_from_binlog,并且這里正向讀取purged_gtids_from_binlog將會(huì)受到binlog_gtid_simple_recovery參數(shù)的影響。同時(shí)我們前文所描述5.7 中Previous gtid Event會(huì)在沒(méi)有開(kāi)啟Gtid的binlog也包含這個(gè)event,將在這部體現(xiàn)出它的價(jià)值。

if (mysql_bin_log.init_gtid_sets(>ids_in_binlog,
                                     &purged_gtids_from_binlog,
                                     opt_master_verify_checksum,
                                     true/*true=need lock*/,
                                     NULL/*trx_parser*/,
                                     NULL/*gtid_partial_trx*/,
                                     true/*is_server_starting*/)) 

我們發(fā)現(xiàn)他實(shí)際上就是調(diào)用bool MYSQL_BIN_LOG::init_gtid_sets()函數(shù)我們繼續(xù)看這個(gè)函數(shù)重要代碼片段:

 list filename_list; //定義一個(gè)string list來(lái)存儲(chǔ)文件名
  LOG_INFO linfo;
  int error;

  list::iterator it;//定義一個(gè)list的正向迭代器
  list::reverse_iterator rit;//定義一個(gè)list的反向迭代器

for (error= find_log_pos(&linfo, NULL, false/*need_lock_index=false*/); !error; //這部分實(shí)際上就是將文件名全部加入到這個(gè)list中
       error= find_next_log(&linfo, false/*need_lock_index=false*/))
  {
    DBUG_PRINT("info", ("read log filename '%s'", linfo.log_file_name));
    filename_list.push_back(string(linfo.log_file_name));
  }
  if (error != LOG_INFO_EOF)
  {
    DBUG_PRINT("error", ("Error reading %s index",
                         is_relay_log ? "relaylog" : "binlog"));
    goto end;
  }

 if (all_gtids != NULL) //數(shù)據(jù)庫(kù)啟動(dòng)初始化的情況下all_gtids不會(huì)為NULL,但是如果是做purge binary logs命令等刪除binlog log all_gtid會(huì)傳入NULL
  {
    rit= filename_list.rbegin(); //反向迭代器指向list尾部
    bool can_stop_reading= false;
    reached_first_file= (rit == filename_list.rend());//如果只有一個(gè)binlog則為true
    while (!can_stop_reading && !reached_first_file) //開(kāi)始反向循環(huán)掃描來(lái)獲得gtids_in_binlog(all_gtids)集合
    {
      const char *filename= rit->c_str(); //獲取文件名
      rit++;
      reached_first_file= (rit == filename_list.rend());//如果達(dá)到第一個(gè)文件則為true表示掃描完成
      switch (read_gtids_from_binlog(filename, all_gtids,
                                     reached_first_file ? lost_gtids : NULL,
                                     NULL/* first_gtid */,
                                     sid_map, verify_checksum, is_relay_log)) //通過(guò)函數(shù)read_gtids_from_binlog讀取這個(gè)binlog文件
      {
        case ERROR:
        {
          error= 1;
          goto end;
        }
        case GOT_GTIDS:  //如果掃描本binlog有PREVIOUS GTID EVENT和GTID EVENT 則break 跳出循環(huán)且設(shè)置can_stop_reading= true
        {
          can_stop_reading= true;
          break;
        }
        case GOT_PREVIOUS_GTIDS://如果掃描本binlog只有PREVIOUS GTID EVENT 則進(jìn)入邏輯判斷
        {
          if (!is_relay_log)//我們只考慮binlog 不會(huì)是relaylog 那么 break 跳出循環(huán)且設(shè)置can_stop_reading= true,
                            //注意這里并不受到binlog_gtid_simple_recovery參數(shù)的影響,我們知道5.7.5過(guò)后每一個(gè)binlog都
                            //包含了PREVIOUS GTID EVENT實(shí)際上即使沒(méi)有開(kāi)啟GTID這里也會(huì)跳出循環(huán),則只是掃描了最后一個(gè)binlog 文件
            can_stop_reading= true;
          break;
        }
        case NO_GTIDS: //如果沒(méi)有找到PREVIOUS GTID EVENT和GTID EVENT 則做如下邏輯,實(shí)際上5.7過(guò)后不可能出現(xiàn)這種問(wèn)題,因?yàn)楸厝话薖REVIOUS GTID EVENT
                       //即便是沒(méi)有開(kāi)啟GTID,所以反向查找一定會(huì)在掃描最后一個(gè)文件后跳出循環(huán)
        {
          if (binlog_gtid_simple_recovery && is_server_starting &&
              !is_relay_log) //這里受到了binlog_gtid_simple_recovery參數(shù)的影響,但是我們知道這個(gè)分支是不會(huì)執(zhí)行的。除非這個(gè)數(shù)據(jù)庫(kù)是升級(jí)的并且沒(méi)有開(kāi)啟Gtid
          {
            DBUG_ASSERT(all_gtids->is_empty());//斷言all_gtids還是沒(méi)有找到
            DBUG_ASSERT(lost_gtids->is_empty());//斷言lost_gtids還是沒(méi)有找到
            goto end;//結(jié)束掃描,從這里我們發(fā)現(xiàn)如果mysql是升級(jí)而來(lái)的一定要注意這個(gè)問(wèn)題,設(shè)置binlog_gtid_simple_recovery可能拿不到正確的GTID,對(duì)于升級(jí)
                     //最好使用master-slave 進(jìn)行升級(jí),可以規(guī)避這個(gè)風(fēng)險(xiǎn)。
          }
          /*FALLTHROUGH*/
        }
        case TRUNCATED:
        {
          break;
        }
      }
    }
//中間還有一部分處理relaylog的占時(shí)沒(méi)有去研究接下來(lái)就是正向查找獲得purged_gtids_from_binlog(lost_gtids)

 if (lost_gtids != NULL && !reached_first_file)//如果前面的掃描沒(méi)有掃描完全部的binlog,這實(shí)際在5.7中是肯定的。
  {
   
    for (it= filename_list.begin(); it != filename_list.end(); it++)//進(jìn)行正向查找
    {
      /*
        We should pass a first_gtid to read_gtids_from_binlog when
        binlog_gtid_simple_recovery is disabled, or else it will return
        right after reading the PREVIOUS_GTIDS event to avoid stall on
        reading the whole binary log.
      */
      Gtid first_gtid= {0, 0};
      const char *filename= it->c_str();//獲得文件名指針
      switch (read_gtids_from_binlog(filename, NULL, lost_gtids,
                                     binlog_gtid_simple_recovery ? NULL :
                                                                   &first_gtid,
                                     sid_map, verify_checksum, is_relay_log))
      {
        case ERROR:
        {
          error= 1;
          /*FALLTHROUGH*/
        }
        case GOT_GTIDS: //如果掃描本binlog有PREVIOUS GTID EVENT和GTID EVENT 則跳出循環(huán)直達(dá)end
        {
          goto end;
        }
        case NO_GTIDS: //這里如果binlog不包含GTID EVENT和PREVIOUS GTID EVENT其處理邏輯一致
        case GOT_PREVIOUS_GTIDS:
        {
          if (binlog_gtid_simple_recovery) //這里受到了binlog_gtid_simple_recovery。如果設(shè)置為ON,實(shí)際上在5.7過(guò)后
            goto end;                      //PREVIOUS GTID EVENT是一定命中的,可以得到正確的結(jié)果,但是如果是5.6升級(jí)而來(lái)
          /*FALLTHROUGH*/                  //則binlog不包含PREVIOUS GTID EVENT則purged_gtids_from_binlog(lost_gtids)獲取為空
                                           //如果在5.7中關(guān)閉了GTID,這種情況這里雖然PREVIOUS GTID EVENT命中但是任然
                                           //不會(huì)跳出循環(huán)goto end,繼續(xù)下一個(gè)文件掃描。
        }                                  
        case TRUNCATED:
        {
          break;
        }
      }
    } 

到這里我們分析了反向查找和正向查找,我們代碼注釋上也說(shuō)明了binlog_gtid_simple_recovery作用,因?yàn)橛辛薖REVIOUS GTID EVENT的支持,5.7.6過(guò)后這個(gè)參數(shù)默認(rèn)都是設(shè)置為true,如果在Gtid關(guān)閉的情況下設(shè)置binlog_gtid_simple_recovery為flase可能需要掃描大量的binlog才會(huì)確定purged_gtids_from_binlog這個(gè)集合,這可能出現(xiàn)在兩個(gè)地方:

  • 如這里討論的Mysql重啟的時(shí)候。
  • 如前文所討論在purge binary logs to或者操作參數(shù)expire_logs_days設(shè)置的時(shí)間刪除binlog的時(shí)候。

這里也是我后文描述的第二個(gè)案例出現(xiàn)的原因。

正常情況下到這里我們的gtids_in_binlog和purged_gtids_from_binlog已經(jīng)獲?。?/p>

  • 主庫(kù)gtids_in_binlog包含了所有最新的Gtid事物(包含丟棄的)而purged_gtids_from_binlog包含了已經(jīng)丟棄的Gtid事物。
  • 從庫(kù)壓根沒(méi)有binlog因此gtids_in_binlog和purged_gtids_from_binlog為空集合。

七、對(duì)Gtid_state.executed_gtids和mysql.gtid_executed表的修正

如第四步描述主庫(kù)通過(guò)讀取mysql.gtid_executed表獲得的Gtid_state.executed_gtids并不是最新的,所以整理需要修正,代碼如下:

 if (!gtids_in_binlog.is_empty() && //如果gtids_in_binlog不為空,從庫(kù)為空不走這個(gè)邏輯了,這里主要是主庫(kù)對(duì)Gtid_state.executed_gtids的修正
        !gtids_in_binlog.is_subset(executed_gtids)) //并且executed_gtids是gtids_in_binlog的子集
      {
      gtids_in_binlog_not_in_table.add_gtid_set(>ids_in_binlog);
      if (!executed_gtids->is_empty())
        gtids_in_binlog_not_in_table.remove_gtid_set(executed_gtids);   //將不在表中的GTID及gtids_in_binlog-executed_gtids 加入到gtids_in_binlog_not_in_table
    if (gtid_state->save(>ids_in_binlog_not_in_table) == -1)//這里將gtids_in_binlog_not_in_table這個(gè)Gtid集合存儲(chǔ)到mysql.gtid_executed表中完成修正
      {
        global_sid_lock->unlock();
        unireg_abort(MYSQLD_ABORT_EXIT);
      }
      executed_gtids->add_gtid_set(>ids_in_binlog_not_in_table);//最后在executed_gtids中加入這個(gè)gtids_in_binlog_not_in_table,這個(gè)完成executed_gtids就是最新的Gtid_set了,完成了Gtid_state.executed_gtids的修正
    } 

這一步完全是主庫(kù)才會(huì)觸發(fā)的邏輯:

  • 主庫(kù)完成這一步Gtid_state.executed_gtids和mysql.gtid_executed表都將修正到最新的Gtid集合。
  • 從庫(kù)不做這個(gè)邏輯,因?yàn)閺膸?kù)的Gtid_state.executed_gtids和mysql.gtid_executed表本來(lái)就是最新的。

到這里Gtid_state.executed_gtids也就是我們的gtid_executed變量初始化已經(jīng)完成mysql.gtid_executed表已經(jīng)修正。

八、初始化Gtid_state.gtids_only_in_table

由于上一步已經(jīng)獲得了完整的的Gtid_state.executed_gtids 集合,這里獲得Gtid_state.gtids_only_in_table只需要簡(jiǎn)單的gtids_only_in_table= executed_gtids - gtids_in_binlog相減即可。

/* gtids_only_in_table= executed_gtids - gtids_in_binlog */
    if (gtids_only_in_table->add_gtid_set(executed_gtids) !=  //這里將executed_gtids加入到gtids_only_in_table
        RETURN_STATUS_OK)
    {
      global_sid_lock->unlock();
      unireg_abort(MYSQLD_ABORT_EXIT);
    }
    gtids_only_in_table->remove_gtid_set(>ids_in_binlog); //這里將去掉gtids_in_binlog 

這一步主庫(kù)和從庫(kù)如下:

  • 主庫(kù)由于存在Gtid_state.executed_gtids是最新的同時(shí)gtids_in_binlog也是最新的所以Gtid_state. gtids_only_in_table是一個(gè)空集合。
  • 從庫(kù)由于Gtid_state.executed_gtids是最新的但是gtids_in_binlog 是一個(gè)空集合,所以Gtid_state. gtids_only_in_table和Gtid_state.executed_gtids相等。

九、初始化Gtid_state.lost_gtids

這一步開(kāi)始獲取Gtid_state.lost_gtids也就是我們的gtid_purged變量,這里只需要簡(jiǎn)單的用Gtid_state.gtids_only_in_table + purged_gtids_from_binlog;即可,他們都已經(jīng)獲取

 /*
      lost_gtids = executed_gtids -
                   (gtids_in_binlog - purged_gtids_from_binlog)
                 = gtids_only_in_table + purged_gtids_from_binlog;
    */

 if (lost_gtids->add_gtid_set(gtids_only_in_table) != RETURN_STATUS_OK || //將gtids_only_in_table這個(gè)集合加入lost_gtids
        lost_gtids->add_gtid_set(&purged_gtids_from_binlog) !=            //將purged_gtids_from_binlog加入到這個(gè)集合
        RETURN_STATUS_OK)
    {
      global_sid_lock->unlock();
      unireg_abort(MYSQLD_ABORT_EXIT);
    } 

這一步主庫(kù)和從庫(kù)如下:

  • 主庫(kù)由于Gtid_state.gtids_only_in_table為空集合,而purged_gtids_from_binlog則是獲取的第一個(gè)binlog Previous gtid Event的Gtid。所以正常情況下Gtid_state.lost_gtids就等于第一個(gè)binlog的binlog Previous gtid Event 的Gtid。
  • 從庫(kù)由于Gtid_state.gtids_only_in_table和Gtid_state.executed_gtids相等而purged_gtids_from_binlog是空集合,所以正常情況下從庫(kù)的Gtid_state.lost_gtids就等于就等于Gtid_state.executed_gtids。也就是gtid_purged變量和gtid_executed變量相等。

到這里gtid_purged變量和gtid_executed變量以及mysql.gtid_executed表都已經(jīng)初始化完成。

十、初始化Gtid_state.previous_gtids_logged

這個(gè)值沒(méi)有變量能夠看到,它代表是直到上一個(gè)binlog所包含的全部的binlog Gtid。

/* Prepare previous_gtids_logged for next binlog */
    if (previous_gtids_logged->add_gtid_set(>ids_in_binlog) !=//很明顯將掃描到的gtids_in_binlog的這個(gè)集合加入即可。
        RETURN_STATUS_OK)
    {
      global_sid_lock->unlock();
      unireg_abort(MYSQLD_ABORT_EXIT);
    } 

很明顯因?yàn)閱?dòng)的時(shí)候binlog會(huì)切換所以簡(jiǎn)單的將掃描到gtids_in_binlog加入到集合即可。
這一步主庫(kù)和從庫(kù)如下:

  • 主庫(kù)gtids_in_binlog包含全部Gtid事物。所以gtid_state.previous_gtids_logged就包含全部binlog中的Gtid事物。但是之后會(huì)做binlog切換。
  • 從庫(kù)gtids_in_binlog為空,顯然gtid_state.previous_gtids_logged也為空。

十一、本節(jié)小結(jié)

通過(guò)讀取mysql.gtid_executed和binlog,然后經(jīng)過(guò)一系列的運(yùn)算后,我們的Gtid模塊初始化完成。4個(gè)內(nèi)存變量和mysql.gtid_executed都得到了初始化,總結(jié)如下:

  1. mysql.gtid_executed表
  • 主庫(kù)在第四步讀取,在第七步的修正完成初始化,它包含了現(xiàn)有的全部的Gtid事物。
  • 從庫(kù)在第四步讀取,因?yàn)閺膸?kù)mysql.gtid_executed本來(lái)就是最新的不需要更改。
  1. Gtid_state.executed_gtids和它對(duì)應(yīng)了變量gtid_executed
  • 主庫(kù)通過(guò)第四步和第七步將Gtid_state.executed_gtids初始化,它包含了全部的Gtid事物。
  • 從庫(kù)通過(guò)第四步就已經(jīng)全部初始化完成,它包含了現(xiàn)有的全部的Gtid事物。
  1. Gtid_state.gtids_only_in_table
  • 主庫(kù)通過(guò)第八步進(jìn)行初始化,主庫(kù)Gtid_state. gtids_only_in_table是一個(gè)空集合。
  • 從庫(kù)通過(guò)第八步進(jìn)行初始化,從庫(kù)Gtid_state. gtids_only_in_table和Gtid_state.executed_gtids相等。
  1. Gtid_state.lost_gtids它對(duì)應(yīng)了變量gtid_purged。
  • 主庫(kù)通過(guò)第九步進(jìn)行初始化,Gtid_state.lost_gtids就是第一個(gè)binlog Previous gtid Event的Gtid。
  • 主庫(kù)通過(guò)第九步進(jìn)行初始化,Gtid_state.lost_gtids等于Gtid_state.executed_gtids
  1. Gtid_state.previous_gtids_logged。
  • 主庫(kù)通過(guò)第十步進(jìn)行初始化,gtid_state.previous_gtids_logged就包含全部binlog中的Gtid事物
  • 從庫(kù)通過(guò)第十步進(jìn)行初始化,gtid_state.previous_gtids_logged為空集合。

注意本節(jié)第五步包含了binlog文件的讀取方法以及binlog_gtid_simple_recovery參數(shù)的作用

學(xué)習(xí)完本節(jié)至少能夠?qū)W習(xí)到:

  • 1、mysql.gtid_executed是如何以及何時(shí)讀取的。
  • 2、binlog 文件中的Gtid何時(shí)讀取。
  • 3、整個(gè)Gtid模塊的初始化流程及細(xì)節(jié)。
  • 4、binlog_gtid_simple_recovery參數(shù)的作用。

作者微信:


Mysql 5.7 Gtid內(nèi)部學(xué)習(xí)(六) Mysql啟動(dòng)初始化Gtid模塊

分享題目:Mysql5.7Gtid內(nèi)部學(xué)習(xí)(六)Mysql啟動(dòng)初始化Gtid模塊
本文URL:http://weahome.cn/article/geehis.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部