深刻MySQL複製(二):基於GTID複製

相比傳統的MySQL複製,gtid複製不管是配置仍是維護都要輕鬆的多。本文對gtid複製稍做介紹。html

MySQL基於GTID複製官方手冊:https://dev.mysql.com/doc/refman/5.7/en/replication-gtids.htmlmysql

1.gtid基本概念

傳統的基於binlog position複製的方式有個嚴重的缺點:若是slave鏈接master時指定的binlog文件錯誤或者position錯誤,會形成遺漏或者重複,不少時候先後數據是有依賴性的,這樣就會出錯而致使數據不一致。sql

從MYSQL5.6開始,mysql開始支持GTID複製。GTID的全稱是global transaction id,表示的是全局事務ID。GTID的分配方式爲uuid:trans_id,其中:centos

  • 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上的生命週期以下:服務器

  1. 客戶端發送DDL/DML給master上,master首先對此事務生成一個惟一的gtid,假如爲uuid_xxx:1,而後當即執行該事務中的操做。session

    注意,主從複製的狀況下,sync-binlog基本上都會設置爲1,這表示在每次提交事務時將緩存中的binlog刷盤。因此,在事務提交前,gtid以及事務相關操做的信息都在緩存中,提交後它們才寫入到binlog file中,而後纔會被dump線程dump出去。架構

    換句話說,只有提交了的事務,gtid和對應的事務操做纔會記錄到binlog文件中。記錄的格式是先記錄gtid,緊跟着再記錄事務相關的操做。app

  2. 當binlog傳送到relay log中後,slave上的SQL線程首先讀取該gtid,並設置變量 gtid_next 的值爲該gtid,表示下一個要操做的事務是該gtid。 gtid_next 是基於會話的,不一樣會話的gtid_next不一樣。

  3. 隨後slave檢測該gtid在本身的binlog中是否存在。若是存在,則放棄此gtid事務;若是不存在,則將此gtid寫入到本身的binlog中,而後馬上執行該事務,並在本身的binlog中記錄該事務相關的操做。

    注意,slave上replay的時候,gtid不是提交後才寫到本身的binlog file的,而是判斷gtid不存在後當即寫入binlog file。

    經過這種在執行事務前先檢查並寫gtid到binlog的機制,不只能夠保證當前會話在此以前沒有執行過該事務,還能保證沒有其餘會話讀取了該gtid卻沒有提交。由於若是其餘會話讀取了該gtid會當即寫入到binlog(不論是否已經開始執行事務),因此當前會話總能讀取到binlog中的該gtid,因而當前會話就會放棄該事務。總之,一個gtid事務是決不容許屢次執行、多個會話並行執行的。

  4. slave在重放relay log中的事務時,不會本身生成gtid,因此全部的slave(不管是何種方式的一主一從或一主多從複製架構)經過重放relay log中事務獲取的gtid都來源於master,並永久保存在slave上。

3.基於gtid複製的好處

從上面能夠看出,gtid複製的優勢大體有:

  1. 保證同一個事務在某slave上絕對只執行一次,沒有執行過的gtid事務老是會被執行。
  2. 不用像傳統複製那樣保證binlog的座標準確,由於根本不須要binlog以及座標。
  3. 故障轉移到新的master的時候很方便,簡化了不少任務。
  4. 很容易判斷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_num1proc_num2分別向數值輔助表backup.num_isambackup.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_executedgtid_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的生命週期"。

!!!!! 狀態不佳,寫的有點亂。不過寫都寫了,仍是發出來吧。

相關文章
相關標籤/搜索