- 深入理解MySQL主從原理
- 高鵬
- 965字
- 2021-04-16 16:29:21
1.3.2 步驟解析
1.獲取server_uuid
這一步會調(diào)用init_server_auto_options函數(shù),用來讀取auto.cnf文件,如果沒有找到auto.cnf文件則會重新生成一個,生成的方法我們已經(jīng)在1.1節(jié)描述過了。丟失auto.cnf文件會導致GTID發(fā)生改變,這是額外需要注意的地方。
2.讀取mysql.gtid_executed表
這一步開始讀取第一個 GTID 的持久化介質(zhì):mysql.gtid_executed 表,其最終調(diào)用為Gtid_table_persistor::fetch_gtids函數(shù),原理為一行一行地讀取mysql.gtid_executed表的數(shù)據(jù)并加入executed_gtids變量,但是對于主庫和從庫來講,executed_gtids變量的意義不一樣:
· 這個時候,主庫的executed_gtids變量是不正確的,如1.2節(jié)所述,主庫的mysql.gtid_executed表并不包含當前binary log的GTID,這些GTID還存在于binary log中。
· 這個時候,從庫的executed_gtids變量是正確的,如1.2節(jié)所述,從庫的mysql.gtid_executed表包含所有的GTID。
下面是部分代碼:

3.讀取binary log
這一步將會讀取我們提及的第二個GTID持久化介質(zhì)binary log,其讀取方式為:先反向掃描,獲得最后一個binary log中包含的最新GTID;然后正向掃描,獲得第一個binary log中的lost GTID,在MySQL 5.7中可以理解為第一個binary log中的PREVIOUS_GTIDS_LOG_EVENT,但是會受到參數(shù)binlog_gtid_simple_recovery的影響(注意,這里筆者描述簡化了,實際情況要復雜很多)。整個邏輯處于MYSQL_BIN_LOG::init_gtid_sets函數(shù)中。下面我們看一下代碼,為了簡捷,該代碼做了大量縮減。
反向掃描:

正向掃描:


這里我們看到了參數(shù)binlog_gtid_simple_recovery是如何影響源碼邏輯的(默認設(shè)置為ON)。
在MySQL 5.7中,即便在不開啟GTID的情況下,PREVIOUS_GTIDS_LOG_EVENT也會存在,如果參數(shù)binlog_gtid_simple_recovery設(shè)置為ON,那么正向掃描binary log獲取lost GTID的過程可以快速完成。但是如果參數(shù)binlog_gtid_simple_recovery設(shè)置為OFF,那么這個過程可能進行大量的binary log掃描,直到找到GTID_EVENT為止。
GTID模塊初始化、執(zhí)行purge binlog命令、超過參數(shù)expire_logs_days的大小刪除binary log,這三種情況都會觸發(fā)binary log的掃描行為。
MySQL 5.7中的參數(shù)binlog_gtid_simple_recovery保持默認值即可。曾經(jīng)有一個案例,當每次超過參數(shù)expire_logs_days的大小而清理binary log時,系統(tǒng)的I/O壓力都非常高,最后發(fā)現(xiàn)和這里參數(shù)binlog_gtid_simple_recovery=false的設(shè)置有關(guān),在1.2節(jié)中我們已經(jīng)講述過,每次清理binary log時都會觸發(fā)gtid_pured變量的設(shè)置。
4.將只在binary log的GTID加入
這一步只在主庫中出現(xiàn),從庫中無此步驟。主要代碼如下。


這一步會將那些只在binary log中存在的GITD加入mysql.gtid_executed表和gtid_executed變量。
這樣,主庫的mysql.gtid_executed表和gtid_executed變量也正確了。
5.初始化gtid_purged變量
初始化gtid_purged變量對于主庫和從庫是不同的,如下。
· 主庫即上面掃描到的lost GTID,一般來講是第一個binary log中的PREVIOUS_GTIDS_LOG_EVENT(但是會受到參數(shù)binlog_gtid_simple_recovery的影響)。
· 因為沒有binary log的存在,所以從庫即gtid_executed變量。
源碼如下。

完成了這一步,整個初始化過程基本上就結(jié)束了,mysql.gtid_executed表、gtid_executed變量與gtid_purged變量都得到了初始化。
需要注意的是,以上步驟是筆者做了提煉和簡化的,源碼中要復雜很多,需要初始化的變量也多得多。
- Mastering NetBeans
- ServiceNow Application Development
- Python概率統(tǒng)計
- Progressive Web Apps with React
- Git Version Control Cookbook
- Rake Task Management Essentials
- 基于Java技術(shù)的Web應用開發(fā)
- Object-Oriented JavaScript(Second Edition)
- Java持續(xù)交付
- Learning JavaScript Data Structures and Algorithms
- RESTful Java Web Services(Second Edition)
- 詳解MATLAB圖形繪制技術(shù)
- Test-Driven JavaScript Development
- 現(xiàn)代C:概念剖析和編程實踐
- 30天學通C#項目案例開發(fā)