MySQL gtid的具體使用
1. 什么是GTID
從MySQL 5.6.5 開始新增了一種基于 GTID 的復制方式。GTID (Global Transaction ID)是全局事務ID,由主庫上生成的與事務綁定的唯一標識,這個標識不僅在主庫上是唯一的,在MySQL復制環(huán)境內(nèi)也是唯一的。
2. GTID格式及含義
GTID = source_uuid:transaction_id
source_uuid是發(fā)起事務服務器的server_uuid,是一個MySQL實例的唯一標識,可以通過show variables like 'server_uuid'
查看。transaction_id代表了該實例上已經(jīng)提交的事務數(shù)量,是一個單調遞增的序列號,從1開始,1-2代表第二個事務;第1-n代表n個事務。
GTID復制拓撲中,無論事務被復制了多少次,事務的GTID都保持不變。一旦某個事務在服務器上提交后,后續(xù)所有相同GTID的事務都會被忽略,這種機制可以有效避免重復復制的現(xiàn)象,保持數(shù)據(jù)一致。
示例1:7a7f2A47-71CA-11E1-9E33-00163e429562:1
含義: 7a7f2A47-71CA-11E1-9E33-00163e429562 是這個節(jié)點的server_uuid,1為這個節(jié)點上提交的第1個事務的事務號,如果提交了10個事務,GTID會是: 7a7f2A47-71CA-11E1-9E33-00163e429562:1-10
【如果有多個范圍要表示,則事務編號的范圍可以用冒號分隔】
示例2:7a7f2A47-71CA-11E1-9E33-00163e429562:1-3:11:47-49
含義:執(zhí)行了源自7a7f2A47-71CA-11E1-9E33-00163e429562服務器的第1-3個事務、第11個事務、第47-49個事務
【GTID集還能表示來自不同數(shù)據(jù)源的事務集】
示例3:7a7f2A47-71CA-11E1-9E33-00163e429562:1-77439,82b6d927-81cc-11ee-9edf-00163e202091:1-98191
含義:執(zhí)行了源自7a7f2A47-71CA-11E1-9E33-00163e429562服務器的第1-77439個事務和源自82b6d927-81cc-11ee-9edf-00163e202091服務器的第1-98191個事務
MySQL 8.3 創(chuàng)新版于 2024 年 1 月 16 號發(fā)布,該版本擴展了 MySQL
復制和組復制中使用全局事務標識(GTID)的格式,支持給 GTID 打標簽,以支持識別事務組。此增強功能可以為特定事務組的 GTID
分配唯一標識。例如:包含數(shù)據(jù)操作的事務可以很容易地與管理操作產(chǎn)生的事務區(qū)分開來,只需要比較他們的 GTID。
帶標簽的格式擴展后的 GTID 格式是 source_id:<tag>:transaction_id
,其中 tag 是最長為 8 個字符的任意字符串。通過設置系統(tǒng)變量 gtid_next 的值為 automatic: 啟用,或者設置 gtid_next 為 uuid::transaction_id 以將單個事務的 uuid 設置為任意值,并為其分配自定義標簽。
3. GTID相關參數(shù)
查看關于gtid的系統(tǒng)參數(shù):
mysql> show variables like '%gtid%'; +-----------------------------------+-----------------------------------------------+ | Variable_name | Value | +-----------------------------------+-----------------------------------------------+ | binlog_gtid_simple_recovery | ON | | enforce_gtid_consistency | ON | | gtid_executed | be423c64-90c8-11ed-bf93-00163e0fcdea:1-1169392| | gtid_executed_compression_period | 1000 | | gtid_mode | ON | | gtid_next | AUTOMATIC | | gtid_owned | | | gtid_purged | be423c64-90c8-11ed-bf93-00163e0fcdea:1-1137671| | session_track_gtids | OFF | +-----------------------------------+-----------------------------------------------+ 9 row in set (0.00 sec)
3.1 gtid_mode
【作用】控制是否開啟GTID模式的日志記錄及日志內(nèi)可以包含的事務類型
【可選值】
OFF
:禁用GTID主從復制,新增和復制的事務都必須是匿名事務。ON
:啟用GTID主從復制,但不會自動創(chuàng)建GTID集。新增和復制的事務都必須是GTID事務。ON_PERMISSIVE
:啟用GTID主從復制,并允許從庫自動創(chuàng)建GTID集。新增的事務是GTID事務,復制的事務可以是匿名事務或GTID事務。(這個選項在標準的MySQL版本中并不直接支持)ON_ENFORCING
:啟用GTID主從復制,并要求從庫手動創(chuàng)建GTID集。
3.2 enforce_gtid_consistency
【作用】指定從庫執(zhí)行事務時的一致性要求,控制SQL語句是否僅允許違反GTID一致性
【可選值】
- OFF:不要求從庫執(zhí)行事務時的一致性要求。
- ON:要求從庫執(zhí)行事務時的一致性要求。(通常設置為ON以確保一致性)
- WARN:允許違反GTID一致性,但是會生成告警信息。
開啟該參數(shù)服務器僅允許GTID安全的語句執(zhí)行,防止某些不安全的語句導致GTID復制失敗。在啟用GTID模式復制前,必須設置為true。當設置為true以后,以下操作將不再可用:
- create table … select語句(MySQL8.0.21后,如果引擎支持原子DDL,可以使用此語句)。
- 事務內(nèi)的create temporary table和drop temporary table。
- 同時更新事務表和非事務表的事務或語句。
enforce_gtid_consistency驗證語句的GTID兼容性是在寫二進制日志的時候,如果在服務器上禁用了二進制日志或過濾器刪除了語句而未寫入二進制日志,都不會檢查。
3.3 gtid_executed
全局變量(@@global.gtid_executed
),包含服務器執(zhí)行的所有事務的GTID集和gtid_purged被設置的變量。@@global.gtid_executed
和show master status
或show slave status
語句輸出executed_gtid_set
字段的值相同。
當服務器啟動時,會根據(jù)binlog_gtid_simple_reocovery
參數(shù)選擇不同的方法初始化其值。
3.4 gtid_next
gtid_next
是會話級變量,代表下一個事務即將分配的GTID。當事務在主庫提交時,系統(tǒng)會自動分配一個新的GTID,當事務復制到從庫時,會保留主庫分配的GTID,而不是由從庫分配新的GTID。GTID可以設置為下列值:
automatic
:系統(tǒng)為事務自動生成GTIDanonymous
:事務沒有GTID(匿名事務),只能通過文件名和偏移量定位UUID:NUMBER
:明確設定一個有效的GTID,下一個事務將分配這個GTID。
此參數(shù)的功能還受到gtid_mode
參數(shù)的影響,如果gtid_mode
設置為OFF
(只有匿名事務),那么此參數(shù)無效。
【注意】如果用SERVER_UUID:TRANSACTION_NUMBER
手動為事務分配了GTID,無論事務提交或回滾,在開啟下一個事務前,必須再次手動設置gtid_next
的值或設置為automatic
。
3.5 gtid_purged
gtid_purged
是全局變量,代表所有在服務器上已提交,但是不在二進制日志中的事務的GTID集。gtid_purged
是gtid_exeucted
的子集。
gtid_purged中的GTID包含下列類別:
- 從庫禁用binarylog,則提交后的事務GTID也會加入gtid_purged。
- 從庫啟用binarylog,事務也寫入二進制日志,但是日志文件被purged(刪除)掉了。
- 通過
set @@global.gtid_purged
語句顯示加入到集合中。
gtid_purged
和gtid_executed
一樣,會在服務器啟動或重啟時根據(jù)binlog_gtid_simple_reocovery
參數(shù)選擇不同的方法初始化其值。
如果要求過濾某些事務,可以手動設置gtid_purged值,這些值會被加入gtid_executed,即使這些事務從未執(zhí)行。
gtid_purged設置方式有2種:
SET @@global.gtid_purged = 'gtid_set'
– 替換SET @@global.gtid_purged = '+gtid_set'
– 追加
binlog_gtid_simple_reocovery
控制MySQL啟動或重啟時如何檢索二進制日志來計算gtid_executed
和gtid_purged
變量的初始值。當binlog_gtid_simple_recovery=true
時,只讀取最舊和最新的binlog文件,否則遍歷所有binlog文件。
3.6 gtid_owned
表示當前正在執(zhí)行的事務的gtid。全局或會話級只讀變量,通常只內(nèi)部使用(其輸出可能對于普通用戶來說不是非常直觀),幫助MySQL管理和跟蹤當前正在處理的事務。
- 全局級:包含服務器正在使用的所有GTID列表和對應的Thread ID。
- 會話級:包含會話當前正在使用的單個GTID。
由于它是全局和會話級別的,其顯示的內(nèi)容可能會根據(jù)當前的會話和全局狀態(tài)而有所不同。
3.7 gtid_executed_compression_period
控制壓縮mysql.gtid_executed
表的事務閾值數(shù)量。
mysql> show variables like 'gtid_executed_compression_period'; +-----------------------------------+---------+ | Variable_name | Value | +-----------------------------------+---------+ | gtid_executed_compression_period | 1000 | +-----------------------------------+---------+ 1 row in set (0.00 sec)
該參數(shù)默認值為1000,指在每執(zhí)行1000次事務后執(zhí)行gtid_executed表的壓縮,方法是將source_id一樣的事務進行合并(僅二進制日志未開啟時生效)。二進制日志開啟時,此參數(shù)無效,只有在二進制日志輪換時才進行壓縮。
3.8 binlog_gtid_simple_recovery
binlog_gtid_simple_recovery
是MySQL中一個重要的系統(tǒng)變量,它用于控制在MySQL啟動或重啟時,如何遍歷二進制日志文件(binlog)以尋找全局事務標識符(GTID)。這個變量對于使用GTID進行復制的環(huán)境尤為重要,因為它影響了MySQL如何初始化和驗證GTID集合。
【版本引入】在MySQL 5.7.5版本中,這個變量以simplified_binlog_gtid_recovery
的形式被引入;從MySQL 5.7.6版本開始,它被重命名為binlog_gtid_simple_recovery
。
- 當
binlog_gtid_simple_recovery=FALSE
時:
gtid_executed
的初始化:MySQL會從最新的binlog文件開始,逆向遍歷到第一個包含Previous_gtids_log_event
或Gtid_log_event
的文件。從該文件中讀取所有的GTID,并存儲在內(nèi)部變量中,然后計算gtid_executed
的值。gtid_purged
的初始化:MySQL會從最早的binlog文件開始,正向遍歷到第一個包含非空的Previous_gtids_log_event
或至少一個Gtid_log_event
的文件。根據(jù)這些事件計算gtid_purged
的值。- 【性能影響】:如果binlog文件數(shù)量很大且沒有GTID事件,這個過程可能會非常耗時。
- 當
binlog_gtid_simple_recovery=TRUE
時(MySQL 5.7.7及以后版本的默認值):gtid_executed
和gtid_purged
的初始化:MySQL只遍歷最新的和最早的binlog文件,并根據(jù)這些文件中的Previous_gtids_log_event
或Gtid_log_event
來計算gtid_executed
和gtid_purged
的值。
【性能優(yōu)勢】:這種方法顯著減少了遍歷binlog文件的數(shù)量,從而提高了MySQL啟動和重啟時的性能。
3.9 session_track_gtids
session_track_gtids
是 MySQL 中的一個系統(tǒng)變量,用于控制 MySQL 會話(session)中是否追蹤全局事務標識符(GTID)的狀態(tài)。這個變量對于使用 GTID 進行復制和讀寫分離的 MySQL 環(huán)境尤為重要,因為它可以幫助確保數(shù)據(jù)的一致性和準確性。
【可選值】:
OFF
:默認值,表示不追蹤 GTID。在這種模式下,MySQL 會話不會記錄與 GTID 相關的狀態(tài)信息。OWN_GTID
:表示追蹤上次反饋后當前會話所提交的所有新增 GTID。這個選項主要用于跟蹤會話內(nèi)部產(chǎn)生的 GTID,以便在需要時能夠準確地識別出哪些 GTID 是由當前會話產(chǎn)生的。ALL_GTIDS
:表示直接返回gtid_executed
系統(tǒng)變量的值,即在當前會話事務完成提交后讀取所有已執(zhí)行的 GTID。這個選項提供了更全面的 GTID 追蹤能力,但可能會引入額外的性能開銷(由于需要讀取和記錄所有已執(zhí)行的 GTID,可能會增加額外的 CPU 和內(nèi)存開銷)。
【配置建議】在大多數(shù)情況下,如果不需要進行復雜的讀寫分離或數(shù)據(jù)一致性校驗,可以保持其默認值 OFF
以減少性能開銷。如果需要這些功能,則可以根據(jù)實際情況選擇 OWN_GTID
或 ALL_GTIDS
。
3.10 其他相關參數(shù)
雖然不直接與GTID的配置相關,但以下參數(shù)在配置GTID主從復制時也非常重要:
server-id
:指定MySQL服務器的唯一ID號,每個MySQL服務器(包括主庫和從庫)都必須擁有不同的ID號。log-bin
:啟用二進制日志功能,這是MySQL主從復制的基礎。binlog_format
:指定二進制日志的格式,對于GTID主從復制,通常設置為ROW以記錄行級別的更改操作。
4. GTID生命周期
4.1 GTID的生成與分配
- 事務提交與GTID分配:當一個事務在主庫上執(zhí)行并提交時,MySQL會自動為該事務分配一個GTID。
- 寫入二進制日志:分配GTID后,該GTID會在事務提交時以Gtid_log_event事件的形式(將GTID和事務本身)寫入主庫的二進制日志文件中。
這是一個原子操作保證GTID和事務內(nèi)容同時寫入日志。
4.2 2. GTID的持久化與記錄
事務提交后很短的時間內(nèi),將GTID寫入@@global.gtid_executed狀態(tài)變量。此變量包含了所有已執(zhí)行的事務,代表了主庫的當前狀態(tài)。
- 寫入
mysql.gtid_executed
表:當二進制日志發(fā)生切換或MySQL服務器關閉時,所有已寫入二進制日志的GTID會被寫入到mysql.gtid_executed
表中,以實現(xiàn)GTID的持久化。 - 更新
GLOBAL.gtid_executed
系統(tǒng)變量:在事務提交時,MySQL還會將該GTID加入到@@GLOBAL.gtid_executed
系統(tǒng)變量中。這個變量是一個GTID集合,代表了目前為止所有被執(zhí)行過的事務。
4.3 GTID的傳輸與應用
- 傳輸?shù)綇膸?/strong>:在主從復制過程中,包含GTID的二進制日志會被傳輸?shù)綇膸?,并存儲在從庫的中繼日志(
relay log
)中。 - 從庫應用GTID事務:從庫讀取relay日志中的GTID,并將其
gtid_next
變量設置為該GTID,表示從庫下一個即將執(zhí)行的事務。然后,從庫執(zhí)行該GTID對應的事務,執(zhí)行前會先進行檢查,保證此GTID沒有被執(zhí)行,且當前的沒有其他會話讀取此GTID。
如果有多個會話讀取了此GTID,只有1個可以執(zhí)行,其他的都會阻塞。從庫的gtid_owned
系統(tǒng)變量@@global.gtid_owned
顯示當前正在使用的GTID以及擁有它的線程ID。如果已經(jīng)使用了該GTID,通過自動跳過功能忽略該事務,并且不會引發(fā)錯誤。
如果此GITD未執(zhí)行過,從庫應用此事務,并使用主庫生成的GTID,不會重新分配。 - 從庫記錄GTID:如果從庫啟用了二進制日志功能,它也會通過gtid_log_event原子事件將該GTID寫入到自己的二進制日志文件中。如果未啟用,當輪換日志或關閉服務器時,則GTID會被記錄在
mysql.gtid_executed
表中(開啟二進制日志時mysql.gtid_executed
不代表服務器的最新狀態(tài))。
從庫提交后很短的時間內(nèi),將GTID寫入從庫@@global.gtid_executed
狀態(tài)變量(建議始終查詢@@global.gtid_executed
來查看服務器的狀態(tài))
4.4 GTID的清理與重置
- 清理GTID_PURGED:如果二進制日志被刪除,則刪除部分的GTID信息會被更新到
@@GLOBAL.GTID_PURGED
中。這個變量是@@GLOBAL.gtid_executed
的子集,表示已經(jīng)被清理的GTID集合。 - 重置GTID信息:使用
RESET MASTER
命令會清除@@global.gtid_purged
、@@global.gtid_executed
、mysql.gtid_executed
表以及清理binlog。
而RESET SLAVE
和RESET SLAVE ALL
命令會清理掉@@global.gtid_executed
和@@global.gtid_purged
。
4.5 GTID的并行復制
多線程復制:如果啟用了多線程復制(slave_parallel_workers > 0
),MySQL會并行執(zhí)行GTID事務。此時,gtid_executed
變量的值可能會有GAP,系統(tǒng)會自動更新這些值以反映并行執(zhí)行的狀態(tài)。
5. GTID自動定位
GTID自動定位是MySQL復制中的一個重要特性,它允許副本(slave)自動定位到主庫(master)的正確位置進行數(shù)據(jù)同步,而無需手動指定日志文件和位置,極大地簡化了主從復制的管理和切換過程。
在使用GTID進行復制時,副本通過啟用SOURCE_AUTO_POSITION或MASTER_AUTO_POSITION選項來自動連接到主庫。這個選項允許副本在初始握手時發(fā)送一個包含已接收、提交或兩者兼有的事務的GTID集合,從而使得副本能夠自動定位到正確的位置進行數(shù)據(jù)同步。
CHANGE MASTER TO MASTER_HOST='master_host_name', MASTER_USER='replication_user_name', MASTER_PASSWORD='replication_password', MASTER_AUTO_POSITION = 1;
MASTER_AUTO_POSITION = 1 表示slave應該自動定位到master的GTID。
如果已經(jīng)有一個配置好的slave,并且想要開啟或者更改GTID自動定位,可以使用以下命令:
STOP SLAVE; CHANGE MASTER TO MASTER_AUTO_POSITION = 1; START SLAVE;
6. GTID復制監(jiān)控與管理
6.1 mysql.gtid_executed表
mysql.gtid_executed
表記錄了是服務器上已經(jīng)執(zhí)行事務的GTID。表的結構如下:
+------------------+-------------+------+-------+------------+-----------+ | Field | Type | Null | Key | Default | Extra | +------------------+-------------+------+-------+------------+-----------+ | source_uuid | char(36) | NO | PRI | NULL | | +------------------+-------------+------+-------+------------+-----------+ | interval_start | bigint | NO | PRI | NULL | | +------------------+-------------+------+-------+------------+-----------+ | interval_end | bigint | NO | | NULL | | +------------------+-------------+------+-------+------------+-----------+ 3 rows in set (0.00 sec)
因此當啟用二進制日志記錄時,mysql.gtid_executed
表并不保存最新已執(zhí)行事務GTID,最新狀態(tài)可以由gtid_executed
全局系統(tǒng)變量(@@global.gtid_executed
)提供,該變量在每次提交事務后更新。為了節(jié)省空間,MySQL服務器會定期壓縮mysql.gtid_executed
表,方法是將多行表示為單行GTID集。
6.2 監(jiān)控復制心跳
復制建立后,主庫會定期向從庫發(fā)送心跳信號(即使沒有發(fā)送事務),心跳可以在建立主從復制時,通過change master to的master_heartbeat_period
子句指定。如果未指定則默認是從庫連接超時的一半:
mysql> show variables like 'slave_net_timeout'; +-------------------+---------+ | Variable_name | Value | +-------------------+---------+ | slave_net_timeout | 10 | +-------------------+---------+ 1 row in set (0.00 sec)
最近一次的心跳時間可以通過performance_schema.replication_connection_status
表中的last_heartbeat_timestamp
查看
到此這篇關于MySQL gtid的具體使用的文章就介紹到這了,更多相關MySQL gtid內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
mysql視圖之確保視圖的一致性(with check option)操作詳解
這篇文章主要介紹了mysql視圖之確保視圖的一致性(with check option)操作,結合實例形式詳細分析了視圖的一致性操作原理、實現(xiàn)技巧與操作注意事項,需要的朋友可以參考下2019-12-12一文帶你了解MySQL之InnoDB統(tǒng)計數(shù)據(jù)是如何收集的
通過show index可以看到關于索引的統(tǒng)計數(shù)據(jù),那么這些統(tǒng)計數(shù)據(jù)是怎么來的呢,它們是以什么方式收集的呢,本章將聚焦于InnoDB存儲引擎的統(tǒng)計數(shù)據(jù)收集策略,需要的朋友可以參考下2023-05-05