相比傳統的MySQL復制,gtid復制無論是配置還是維護都要輕松的多。本文對gtid復制稍作介紹。
MySQL基於GTID復制官方手冊:https://dev.mysql.com/doc/refman/5.7/en/replication-gtids.html
1.gtid基本概念
傳統的基於binlog position復制的方式有個嚴重的缺點:如果slave連接master時指定的binlog文件錯誤或者position錯誤,會造成遺漏或者重復,很多時候前后數據是有依賴性的,這樣就會出錯而導致數據不一致。
從MYSQL5.6開始,mysql開始支持GTID復制。GTID的全稱是global transaction id,表示的是全局事務ID。GTID的分配方式為uuid:trans_id
,其中:
uuid
是每個mysql服務器都唯一的,記錄在$datadir/auto.cnf
中。如果復制結構中,任意兩台服務器uuid重復的話(比如直接冷備份時,auto.conf中的內容是一致的),在啟動復制功能的時候會報錯。這時可以刪除auto.conf文件再重啟mysqld。
mysql> show variables like "%uuid%";
+---------------+--------------------------------------+
| Variable_name | Value |
+---------------+--------------------------------------+
| server_uuid | a126fcb6-3706-11e8-b1d5-000c294ebf0d |
+---------------+--------------------------------------+
1 row in set (0.00 sec)
mysql> \! cat /data/auto.cnf
[auto]
server-uuid=a126fcb6-3706-11e8-b1d5-000c294ebf0d
trans_id
是事務ID,可以唯一標記某MySQL服務器上執行的某個事務。事務號從1開始,每提交一個事務,事務號加1。
例如"gtid_executed 5ad9cb8e-2092-11e7-ac95-000c29bf823d:1-6",表示該server_uuid上執行了從1到6的事務。
2.gtid的生命周期
gtid的生命周期對於配置和維護基於gtid的復制至關重要。所以,請盡可能理解以下幾個過程。
gtid在master和slave上是一直持久化保存(即使刪除了日志,也會記錄到Previous_GTID中)的。它在master和slave上的生命周期如下:
-
客戶端發送DDL/DML給master上,master首先對此事務生成一個唯一的gtid,假如為
uuid_xxx:1
,然后立即執行該事務中的操作。注意,主從復制的情況下,sync-binlog基本上都會設置為1,這表示在每次提交事務時將緩存中的binlog刷盤。所以,在事務提交前,gtid以及事務相關操作的信息都在緩存中,提交后它們才寫入到binlog file中,然后才會被dump線程dump出去。
換句話說,只有提交了的事務,gtid和對應的事務操作才會記錄到binlog文件中。記錄的格式是先記錄gtid,緊跟着再記錄事務相關的操作。
-
當binlog傳送到relay log中后,slave上的SQL線程首先讀取該gtid,並設置變量 gtid_next 的值為該gtid,表示下一個要操作的事務是該gtid。 gtid_next 是基於會話的,不同會話的gtid_next不同。
-
隨后slave檢測該gtid在自己的binlog中是否存在。如果存在,則放棄此gtid事務;如果不存在,則將此gtid寫入到自己的binlog中,然后立刻執行該事務,並在自己的binlog中記錄該事務相關的操作。
注意,slave上replay的時候,gtid不是提交后才寫到自己的binlog file的,而是判斷gtid不存在后立即寫入binlog file。
通過這種在執行事務前先檢查並寫gtid到binlog的機制,不僅可以保證當前會話在此之前沒有執行過該事務,還能保證沒有其他會話讀取了該gtid卻沒有提交。因為如果其他會話讀取了該gtid會立即寫入到binlog(不管是否已經開始執行事務),所以當前會話總能讀取到binlog中的該gtid,於是當前會話就會放棄該事務。總之,一個gtid事務是決不允許多次執行、多個會話並行執行的。
-
slave在重放relay log中的事務時,不會自己生成gtid,所以所有的slave(無論是何種方式的一主一從或一主多從復制架構)通過重放relay log中事務獲取的gtid都來源於master,並永久保存在slave上。
3.基於gtid復制的好處
從上面可以看出,gtid復制的優點大致有:
- 保證同一個事務在某slave上絕對只執行一次,沒有執行過的gtid事務總是會被執行。
- 不用像傳統復制那樣保證binlog的坐標准確,因為根本不需要binlog以及坐標。
- 故障轉移到新的master的時候很方便,簡化了很多任務。
- 很容易判斷master和slave的數據是否一致。只要master上提交的事務在slave上也提交了,那么一定是一致的。
當然,MySQL提供了選項可以控制跳過某些gtid事務,防止slave第一次啟動復制時執行master上的所有事務而導致耗時過久。
雖然對於row-based和statement-based的格式都能進行gtid復制,但建議采用row-based格式。
4.配置一主一從的gtid復制
環境:
主機IP | OS版本 | MySQL版本 | 角色(master/slave) | 數據狀態 |
---|---|---|---|---|
192.168.100.21 | centos 7 | MySQL 5.7.22 | master_gtid | 全新實例 |
192.168.100.22 | centos 7 | MySQL 5.7.22 | slave1_gtid | 全新實例 |
因為是用作master和slave的mysql實例都是全新環境,所以這里簡單配置一下即可。
master的配置文件:
[mysqld]
datadir=/data
socket=/data/mysql.sock
log-bin=/data/master-bin # 必須項
sync-binlog=1 # 建議項
binlog_format=row # 建議項
server-id=100 # 必須項
log-error=/data/error.log
pid-file=/data/mysqld.pid
enforce_gtid_consistency=on # gtid復制需要加上的必須項
gtid_mode=on # gtid復制需要加上的必須項
關於后面的兩項,是gtid復制所必須開啟的項,這里指定它開啟就行了,它們的意義以及更多gtid相關的選項見后文解釋。
slave的配置文件:
[mysqld]
datadir=/data
socket=/data/mysql.sock
log-bin=/data/master-slave-bin # mysql 5.6必須項,mysql 5.7非必須項
sync-binlog=1 # 建議項
binlog_format=row # 建議項
relay-log=/data/slave-bin # 必須項
server-id=110 # 必須項
log-error=/data/error.log
pid-file=/data/mysqld.pid
enforce_gtid_consistency=on # 必須項
gtid_mode=on # 必須項
我的環境是mysql 5.7,如果是mysql 5.6,那么在上面兩個配置文件中需要加上log-slave-updates
選項。
重啟master和slave后,在master上創建一個用於復制的用戶repl
。
# master上執行
mysql> grant replication slave on *.* to repl@'192.168.100.%' identified by 'P@ssword1!';
因為master上的binlog沒有刪除過,所以在slave上直接change master to
配置連接參數。
# slave上執行
mysql> change master to
master_host='192.168.100.21',
master_port=3306,
master_auto_position=1; # gtid復制必須設置此項
因為是MySQL 5.7,沒有在change master to
語句中加入user和password項,而是在start slave
語句中使用,否則會警告。
現在啟動slave上的兩個復制線程。
# slave上執行
mysql> start slave user='repl' password='P@ssword1!';
查看io線程和sql線程是否正常。
# slave上執行,為了排版,縮減了一些無關緊要的字段
mysql> show processlist;
+----+-------------+---------+--------------------------------------------------------+
| Id | User | Command | State |
+----+-------------+---------+--------------------------------------------------------+
| 9 | root | Query | starting |
| 10 | system user | Connect | Waiting for master to send event |
| 11 | system user | Connect | Slave has read all relay log; waiting for more updates |
+----+-------------+---------+--------------------------------------------------------+
最后驗證gtid復制是否生效。
在master上插入一些數據。這里使用上一篇文章中使用的存儲過程proc_num1
和proc_num2
分別向數值輔助表backup.num_isam
和backup.num_innodb
中插入一些數據,該存儲過程的代碼見:https://www.cnblogs.com/f-ck-need-u/p/9155003.html#blognum。
# 向MyISAM數值輔助表backup.num_isam插入100W行數據
call proc_num1(1000000);
# 向InnoDB數值輔助表backup.num_innodb插入100W行數據
call proc_num2(1000000);
在slave上查看slave的狀態,以下是同步結束后的狀態信息。
# slave上執行:
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.100.21
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000004
Read_Master_Log_Pos: 10057867
Relay_Log_File: slave-bin.000003
Relay_Log_Pos: 457
Relay_Master_Log_File: master-bin.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 10057867
Relay_Log_Space: 10058586
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 100
Master_UUID: a659234f-6aea-11e8-a361-000c29ed4cf4
Master_Info_File: /data/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: a659234f-6aea-11e8-a361-000c29ed4cf4:1-54
Executed_Gtid_Set: a659234f-6aea-11e8-a361-000c29ed4cf4:1-54
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
5.添加新的slave到gtid復制結構中
GTID復制是基於事務ID的,確切地說是binlog中的GTID,所以事務ID對GTID復制來說是命脈。
當master沒有刪除過任何binlog時,可以隨意地向復制結構中添加新的slave,因為slave會復制所有的binlog到自己relay log中並replay。這樣的操作盡管可能速度不佳,但勝在操作極其簡便。
當master刪除過一部分binlog后,在向復制結構中添加新的slave時,必須先獲取到master binlog中當前已記錄的第一個gtid之前的所有數據,然后恢復到slave上。只有slave上具有了這部分基准數據,才能保證和master的數據一致性。
而在實際環境中,往往會定期刪除一部分binlog。所以,為了配置更通用的gtid復制環境,這里把前文的master的binlog給purge掉一部分。
目前master上的binlog使用情況如下,不難發現絕大多數操作都集中在master-bin.000004
這個binlog中。
[root@xuexi ~]# ls -l /data/*bin*
-rw-r----- 1 mysql mysql 177 Jun 8 15:07 /data/master-bin.000001
-rw-r----- 1 mysql mysql 727 Jun 8 15:42 /data/master-bin.000002
-rw-r----- 1 mysql mysql 177 Jun 9 09:50 /data/master-bin.000003
-rw-r----- 1 mysql mysql 10057867 Jun 9 10:17 /data/master-bin.000004
-rw-r----- 1 mysql mysql 96 Jun 9 09:50 /data/master-bin.index
purge已有的binlog。
mysql> flush logs;
mysql> purge master logs to 'master-bin.000005';
[root@xuexi ~]# cat /data/master-bin.index
/data/master-bin.000005
但無論master是否purge過binlog,配置基於gtid的復制都極其方便,而且方法眾多(只要理解了GTID的生命周期,可以隨意折騰,基本上都能很輕松地維護好),這是它"迷人"的優點。
現在的測試環境是這樣的:
主機IP | OS版本 | MySQL版本 | 角色(master/slave) | 數據狀態 |
---|---|---|---|---|
192.168.100.21 | centos 7 | MySQL 5.7.22 | master_gtid | 已purge過binlog |
192.168.100.22 | centos 7 | MySQL 5.7.22 | slave1_gtid | 已同步 |
192.168.100.23 | centos 7 | MySQL 5.7.22 | slave2_gtid | 全新實例 |
其中slave2的配置文件和slave1的配置文件完全相同:
[mysqld]
datadir=/data
socket=/data/mysql.sock
log-bin=/data/master-slave-bin # 必須項
sync-binlog=1 # 建議項
binlog_format=row # 建議項
relay-log=/data/slave-bin # 必須項
server-id=110 # 必須項
log-error=/data/error.log
pid-file=/data/mysqld.pid
enforce_gtid_consistency=on # 必須項
gtid_mode=on # 必須項
1.備份master。
我選擇的是xtrabackup的innobackupex工具,因為它速度快,操作簡單,而且在線備份也比較安全。如果不知道xtrabackup備份的使用方法,見我的另一篇文章:xtrabackup用法和原理詳述。當然,你也可以采用mysqldump和冷備份的方式,因為gtid復制的特性,這些備份方式也都很安全。
# master上執行,備份所有數據:
[root@xuexi ~]# mkdir /backdir # 備份目錄
[root@xuexi ~]# innobackupex -uroot -pP@ssword1! -S /data/mysql.sock /backdir/ # 准備數據
[root@xuexi ~]# innobackupex --apply-log /backdir/2018-06-09_20-02-24/ # 應用數據
[root@xuexi ~]# scp -pr /backdir/2018-06-09_20-02-24/ 192.168.100.23:/tmp
2.將備份恢復到slave2。
在slave2上執行:
[root@xuexi ~]# systemctl stop mysqld
[root@xuexi ~]# rm -rf /data/* # 恢復前必須先清空數據目錄
[root@xuexi ~]# innobackupex --copy-back /tmp/2018-06-09_20-02-24/ # 恢復備份數據
[root@xuexi ~]# chown -R mysql.mysql /data
[root@xuexi ~]# systemctl start mysqld
3.設置gtid_purged,連接master,開啟復制功能。
由於xtrabackup備份數據集卻不備份binlog,所以必須先獲取此次備份結束時的最后一個事務ID,並在slave上明確指定跳過這些事務,否則slave會再次從master上復制這些binlog並執行,導致數據重復執行。
可以從slave2數據目錄中的xtrabackup_info
文件中獲取。如果不是xtrabackup備份的,那么可以直接從master的show global variables like "gtid_executed";
中獲取,它表示master中已執行過的事務。
[root@xuexi ~]# cat /data/xtrabackup_info
uuid = fc3de8c1-6bdc-11e8-832d-000c29ed4cf4
name =
tool_name = innobackupex
tool_command = -uroot -pP@ssword1! -S /data/mysql.sock /backdir/
tool_version = 2.4.11
ibbackup_version = 2.4.11
server_version = 5.7.22-log
start_time = 2018-06-09 20:02:28
end_time = 2018-06-09 20:02:30
lock_time = 0
binlog_pos = filename 'master-bin.000005', position '194', GTID of the last change 'a659234f-6aea-11e8-a361-000c29ed4cf4:1-54'
innodb_from_lsn = 0
innodb_to_lsn = 51235233
partial = N
incremental = N
format = file
compact = N
compressed = N
encrypted = N
其中binlog_pos
中的GTID對應的就是已備份的數據對應的事務。換句話說,這里的gtid集合1-54表示這54個事務不需要進行復制。
或者在master上直接查看executed的值,注意不是gtid_purged的值,master上的gtid_purged表示的是曾經刪除掉的binlog。
mysql> show global variables like '%gtid%';
+----------------------------------+-------------------------------------------+
| Variable_name | Value |
+----------------------------------+-------------------------------------------+
| binlog_gtid_simple_recovery | ON |
| enforce_gtid_consistency | ON |
| gtid_executed | a659234f-6aea-11e8-a361-000c29ed4cf4:1-54 |
| gtid_executed_compression_period | 1000 |
| gtid_mode | ON |
| gtid_owned | |
| gtid_purged | a659234f-6aea-11e8-a361-000c29ed4cf4:1-54 |
| session_track_gtids | OFF |
+----------------------------------+-------------------------------------------+
可以在啟動slave線程之前使用gtid_purged
變量來指定需要跳過的gtid集合。但因為要設置gtid_purged必須保證全局變量gtid_executed為空,所以先在slave上執行reset master
(注意,不是reset slave),再設置gtid_purged。
# slave2上執行:
mysql> reset master;
mysql> set @@global.gtid_purged='a659234f-6aea-11e8-a361-000c29ed4cf4:1-54';
設置好gtid_purged之后,就可以開啟復制線程了。
mysql> change master to
master_host='192.168.100.21',
master_port=3306,
master_auto_position=1;
mysql> start slave user='repl' password='P@ssword1!';
查看slave的狀態,看是否正確啟動了復制功能。如果沒錯,再在master上修改一部分數據,檢查是否同步到slave1和slave2。
4.回到master,purge掉已同步的binlog。
當slave指定gtid_purged並實現了同步之后,為了下次重啟mysqld實例不用再次設置gtid_purged(甚至可能會在啟動的時候自動開啟復制線程),所以應該去master上將已經同步的binlog給purged掉。
# master上執行:
mysql> flush logs; # flush之后滾動到新的日志master-bin.000006
# 在確保所有slave都復制完000006之前的所有事務后,purge掉舊日志
mysql> purge master logs to "master-bin.000006";
6.GTID復制相關的狀態信息和變量
6.1 show slave status
中和gtid復制相關的狀態行
Retrieved_Gtid_Set: a659234f-6aea-11e8-a361-000c29ed4cf4:1-54
Executed_Gtid_Set: a659234f-6aea-11e8-a361-000c29ed4cf4:1-54
Auto_Position: 1
其中:
Retrieved_Gtid_Set
:在開啟了gtid復制(即gtid_mode=on)時,slave在啟動io線程的時候會檢查自己的relay log,並從中檢索出gtid集合。也就是說,這代表的是slave已經從master中復制了哪些事務過來。檢索出來的gtid不會再請求master發送過來。Executed_Gtid_Set
:在開啟了gtid復制(即gtid_mode=on)時,它表示已經向自己的binlog中寫入了哪些gtid集合。注意,這個值是根據一些狀態信息計算出來的,並非binlog中能看到的那些。舉個特殊一點的例子,可能slave的binlog還是空的,但這里已經顯示一些已執行gtid集合了。Auto_Position
:開啟gtid時是否自動獲取binlog坐標。1表示開啟,這是gtid復制的默認值。
6.2 binlog中關於gtid的信息
例如:
[root@xuexi ~]# mysqlbinlog /data/master-bin.000007
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#180610 1:34:08 server id 100 end_log_pos 123 CRC32 0x4a6e9510 Start: binlog v 4, server v 5.7.22-log created 180610 1:34:08
# Warning: this binlog is either in use or was not closed properly.
BINLOG '
kA8cWw9kAAAAdwAAAHsAAAABAAQANS43LjIyLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
ARCVbko=
'/*!*/;
# at 123
#180610 1:34:08 server id 100 end_log_pos 194 CRC32 0x0f6ba409 Previous-GTIDs
# a659234f-6aea-11e8-a361-000c29ed4cf4:1-57 #### 注意行1
# at 194
#180610 2:06:31 server id 100 end_log_pos 259 CRC32 0xfef9194e GTID last_committed=0 sequence_number=1 rbr_only=no #### 注意行2
SET @@SESSION.GTID_NEXT= 'a659234f-6aea-11e8-a361-000c29ed4cf4:58'/*!*/; #### 注意行3
# at 259
#180610 2:06:31 server id 100 end_log_pos 359 CRC32 0x5a561d94 Query thread_id=2 exec_time=0 error_code=0
use `backup`/*!*/;
SET TIMESTAMP=1528567591/*!*/;
SET @@session.pseudo_thread_id=2/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1436549152/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
create table t1(n int)
/*!*/;
# at 359
#180610 2:09:36 server id 100 end_log_pos 424 CRC32 0x82564e69 GTID last_committed=1 sequence_number=2 rbr_only=no #### 注意行4
SET @@SESSION.GTID_NEXT= 'a659234f-6aea-11e8-a361-000c29ed4cf4:59'/*!*/; #### 注意行5
# at 424
#180610 2:09:36 server id 100 end_log_pos 524 CRC32 0xbc21683a Query thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1528567776/*!*/;
create table t2(n int)
/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/; #### 注意行6
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
其中:
- "注意行1"中
Previous-GTIDs
代表的gtid集合是曾經的gtid,換句話說是被purge掉的事務。 - "注意行2"和"注意行4"是兩個事務的gtid信息。它們寫在每個事務的前面。
- "注意行3"和"注意行5"設置了GTID_NEXT的值,表示讀取到了該事務后,那么必須要執行的是稍后列出的這個事務。
- "注意行6"是在所有事務執行結束時設置的,表示自動獲取gtid的值。它對復制是隱身的(也就是說不會dump線程不會將它dump出去),該行的結尾也說了,這一行是mysqlbinlog添加的。
6.3 一些重要的變量
gtid_mode
:是否開啟gtid復制模式。只允許on/off類的布爾值,不允許其他類型(如1/0)的布爾值,實際上這個變量是枚舉類型的。要設置 gtid_mode=on ,必須同時設置 enforce_gtid_consistency 開。在MySQL 5.6中,還必須開啟 log_slave_updates ,即使是master也要開啟。enforce_gtid_consistency
:強制要求只允許復制事務安全的事務。 gtid_mode=on 時必須顯式設置該項,如果不給定值,則默認為on。應該盡量將該選項放在 gtid_mode 的前面,減少啟動mysqld時的檢查。- 不能在事務內部創建和刪除臨時表。只能在事務外部進行,且autocommit需要設置為1。
- 不能執行 create table ... select 語句。該語句除了創建一張新表並填充一些數據,其他什么事也沒干。
- 不能在事務內既更新事務表又更新非事務表。
gtid_executed
:已經執行過的GTID。 reset master 會清空該項的全局變量值。gtid_purged
:已經purge掉的gtid。要設置該項,必須先保證 gtid_executed 已經為空,這意味着也一定會同時設置該項為空。在slave上設置該項時,表示稍后啟動io線程和SQL線程都跳過這些gtid,slave上設置時應該讓此項的gtid集合等於master上 gtid_executed 的值。gtid_next
:表示下一個要執行的gtid事務。
需要注意,master和slave上都有gtid_executed
和gtid_purged
,它們代表的意義有時候是不同的。
還有一些變量,可能用到的不會多。如有需要,可翻官方手冊。
6.4 mysql.gtid_executed表
MySQL 5.7中添加了一張記錄已執行gtid的表mysql.gtid_executed
,所以slave上的binlog不是必須開啟的。
mysql> select * from mysql.gtid_executed;
+--------------------------------------+----------------+--------------+
| source_uuid | interval_start | interval_end |
+--------------------------------------+----------------+--------------+
| a659234f-6aea-11e8-a361-000c29ed4cf4 | 1 | 57 |
| a659234f-6aea-11e8-a361-000c29ed4cf4 | 58 | 58 |
| a659234f-6aea-11e8-a361-000c29ed4cf4 | 59 | 59 |
+--------------------------------------+----------------+--------------+
7.一張圖說明GTID復制
在前面第6節中,使用了xtrabackup備份的方式提供gtid復制的基准數據。其中涉及到一些gtid檢查、設置的操作。通過這些操作,大概可以感受的到gtid復制的幾個概念。
用一張圖來說明:
假如當前master的gtid為A3,已經purge掉的gtid為"1-->A1",備份到slave上的數據為1-A2部分。
如果A1 = 0
,表示master的binlog沒有被Purge過。slave可以直接開啟gtid復制,但這樣可能速度較慢,因為slave要復制所有binlog。也可以將master數據備份到slave上,然后設置 gtid_purged 跳過備份結束時的gtid,這樣速度較快。
如果A1 != 0
,表示master上的binlog中刪除了一部分gtid。此時slave上必須先從master處恢復purge掉的那部分日志對應的數據。上圖中備份結束時的GTID為A2。然后slave開啟復制,唯一需要考慮的是"是否需要設置 gtid_purged 跳過一部分gtid以避免重復執行"。
備份數據到slave上,方式可以是mysqldump、冷備份、xtrabackup備份都行。由於gtid復制的特性,所需要的操作都很少,也很簡單,前提是理解了"gtid的生命周期"。
!!!!!
狀態不佳,寫的有點亂。不過寫都寫了,還是發出來吧。