Gtid的核心就是給每個事務分配一個惟一的id,根據這個ID就知道這個事務是在哪個節點執行。鑑於它有上述的特色,可讓主從方便的作failover,集羣能夠經過gtid作衝突檢查,由於每個事務都有標記,dba在作集羣遷移的時候也更加的方便。每執行一個事務,當前執行線程都會拿到一個惟一的(整個集羣環境惟一)的事務標識符 格式:GTID=server_uuid:seq_id server_uuid其實是一個32字節+1個字節的」/0」的字符串,在mysql啓動的時候會自動去讀datadir中的auto.cnf文件,若是沒沒有找到就自動建立一個。seq_id是給事務分配的一個序列號。 在GTID中,同一個gtid對應的事務只能被執行一次,這個和基於傳統模式複製的GTID不同,在傳統模式的複製中可能會由於指定了錯誤position和logfile致使事務被重複執行。 Gtid是在事務commit階段調用mysql_binlog:orderd_commit生成的。最終gtid會被寫入到binlog中,注意,如今生成的是下一個事務的gtid(gtid_next)。mysql
之因此須要進行GTID的持久化工做是由於gtid_executed等這些變量都是在內存中的,在數據庫重啓以後須要肯定哪些GTID是執行過的,哪些GTID是沒有執行過的。在5.7.6以前版本的數據庫中,只能經過binlog來進行持久化,一個事務在寫入binlog以前先重gtid_next中獲取這個事務的gtid寫入到binlog中,而後在進行事務的寫入,在事務的commit階段生成gtid_next的值。鑑於上訴機制,在5.7.5如下的版本中,slave端必需要開啓log_slave_updates才能夠。 對於5.7.6以上的版本中,引入了mysql.gtid_executed這個表來進行gtid的持久化,全部執行過的gtid都會被記錄在該表中。經過gtid_executed_compression_period參數去設置執行多個個事務壓縮該表一次。git
gtid_owned,保存了服務器上正在實行的GTID事務列表以及擁有他們(負責執行)的server_id。主要用於多線程複製,在應用線程處理gtid事務的時候會一直擁有該事務的gtid,因此說當gtid_owned有值的時候說明當前應用線程正在應用gtid事務,在事務commit或者回滾以後就會釋放。 gtid_executed,哪些gtid事務被執行了,信息是放在內存中。 gtid_purged,因爲binlog被刪除或者expire所致使的gtid信息丟失,對於主庫來講該變量表示再也不當前binlog中的gtid集合,對於備庫來講該變量表示已經執行過的gtid,因此若是使用mysqldump來初始化一個開啓了gtid備庫的時候要特別注意在start slave以前須要先reset master而後在設置GTID_PURGED變量。sql
關於gtid_executed修改的時間,對於主庫來講,在binlog關閉的時候,gtid_executed、gtid_purged、mysql.gtid_executed都不會更新,也不能開啓。在binlog開啓的時候,在binlog發生rotate的時候更新gtid_executed信息,這個時候mysql.executed表不是實時更新的,可是gtid_executed變量是實時更新的。關於gtid_executed變量的更新,在ordered_commit flush階段產生gtid,因此gtid_executed是實時更新的。關於gtid_purge變量的更新時間,在purge binlog或者超過expire時間的時候會更新gtid_purge信息。 對於從庫來講,在沒有開啓log_slave_updates的狀況下,無論有沒有啓用binlog結果都是gtid_executed實時更新,gtid_executed變量的值是實時更新的。關於gtid_purge變量的更新,由於沒有binlog記錄,全部gtid_purged的值是實時更新的,binlog開啓同時log_slave_updates開啓的狀況下,由於有binlog event記錄gtid,mysql.executed不須要實時更新,它更新的狀況和主庫是同樣的,只是在binlog發生切換的時候或者超過expire的時候更新。 對於mysql.gtid_executed來講,在reset master的時候會清空這個表,在set global gitd_purged的時候,設置本表,同時主庫發生日誌輪轉的時候也會修改本表。數據庫
一、確認事務的內容是能夠跳過的 二、stop slave 三、設置gtid_next='master_uuid:xxx'; 四、註冊空事務 五、設置gtid_next爲automatic 六、啓動slave 在gtid_executed中,若是slave本身作了寫入,那麼也會記錄在gtid_executed中,格式爲slave_uuid:xxx服務器
##轉換多線程
一、在全部節點上面修改enforce_gtid_consistency=warn,在設置了這個參數以後,當存在違法gtid一致性的event時候就會報錯 SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN; 設置完成以後運行一段時間,確認無任何報錯以後能夠繼續進行下一步,若是有報錯須要修改應用 二、在確認無告警以後 SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = ON;性能
三、設置gtid_mode 在哪一個服務器上面先執行這個是可有可無的 SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE; 設置了以後表示新事務是匿名的,同時運行復制時使用gtid或者匿名事務 四、設置gtid_mode=ON_PERMISSIVE; SET global gtid_mode=ON_PERMISSIVE; 先在哪一個服務器上面執行沒有關係,設置了以後表示新事務是gtid事務,同時容許複製時候使用gtid或者匿名事務。 五、確認匿名事務爲0,全部節點 SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT'; 有的時候可能發現這個值爲0或者不爲0,可是沒有關係,只要有一次爲0就能夠了 必需要確認全部匿名事務均已經複製完成才能繼續,建議經過上述命令方式+binlog的方式,由於若是下一步執行了gtid_mode=on,那麼那些未有複製的匿名事務就不能複製了。 六、開啓gtid,而且寫入到my.cnf文件 SET @@GLOBAL.GTID_MODE = ON;ui
一、記錄複製的位置以後中止io sql線程 mh01@3307>stop slave io_thread; 查看slave狀態確認,確認數據已經所有同步 Exec_Master_Log_Pos: 47477668 Read_Master_Log_Pos: 47477668 二、change master操做 mh01@3307>change master to master_auto_position=0,master_log_file='mh01-3306.000017',master_log_pos=47477668; 三、在每一臺服務器上面設置gtid爲on_permissive模式 set global gtid_mode=on_permissive; 四、在每一臺服務器上面設置gtid爲off_permissive模式 set global gtid_mode=off_permissive;
5 五、等待全部gtid_owned爲空,爲空表示已經沒有gtid事務正在被執行。 select @@global.gtid_owned;線程
七、等待全部匿名事務完成 show global status like 'ONGOING_ANONYMOUS_TRANSACTION_COUNT'; 注意,有的時候會顯示0或者非0,可是沒有關係,在前面的步驟完成後只要有一次顯示0就能夠了。 八、關閉gtid set global gtid_mode=off; 重要的是要了解包含GTID事務的日誌在下一步以後沒法使用。 在繼續以前,您必須確保拓撲中的任何位置都不存在GTID事務。 九、寫入配置到my.cnf文件日誌
##其餘
該參數用於定義是否支持快速gtid掃描,5.7.5以前胃false,以後爲true,如今討論什麼狀況下可能發生binlog全掃描的問題。 注意的問題:在gtid關閉,simplified_binlog_gtid_recovery=false的狀況下,無論什麼版本在重啓的時候都須要進行binlog的全掃描。在binlog被刪除或者被purge的狀況下,5.7.6以後的數據庫也須要進行binlog的全掃描,可是這個版本以前的就不須要了,由於這個版本以前的數據庫不支持在線修改gtid狀態。另外,若是simplified_binlog_gtid_recovery=true,那麼在舊版本的數據庫中可能不能獲取正確的gtid值。 在5.7.6以上的數據庫中,simplified_binlog_gtid_recovery=true是最好的選擇。由於在獲取gtid值的時候只須要掃描最新和最舊的binlog就能夠了,性能很好。5.7.6如下版本的數據庫中通常不會使用gtid來切換數據庫。由於沒有mysql.executed的支持,必需要開啓log_slave_updates,會帶來性能上面的影響。