MySQL5.7配置GTID主從---GTID介紹


一、什么是 GTID
GTID (Global Transaction Identifiers)是對於一個已提交事務的編號,事務的唯一編號,並且是一個全局唯一的編號。GTID 和事務會記錄到 binlog 中,用來標識事務。
GTID 是用來替代以前 classic 復制方法,MySQL-5.6.2 開始支持 GTID,在 MySQL-5.6.10 后完善。
有了 GTID,一個事務在集群中就不再孤單,在每一個節點中,都存在具有相同標識符的兄弟們和它作伴,可以避免同一個事務,在同一個節點中出現多次的情況。
GTID 的出現,最直接的效果就是,每一個事務在集群中具有了唯一性的意義,這在運維方面具有更大的意義,因為使用 GTID 后再也不需要為了不斷地找點而煩惱了,給 DBA 帶來了很大的便利性。

GTID 組成:
GTID 是由 server_uuid:Sequence_Number 。
Server_Uuid:是一個 MySQL 實例的全局唯一標識;存放為在$datadir/auto.cnf
Sequence_Number:是 MySQL 內部的一個事務的編號,一個 MySQL 實例不會重復的序列號(保證服務器內唯一),也表示在該實例上已經提交事務的數量,並且隨着事務提交而遞增。
根據 GTID 可以知道事務最初是在哪個實例上提交的,方便故障排查和切換

cat /data/mysql/data/auto.cnf
[auto]
server-uuid=b3f31135-4851-11e8-b758-000c29148b03


二、GTID 主從復制原理

(1) 當一個事務在主庫端執行並提交時,產生 GTID,一同記錄到 binlog 日志中。
(2) binlog 傳輸到 slave,並存儲到 slave 的 relaylog 后,讀取這個 GTID 的這個值設置 gtid_next 變量,即告訴 Slave,下一個要執行的 GTID 值。
(3) sql 線程從 relay log 中獲取 GTID,然后對比 slave 端的 binlog 是否有該 GTID。
(4) 如果有記錄,說明該 GTID 的事務已經執行,slave 會忽略。
(5) 如果沒有記錄,slave 就會執行該 GTID 事務,並記錄該 GTID 到自身的 binlog;
(6) 在解析過程中會判斷是否有主鍵,如果沒有就用二級索引,如果沒有就用全部掃描。

 

三、GTID 優勢和限制

GTID 的優勢:
(1) 根據 GTID 可以快速的確定事務最初是在哪個實例上提交的。
(2) 簡單的實現 failover,不用以前那樣在需要找 log_file 和 log_pos。
(3) 更簡單的搭建主從復制,確保每個事務只會被執行一次。
(4) 比傳統的復制更加安全。
(5) GTID 的引入,讓每一個事務在集群事務的海洋中有了秩序,使得 DBA 在運維中做集群變遷時更加方便,能夠做到胸有成竹心中有數。

GTID 的限制:
因為基於 GTID 的復制依賴於事務,所以在使用 GTID 時,有些 MySQL 特性是不支持的。
(1) 不允許在一個 SQL 同時更新一個事務引擎和非事務引擎的表;
事務中混合多個存儲引擎,就會產生多個 GTID。當使用 GTID 時,如果在同一個事務中,更新包括了非事務引擎(如 MyISAM)和事務引擎(如 InnoDB)表的操作,就會導致多個 GTID 分配給了同一個事務。
(2) 主從庫的表存儲引擎必須是一致的;
主從庫的表存儲引擎不一致,就會導致數據不一致。如果主從庫的存儲引擎不一致,例如一個是事務存儲引擎,一個是非事務存儲引擎,則會導致事務和 GTID 之間一對一的關系被破壞,結果就會導致基於 GTID 的復制不能正確運行;
(3) 不支持 create table … select 語句復制(主庫直接報錯)
由於使用基於行模式的復制時,create table ...select 語句會被記錄為兩個單獨的事件(會生成兩個 sql),一個是 DDL 創建表 SQL,一個是 insert into 插入數據的 SQL。由於 DDL 會導致自動提交,所以這個 sql 至少需要兩個 GTID,但是 GTID 模式下,只能給這個 sql 生成一個 GTID,如果強制執行會導致和上面(2)中一樣的結果。
(4) 在一個復制組中,必須要求統一開啟 GTID 或是關閉 GTID;
(5) 開啟 GTID 需要重啟(5.6 需要,5.7 中不需要)
(6) 開啟 GTID 后,就不能在使用原來的傳統的復制方式;
(7) 不支持 create temporary table 和 drop temporary table 語句;
使用 GTID 復制時,不支持 create temporary table 和 drop temporary table ,但是在 autocommit=1 情況下可以創建臨時表,MASTER 創建臨時表不產生 GTID 信息,所以不會同步到 SLAVE 上,但是刪除臨時表時,產生 GTID 會導致主從復制中斷。
(8) 不推薦在 GTID 模式的實例上進行 mysql_upgrade;
因為 mysql_upgrade 的過程要創建或修改系統表(非事務引擎),所以不建議在開啟 GTID 的模式的實例上使用帶有--write-binlog 選項的 mysql_upgrade;
(9) 不支持 sql_slave_skip_counter;

 

四、為什么要使用 GTID

比如以下M-S結構

S1→M←S2,當M宕機的時候,其中一台S就必須承擔起M的責任,但是由於2台S之間沒有關系,很難使S2成為S1的slave。

GTID 的存在方便了 Replication 的 Failover在 MySQL 5.6 GTID 出現之前 Replication failover 的操作過程:修改復制源的命令語法為:

mysql> CHANGE MASTER TO MASTER_HOST='XXXX', MASTER_USER='XXXX', MASTER_PASSWORD='XXXXX', MASTER_LOG_FILE='XXXXX', MASTER_LOG_POS=XXXXX;

而比較麻煩的地方是:由於同一個事務在每台服務器上所在的 binlog 名字和 Postion 位置點都不一樣,那么怎么找到 slave2 當前同步停止點,對應 New Master 的 master_log_file 和 Master_log_pos 是什么的時候就成為了難題。這也就是為什么 M-S 復制集群需要使用 MMM,MHA 這樣的額外管理工具的一個重要原因。

其實也可以找到,只是比較麻煩,我們都知道主從復制環境中 master 的 binlog 復制到 slave 上后 事務執行時的時間戳是不變的,所有 slave 上同一個事務的時間戳都是相同的。可以根據這個時間戳定位到 Master_log_file 和 Master_log_pos。只是很費時間;麻煩。。。

GTID 出現之后:
在 MySQL 5.6 的 GTID 出現之后,處理這個問題就非常簡單了。
由於同一個事務的 GTID 在所有的節點上都是一致的,那么根據 Slave 當前停止點的 GTID 就能唯一定位到 New Master 的 GTID。
更簡單的是,由於 MASTER_AUTO_POSITION 功能的出現,我們都不需要知道 GTID 的具體值。直接使用

mysql> CHANGE MASTER TO MASTER_HOST='XXXX', MASTER_USER='XXXXX', MASTER_PASSWORD='XXXXX', MASTER_PORT=3306, MASTER_AUTO_POSITION=1;

命令就可以直接完成 failover 的工作了。使用 GTID 處理這個問題就簡單很多。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM