MySQL GTID Replication:
專(zhuān)注于為中小企業(yè)提供做網(wǎng)站、網(wǎng)站設(shè)計(jì)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)莫力達(dá)免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上千多家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
從MySQL5.6開(kāi)始增加了強(qiáng)大的GTID(Global Transaction ID,全局事務(wù)ID)這個(gè)特性,用來(lái)強(qiáng)化數(shù)據(jù)庫(kù)的主備一致性, 故障恢復(fù), 以及容錯(cuò)能力。用于取代過(guò)去傳統(tǒng)的主從復(fù)制(即:基于binlog和position的異步復(fù)制)。
借助GTID,在發(fā)生主備切換的情況下,MySQL的其他slave可以自動(dòng)在新主上找到正確的復(fù)制位置,這大大簡(jiǎn)化了復(fù)雜復(fù)制拓?fù)湎录旱木S護(hù),也減少了人為設(shè)置復(fù)制position發(fā)生誤操作的風(fēng)險(xiǎn)。另外,基于GTID的復(fù)制可以忽略已經(jīng)執(zhí)行過(guò)的事務(wù),減少了數(shù)據(jù)發(fā)生不一致的風(fēng)險(xiǎn)。
GTID組成:
GTID是由server_uuid和事務(wù)id組成的,即GTID=server_uuid:transaction_id。
server_uuid,是在MySQL第一次啟動(dòng)時(shí)自動(dòng)生成并持久化到auto.cnf文件(存放在數(shù)據(jù)目錄下,每臺(tái)機(jī)器的server_uuid都不一樣。
transaction_id,是一個(gè)從1開(kāi)始的自增計(jì)數(shù),表示在這個(gè)主庫(kù)上執(zhí)行的第n個(gè)事務(wù)。MySQL會(huì)保證事務(wù)與GTID之間的1:1映射,如:b6af5b5c-666f-11e9-bed3-000c29b85ea6:1
表示在以b6af5b5c-666f-11e9-bed3-000c29b85ea6為唯一標(biāo)識(shí)的MySQL實(shí)例上執(zhí)行的第1個(gè)數(shù)據(jù)庫(kù)事務(wù)。
一組連續(xù)的事務(wù)可以用 "-" 連接的事務(wù)序號(hào)范圍表示。例如:b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-5
基于GTID復(fù)制的優(yōu)點(diǎn):
1、根據(jù)傳統(tǒng)的復(fù)制原理,當(dāng)連接發(fā)生故障時(shí),需要重新連接到master主機(jī),需要找到binlog和position,然后change master to 連接到master主機(jī),此過(guò)程需要人工來(lái)做,比較麻煩,也容易出錯(cuò),尤其是master寫(xiě)操作較多時(shí),更不容易確定position,如果flush table with read lock,勢(shì)必會(huì)影響到線上業(yè)務(wù)。而GTID復(fù)制方式不需要找master的binlog和position,只需要知道m(xù)aster的ip、端口、賬號(hào)密碼,即可進(jìn)行復(fù)制,MySQl會(huì)通過(guò)內(nèi)部機(jī)制自動(dòng)找點(diǎn)同步(MASTER_AUTO_POSITION=1)
簡(jiǎn)單來(lái)說(shuō)就是:簡(jiǎn)化復(fù)制。傳統(tǒng)復(fù)制是基于file和position來(lái)實(shí)現(xiàn)的,而file和position是人為確定的,file還好一些,但是position卻是實(shí)時(shí)變動(dòng)的,難以確定,除非對(duì)全庫(kù)加讀鎖,但這勢(shì)必會(huì)對(duì)線上業(yè)務(wù)產(chǎn)生影響,GTID會(huì)自動(dòng)找position進(jìn)行數(shù)據(jù)同步
2、多線程復(fù)制(基于庫(kù)),在MySQL5.6以前的版本,slave的復(fù)制是單線程的。一個(gè)事件一個(gè)事件的讀取應(yīng)用。而master是并發(fā)寫(xiě)入的,所以延遲是避免不了的。唯一有效的方法是把多個(gè)庫(kù)放在多臺(tái)slave,這樣又有點(diǎn)浪費(fèi)服務(wù)器。在MySQL5.6里面,我們可以把多個(gè)表放在多個(gè)庫(kù),這樣就可以使用多線程復(fù)制,當(dāng)只有1個(gè)庫(kù),多線程復(fù)制是沒(méi)有用的(即:所謂的并行復(fù)制)
簡(jiǎn)單來(lái)說(shuō)就是:跟多線程復(fù)制相關(guān)。多線程復(fù)制是基于組提交方式實(shí)現(xiàn)的,而組提交信息是存儲(chǔ)在GTID中的
GTID的作用:
1、根據(jù)GTID可以知道事務(wù)最初是在哪個(gè)實(shí)例上提交的
2、GTID的存在方便了Replication的Failover
GTID復(fù)制實(shí)現(xiàn)的工作原理:
1、master更新數(shù)據(jù)時(shí),會(huì)在事務(wù)前產(chǎn)生GTID,一同記錄到binlog日志中
2、slave端的I/O線程將變更的binlog,寫(xiě)入到本地的relay log中
3、SQL線程從relay log中獲取GTID,然后對(duì)比slave端的binlog是否有記錄(所以MySQL5.6 slave端必須開(kāi)啟binlog)
4、如果有記錄,說(shuō)明該GTID的事務(wù)已經(jīng)執(zhí)行,slave會(huì)忽略
5、如果沒(méi)有記錄,slave就會(huì)從relay log中執(zhí)行該GTID的事務(wù),并記錄到binlog
6、在解析過(guò)程中會(huì)判斷是否有主鍵,如果沒(méi)有就用二級(jí)索引,如果沒(méi)有就用全部掃描
GTID使用限制:
1、? MySQL5.7之后才開(kāi)始支持動(dòng)態(tài)切換GTID相關(guān)的參數(shù)
2、? 不支持CREATE TABLE ... SELECT statements
3、? 不支持CREATE TEMPORARY TABLE statements inside transactions
4、? transaction or statement 既更新了事務(wù)表又更新了非事務(wù)表
5、? 使用GTID復(fù)制從庫(kù)跳過(guò)錯(cuò)誤時(shí),不支持執(zhí)行sql_slave_skip_counter參數(shù)的語(yǔ)法
GTID相關(guān)狀態(tài)變量介紹:
推薦閱讀MySQL官網(wǎng)英文原著
Master、Slave上都可以查看GTID相關(guān)的狀態(tài)變量
mysql> show global variables like '%gtid%';
+--------------------------+------------------------------------------+
| Variable_name??????????? | Value??????????????????????????????????? |
+--------------------------+------------------------------------------+
| enforce_gtid_consistency | ON?????????????????????????????????????? |
| gtid_executed??????????? | b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-7 |
| gtid_mode??????????????? | ON?????????????????????????????????????? |
| gtid_owned?????????????? |????????????????????????????????????????? |
| gtid_purged????????????? |????????????????????????????????????????? |
+--------------------------+------------------------------------------+
5 rows in set (0.00 sec)
以下內(nèi)容是筆者從博客、論壇等收集的資料,不保證正確性,僅供參考:
1、gtid_executed
在當(dāng)前實(shí)例上執(zhí)行過(guò)的GTID集合,實(shí)際上包含了所有記錄到binlog中的事務(wù)。所以,設(shè)置set sql_log_bin=0后執(zhí)行的事務(wù)不會(huì)生成binlog事件,也不會(huì)被記錄到gtid_executed中。執(zhí)行reset master可以將該變量清空
2、gtid_purged
binlog不可能永久停留在服務(wù)器上,需要進(jìn)行定期清理(如通過(guò)expire_logs_days),否則遲早它會(huì)把磁盤(pán)空間用完。gtid_purged用于記錄已經(jīng)被清除了的binlog事務(wù)集合,它是gtid_executed的子集。只有g(shù)tid_executed為空時(shí)才能手動(dòng)設(shè)置該變量,此時(shí)會(huì)同時(shí)更新gtid_executed為和gtid_purged相同的值。gtid_executed為空意味著要么之前沒(méi)有啟動(dòng)過(guò)基于GTID的復(fù)制,要么執(zhí)行過(guò)reset master。執(zhí)行reset master時(shí)同樣也會(huì)把gtid_purged置空,即始終保持gtid_purged是gtid_executed的子集。
3、gtid_next
會(huì)話級(jí)變量,指示如何產(chǎn)生下一個(gè)GTID??赡艿娜≈担?br />AUTOMATIC,自動(dòng)生成下一個(gè)GTID,實(shí)現(xiàn)上是分配一個(gè)當(dāng)前實(shí)例上尚未執(zhí)行過(guò)的序號(hào)最小的GTID
ANONYMOUS,設(shè)置后執(zhí)行事務(wù)不會(huì)產(chǎn)生GTID
顯式指定的GTID,可以指定任意形式合法的GTID值,但不能是當(dāng)前gtid_executed中的已經(jīng)包含的GTID,否則,下次執(zhí)行事務(wù)時(shí)會(huì)報(bào)錯(cuò)
4、gtid_mode
是否開(kāi)啟GTID復(fù)制功能
5、enforce-gtid-consistency = ON
啟動(dòng)強(qiáng)制GTID的一致性,如果開(kāi)啟GTID功能則此參數(shù)必須要開(kāi)啟;slave在做同步復(fù)制時(shí),無(wú)須找到binlog日志和POS點(diǎn),直接change master to master_auto_position=1即可,自動(dòng)根據(jù)GTID進(jìn)行同步數(shù)據(jù)。
延伸:
多線程復(fù)制:
MySQL5.6之前的版本,同步復(fù)制是單線程的、隊(duì)列的,只能一個(gè)一個(gè)執(zhí)行。在MySQL5.6里,可以做到多個(gè)庫(kù)之間的多線程復(fù)制。例如數(shù)據(jù)庫(kù)里,存放著用戶表、商品表、價(jià)格表、訂單表,那么將每個(gè)業(yè)務(wù)表單獨(dú)放在一個(gè)庫(kù)里,這時(shí)就可以做到多線程復(fù)制,但一個(gè)庫(kù)里的表,多線程復(fù)制是無(wú)效的(因?yàn)橥粋€(gè)庫(kù)進(jìn)行多線程復(fù)制到Slave上時(shí)會(huì)造成問(wèn)題);每個(gè)數(shù)據(jù)庫(kù)僅能使用一個(gè)線程(即:MySQL5.6多線程復(fù)制基于庫(kù)),復(fù)制涉及到多個(gè)數(shù)據(jù)庫(kù)時(shí)多線程復(fù)制才有意義。Slave上多線程復(fù)制的控制參數(shù)為slave-parallel-workers=0(0表示禁用多線程功能)
題外:
本文的主要作用是記錄GTID的用途、優(yōu)缺點(diǎn)、使用限制、狀態(tài)變量介紹等,內(nèi)容大多是從MySQL官網(wǎng)或者一些博客論壇摘錄的理解。本著實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn)的原則,記錄本文更多的作用為將來(lái)實(shí)際應(yīng)用的時(shí)候做鋪路。所以,筆者不保證內(nèi)容準(zhǔn)確性,僅供參考。歡迎業(yè)內(nèi)大佬指出其中不當(dāng)之處,在此先表示感謝!