1. 程式人生 > >4:GTID簡單介紹

4:GTID簡單介紹

一次 資料 初使用 環境 如果 execute 表達 解決 gtid

  • 概述:
  • 當使用GTIDs時,可以識別和跟蹤每一個事務,因為它是在原始服務器上提交的,並由任何slave應用;簡單來說就是master提交的所有事務都在slaves應用一次,兩者的數據就能保證一致性,此外,同一GTID的事務只能在同一服務器上面提交一次。
  • 格式:
    • GTID表示為一對坐標,由冒號分隔(:)
    • GTID = source_id:transaction_id
    • source_id標識原始服務器.通常,服務器的server_uuid用於此目的。transaction_id是一個序列號,由在該服務器上提交事務的順序決定;例如,要提交的第一個事務的transaction_id為1,而在同一個源服務器上提交的第十個事務的transaction_id為10。事務不可能將0作為GTID中的序列號。例如,在最初使用UUID 3E11FA47-71CA-11E1-9E33-C80AA9429562的服務器上提交的第23個事務具有以下GTID:
      3E11FA47-71CA-11E1-9E33-C80AA9429562:23
    • 如在SHOW MASTER STATUS或SHOW SLAVE STATUS等語句的輸出中所寫,來自同一服務器的一系列GTID可以折疊成單個表達式,如此處所示
      3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5
      剛剛顯示的示例表示源自MySQL服務器的第一到第五個事務,其server_uuid是3E11FA47-71CA-11E1-9E33-C80AA9429562。
  • 生命周期:
    1. 事務在master上執行並提交。此客戶端事務被分配一個GTID,該GTID由master的UUID和此服務器上尚未使用的最小非零事務序列號組成。GTID被寫入master的二進制日誌(緊接在日誌中的事務本身之前)。如果未將客戶端事務寫入二進制日誌(例如,因為事務已被過濾掉,或者事務是只讀的),則不會為其分配GTID
    2. 如果為事務分配了GTID,則在提交時通過將其寫入事務開始時的二進制日誌(作為Gtid_log_event)以原子方式持久化GTID。無論何時旋轉二進制日誌或關閉服務器,服務器都會將寫入先前二進制日誌文件的所有事務的GTID寫入mysql.gtid_executed表。
    3. 如果為事務分配了GTID,則通過將GTID添加到gtid_executed系統變量(@@GLOBAL.gtid_executed)中的GTIDs集,以非原子方式外部化GTID(在提交事務之後不久)。此GTID集包含所有已提交的GTID事務集的表示形式,並在復制中用作表示服務器狀態的標記。啟用二進制日誌記錄(根據master的要求),gtid_executed系統變量中的GTID集是應用事務的完整記錄,但mysql.gtid_executed表不是,因為最新的歷史記錄仍在當前二進制日誌文件中
    4. 將二進制日誌數據傳輸到slave並存儲在slave的中繼日誌中,然後slave讀取GTID並將其gtid_next系統變量的值設置為此GTID。這告訴slave必須使用此GTID記錄下一個事務。值得註意的是,slave在會話上下文中設置了gtid_next。
    5. slave驗證沒有線程在gtid_next中獲得GTID的所有權以便處理事務。通過首先讀取和檢查復制事務的GTID,在處理事務本身之前,slave不僅保證在slave上沒有應用具有此GTID的先前事務,而且還保證沒有其他會話已經讀取此GTID但尚未提交的相關事務。因此,如果多個客戶端嘗試同時應用同一事務,則服務器只允許其中一個執行,從而解決此問題。slave的gtid_owned系統變量(@@ GLOBAL.gtid_owned)顯示當前正在使用的每個GTID以及擁有它的線程的ID。如果已經使用了GTID,則不會引發錯誤,並且使用自動跳過功能來忽略該事務。
    6. 如果尚未使用GTID,則slave應用復制的事務。由於gtid_next設置為master已分配的GTID,因此slave不會嘗試為此事務生成新的GTID,而是使用存儲在gtid_next中的GTID。
    7. 如果在slave上啟用了二進制日誌記錄,那麽GTID將在提交時以原子方式持久化,方法是在事務開始時將其寫入二進制日誌(作為Gtid_log_event)。無論何時旋轉二進制日誌或關閉服務器,服務器都會將寫入先前二進制日誌文件的所有事務的GTID寫入mysql.gtid_executed表。
    8. 如果在slave上禁用二進制日誌記錄,則通過將GTID直接寫入mysql.gtid_executed表來原子性地保留GTID。MySQL向事務添加一條語句,將GTID插入到表中。在這種情況下,mysql.gtid_executed表是slave上應用的事務的完整記錄。請註意,在MySQL 5.7中,將GTID插入表中的操作對於DML語句是原子操作,但對於DDL語句則不是,因此如果服務器在涉及DDL語句的事務之後意外退出,則GTID狀態可能會變得不一致。從MySQL 8.0開始,DDL語句和DML語句的操作都是原子操作。
    9. 在slave上提交復制事務之後不久,通過將GTID添加到slave的gtid_executed系統變量(@@ global.gtid_execute)中的GTIDs集合中,以非原子方式外部化GTID。對於master,這個GTID集合包含所有已提交GTID事務的集合的表示。如果在slave上禁用二進制日誌記錄,則mysql.gtid_executed表也是在slave上應用的事務的完整記錄。如果在slave上啟用了二進制日誌記錄,則意味著某些GTIDs僅記錄在二進制日誌中,gtid_executed系統變量中的GTIDs集是唯一的完整記錄。
  • 參考資料:https://dev.mysql.com/doc/refman/5.7/en/replication-gtids.html

    PREV: 3:添加一個slave到已有的復制環境(基於二進制日誌文件位置) http://blog.51cto.com/itzhoujun/2351567

    4:GTID簡單介紹