MySQL基于GTID復(fù)制

一皮璧、GTID的概述:

1、全局事物標(biāo)識(shí):global transaction identifieds分飞。

2悴务、GTID事物是全局唯一性的,且一個(gè)事務(wù)對(duì)應(yīng)一個(gè)GTID譬猫。

3讯檐、一個(gè)GTID在一個(gè)服務(wù)器上只執(zhí)行一次,避免重復(fù)執(zhí)行導(dǎo)致數(shù)據(jù)混亂或者主從不一致染服。

4别洪、GTID用來(lái)代替classic的復(fù)制方法,不在使用binlog+pos開(kāi)啟復(fù)制柳刮。而是使用master_auto_postion=1的方式自動(dòng)匹配GTID斷點(diǎn)進(jìn)行復(fù)制挖垛。

5、MySQL-5.6.5開(kāi)始支持的秉颗,MySQL-5.6.10后開(kāi)始完善痢毒。

6、在傳統(tǒng)的slave端蚕甥,binlog是不用開(kāi)啟的闸准,但是在GTID中,slave端的binlog是必須開(kāi)啟的梢灭,目的是記錄執(zhí)行過(guò)的GTID(強(qiáng)制)夷家。

二蒸其、GTID的組成部分:

前面是server_uuid:后面是一個(gè)序列號(hào)

例如:server_uuid:sequence number

7800a22c-95ae-11e4-983d-080027de205a:10

UUID:每個(gè)mysql實(shí)例的唯一ID,由于會(huì)傳遞到slave库快,所以也可以理解為源ID摸袁。

Sequence number:在每臺(tái)MySQL服務(wù)器上都是從1開(kāi)始自增長(zhǎng)的序列,一個(gè)數(shù)值對(duì)應(yīng)一個(gè)事務(wù)义屏。

三靠汁、GTID比傳統(tǒng)復(fù)制的優(yōu)勢(shì):

1、更簡(jiǎn)單的實(shí)現(xiàn)failover闽铐,不用以前那樣在需要找log_file和log_Pos蝶怔。

2、更簡(jiǎn)單的搭建主從復(fù)制兄墅。

3踢星、比傳統(tǒng)復(fù)制更加安全。

4隙咸、GTID是連續(xù)沒(méi)有空洞的沐悦,因此主從庫(kù)出現(xiàn)數(shù)據(jù)沖突時(shí),可以用添加空事物的方式進(jìn)行跳過(guò)五督。

四藏否、GTID的工作原理:

1、master更新數(shù)據(jù)時(shí)充包,會(huì)在事務(wù)前產(chǎn)生GTID副签,一同記錄到binlog日志中。
2基矮、slave端的i/o 線(xiàn)程將變更的binlog淆储,寫(xiě)入到本地的relay log中。
3愈捅、sql線(xiàn)程從relay log中獲取GTID,然后對(duì)比slave端的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)有就用全部掃描。

五凭豪、要點(diǎn):

1焙蹭、slave在接受master的binlog時(shí),會(huì)校驗(yàn)master的GTID是否已經(jīng)執(zhí)行過(guò)(一個(gè)服務(wù)器只能執(zhí)行一次)嫂伞。

2孔厉、為了保證主從數(shù)據(jù)的一致性,多線(xiàn)程只能同時(shí)執(zhí)行一個(gè)GTID帖努。

六撰豺、使用GTID搭建mysql的主從復(fù)制的主要參數(shù):

[mysqld]
#GTID:
gtid_mode=on
enforce_gtid_consistency=on
server_id=2003306    #每天實(shí)例的server_id都要不一樣

#binlog
log-bin=mysqlbin
log-slave-updates=1   #允許下端接入slave
binlog_format=row      #強(qiáng)烈建議,其他格式可能造成數(shù)據(jù)不一致

#relay log
skip_slave_start=1
注意:建議使用mysql-5.6.5以上的最新版本拼余。

啟動(dòng)GTID的兩種方法:

方法一污桦、

1、如果是在已經(jīng)跑的服務(wù)器姿搜,你需要重啟一下mysql server寡润。
2、啟動(dòng)之前舅柜,一定要先關(guān)閉master的寫(xiě)入梭纹,保證所有slave端都已經(jīng)和master端數(shù)據(jù)保持同步。
3致份、所有slave需要加上skip_slave_start=1的配置參數(shù)变抽,避免啟動(dòng)后還是使用老的復(fù)制協(xié)議。

方法二氮块、

1绍载、如果是新搭建的服務(wù)器,直接啟動(dòng)就行了滔蝉。

七击儡、master-slave搭建的注意事項(xiàng):

(一)、使用GTID的方式蝠引,把salve端掛載master端:

1阳谍、啟動(dòng)以后最好不要立即執(zhí)行事務(wù),而是先change master上螃概。
2矫夯、然后在執(zhí)行事務(wù),當(dāng)然知不是必須的吊洼。
3训貌、使用下面的sql切換slave到新的master。

stop slave;

CHANGE MASTER TO
MASTER_HOST='127.0.0.1',
MASTER_PORT=3306,
MASTER_USER='repl',
MASTER_PASSWORD='repl',
master_auto_position = 1;

(二)冒窍、如果給已經(jīng)運(yùn)行的GTID的master端添加一個(gè)新的slave

有兩種方法:

方法一递沪、適用于master也是新建不久的情況豺鼻。

1、如果你的master所有的binlog還在区拳【辛欤可以選擇類(lèi)似于上面的方法,安裝slave樱调,直接change master to到master端约素。

2、原理是直接獲取master所有的GTID并執(zhí)行笆凌。

3圣猎、優(yōu)點(diǎn):簡(jiǎn)單方便。

4乞而、缺點(diǎn):如果binlog太多送悔,數(shù)據(jù)完全同步需要時(shí)間較長(zhǎng),并且master一開(kāi)始就啟用了GTUD爪模。

方法二欠啤、適用于擁有較大數(shù)據(jù)的情況。(推薦)

1屋灌、通過(guò)master或者其他slave的備份搭建新的slave洁段。(看第三部分)

2、原理:獲取master的數(shù)據(jù)和這些數(shù)據(jù)對(duì)應(yīng)的GTID范圍共郭,然后通過(guò)slave設(shè)置@@global.gtid_purged跳過(guò)備份包含的gtid祠丝。

3、優(yōu)點(diǎn):是可以避免第一種方法的不足除嘹。

4写半、缺點(diǎn):相對(duì)來(lái)說(shuō)有點(diǎn)復(fù)雜。

(三)尉咕、通過(guò)備份搭建新的slave:(方法二的擴(kuò)展)

兩種方法:

方法一叠蝇、mysqldump的方式:

1、在備份的時(shí)候指定--master-data=2(來(lái)保存binlog的文件號(hào)和位置的命令)年缎。
2悔捶、使用mysqldump的命令在dump文件里可以看到下面兩個(gè)信息:
  SET @@SESSION.SQL_LOG_BIN=0;
  SET @@GLOBAL.GTID_PURGED='7800a22c-95ae-11e4-983d-080027de205a:1-8';
3、將備份還原到slave后晦款,使用change master to命令掛載master端炎功。

注意:在mysql5.6.9以后的命令才支持這個(gè)功能枚冗。

方法二缓溅、percona Xtrabackup

1、Xtrabackup_binlog_info文件中赁温,包含global.gtid_purged='XXXXXX:XXXX'的信息坛怪。
2淤齐、然后到slave去手工的 SET GLOBAL.GTID_PURGED='XXXXXX:XXXX'。
3袜匿、恢復(fù)備份更啄,開(kāi)啟change master to 命令。

注意:如果系統(tǒng)運(yùn)行了很久居灯,無(wú)法找到GTID的變好了祭务,可以通過(guò)上面的方式進(jìn)行查找。

八怪嫌、GTID如何跳過(guò)事務(wù)沖突:

1义锥、這個(gè)功能主要跳過(guò)事務(wù),代替原來(lái)的set global sql_slave_skip_counter = 1岩灭。

2拌倍、由于在這個(gè)GTID必須是連續(xù)的,正常情況同一個(gè)服務(wù)器產(chǎn)生的GTID是不會(huì)存在空缺的噪径。所以不能簡(jiǎn)單的skip掉一個(gè)事務(wù)柱恤,只能通過(guò)注入空事物的方法替換掉一個(gè)實(shí)際操作事務(wù)。

3找爱、注入空事物的方法:

stop slave;
set gtid_next='xxxxxxx:N';
begin;commit;
set gtid_next='AUTOMAIC';
start slave;

4梗顺、這里的xxxxx:N 也就是你的slave sql thread報(bào)錯(cuò)的GTID,或者說(shuō)是你想要跳過(guò)的GTID缴允。

九荚守、GTID的參數(shù)注釋?zhuān)?/h2>
[master]>show global variables like '%gtid%';
1、enforce_gtid_consistency:開(kāi)啟gtid的一些安全限制(介意開(kāi)啟)练般。

2矗漾、gtid_executed:全局和seeeion級(jí)別都可以用。用來(lái)保存已經(jīng)執(zhí)行過(guò)的GTIDs薄料。
貼士:show  master status\G;輸出結(jié)果中的Executed_Gtid_Set和gitd_executed一致敞贡。reset master時(shí),此值會(huì)被清空摄职。

3誊役、gtid_owned:全局和session級(jí)別都可用,全局表示所有服務(wù)器擁有GTIDs谷市,session級(jí)別表示當(dāng)前client擁有所有GTIDs蛔垢。(此功能用的少)

4、gtid_mode:是否開(kāi)啟GTID功能迫悠。

5鹏漆、gtid_purged:全局參數(shù),設(shè)置在binlog中,已經(jīng)purged的GTIDs艺玲,并且purged掉的GTIDs會(huì)包含到gtid_executed中括蝠。

貼士:從而導(dǎo)致slave不會(huì)再去master請(qǐng)求這些GTIDs,并且Executed_Gtid_Set為空時(shí)饭聚,才可以設(shè)置此值忌警。

6、gtid_next:這個(gè)時(shí)session級(jí)別的參數(shù):
[master]>show session variables like '%gtid_next%';

十秒梳、關(guān)于GTID的一些功能限制:

(一)法绵、更新非事務(wù)引擎:

1、Case重現(xiàn):
master:對(duì)一個(gè)innodb表做一個(gè)多sql更新的事物酪碘,效果是產(chǎn)生一個(gè)GTID礼烈。
slave:對(duì)應(yīng)的表是MYISAM引擎,執(zhí)行這個(gè)GTID的第一個(gè)語(yǔ)句后就會(huì)報(bào)錯(cuò)婆跑,因?yàn)榉鞘聞?wù)引擎一個(gè)sql就是一個(gè)事務(wù)此熬。

2、錯(cuò)誤編號(hào):
last_Errno:1756

3滑进、異诚溃恢復(fù)方案:
(1)、簡(jiǎn)單的stop slave; start slave;就能夠忽略錯(cuò)誤扶关。但是這個(gè)時(shí)候主從的一致性已經(jīng)出現(xiàn)問(wèn)題阴汇。需要手工的把slave差的數(shù)據(jù)補(bǔ)上。
(2)节槐、首先將引擎調(diào)整為一樣的搀庶,slave也改為事務(wù)引擎。

(二)铜异、create table ....select statements

1哥倔、case重現(xiàn):
master:直接執(zhí)行一個(gè)create table select * from table;的sql

2、報(bào)錯(cuò):
error 1786

3揍庄、原理:
由于create table ...select語(yǔ)句會(huì)生成兩個(gè)sql咆蒿,一個(gè)是DDL創(chuàng)建表SQL,一個(gè)是insert into 插入數(shù)據(jù)的sql蚂子。由于DDL會(huì)導(dǎo)致自動(dòng)提交沃测,所以這個(gè)sql至少需要兩個(gè)GTID,但是GTID模式下食茎,只能給這個(gè)sql生成一個(gè)GTID蒂破,如果強(qiáng)制執(zhí)行會(huì)導(dǎo)致和上面更新非事務(wù)引擎一樣的結(jié)果。

(三)别渔、一個(gè)sql同事操作innodb引擎和myisam引擎:

case重現(xiàn):t1表是innodb附迷,t2表是myisam
1田巴、update t1,t2 set t1.id=1000,t2.id=1000 where t1.id=t2.id;
2、報(bào)錯(cuò):1785
3挟秤、原理和第二個(gè)相同。

(四)抄伍、在一個(gè)replication grouop 中艘刚,所有的mysql必須要統(tǒng)一開(kāi)啟或者關(guān)閉GTID功能。

1截珍、case重現(xiàn):
將一個(gè)未開(kāi)啟gtid的slave通過(guò)原始的binlog和pos方式連接到開(kāi)啟GTID的master攀甚。

2、報(bào)錯(cuò):
The slave IO thread stops because the master has @@GLOBAL.GTID_MODE ON and this server has @@GLOBAL.GTID_MODE OFF岗喉。

(五)秋度、在一個(gè)replication group中,如果開(kāi)啟GTID以后钱床,就不再允許使用classic的復(fù)制方式:

1荚斯、case重現(xiàn):
將一個(gè)開(kāi)啟gtid的slave通過(guò)原始的binlog和pos方式連接到開(kāi)啟GTID的master。

2查牌、報(bào)錯(cuò):
ERROR 1776(HY000):Parameters MASTER_LOG_FILE事期,MASTER_LOG_POS,RELAY_LOG_FILE and RELAY_LOG_POS cannot be set when MASTER_AUTO_POSITION is active纸颜。

(六)兽泣、GTID_MODE是not online的:

需要重啟才能生效,官方暫時(shí)不支持平滑的從classic replication切換到GTID replication胁孙。
貼士:
由于GTID開(kāi)啟需要重啟系統(tǒng)唠倦,一個(gè)復(fù)制組中所有的實(shí)例必須統(tǒng)一開(kāi)啟或者關(guān)閉GTID,開(kāi)啟GTID以后不能在使用classic復(fù)制。
問(wèn)題:
也就是說(shuō)在線(xiàn)業(yè)務(wù)必須統(tǒng)一關(guān)閉涮较,然后再啟動(dòng)稠鼻,會(huì)導(dǎo)致服務(wù)中斷。

解決方案:
1狂票、針對(duì)這種情況枷餐,社區(qū)有兩種對(duì)應(yīng)的平滑升級(jí)的方案:
一種是booking.com出品,這兩個(gè)差別在淘寶9月份數(shù)據(jù)庫(kù)月報(bào)里有說(shuō)明苫亦,加了一個(gè)橋接的服務(wù)器毛肋,既可以運(yùn)行GTID模式下,也可以運(yùn)行classic模式下屋剑。
另外一種是facebook.com出品润匙。所有的slave可以在開(kāi)啟GTID模式的情況下,可以連接到?jīng)]有開(kāi)啟GTID模式的master唉匾。

2孕讳、可以關(guān)閉一個(gè)部分匠楚,停止寫(xiě)操作,但是讀不用厂财,將另一部分改成GTID模式芋簿。

(七)、Temporary tables璃饱。

1与斤、create temporary table和drop temporary table語(yǔ)句一樣在GTID環(huán)境下不支持。
如果--enforce_gtid_consistency參數(shù)開(kāi)啟荚恶,并且autocommit=1撩穿,那么可以使用。

(八)谒撼、關(guān)于Errant transaction

1食寡、Errant transaction:所謂的errant transaction也就是沒(méi)有規(guī)范的從master執(zhí)行,而是直接從slave執(zhí)行的事務(wù)廓潜。
2抵皱、由于GTID協(xié)議的原因,最開(kāi)始已經(jīng)提過(guò)(參見(jiàn)GTID architecture)辩蛋。
3叨叙、如果slave有errant transaction產(chǎn)生,由于GTID協(xié)議中的規(guī)則堪澎,很容易導(dǎo)致failover失敗擂错。主要有兩種情況:

a、在slave上做了無(wú)用的或者臨時(shí)的errant transaction操作樱蛤,如果該slave升級(jí)成為master的話(huà)钮呀,連接到它的所有數(shù)據(jù)庫(kù)都會(huì)獲取到這個(gè)事務(wù)。如果一樣就會(huì)產(chǎn)生沖突昨凡。

b爽醋、由于做了這個(gè)errant transaction這個(gè)事務(wù)以后,其他的slave還沒(méi)有獲取這個(gè)errant transaction的GTID便脊,需要從master上發(fā)同步給其他的slave蚂四,但是主的binlog又被刪掉了,這時(shí)將會(huì)報(bào)錯(cuò)哪痰。

4遂赠、總之:盡量避免產(chǎn)生errant transaction∩谓埽可以通過(guò):set sql_log_bin=off的方式在slave執(zhí)行sql跷睦,但是也要考慮到數(shù)據(jù)一致性。


··············跳過(guò)錯(cuò)誤
從庫(kù)已經(jīng)執(zhí)行過(guò)的事務(wù)是'e10c75be-5c1b-11e6-ab7c-000c296078ae:1-5',執(zhí)行出錯(cuò)的事務(wù)是'e10c75be-5c1b-11e6-ab7c-000c296078ae:6'肋演,當(dāng)前主備的數(shù)據(jù)其實(shí)是一致的抑诸,可以通過(guò)設(shè)置gtid_next跳過(guò)這個(gè)出錯(cuò)的事務(wù)烂琴。

在從庫(kù)上執(zhí)行以下SQL:

mysql> set gtid_next='e10c75be-5c1b-11e6-ab7c-000c296078ae:6';
Query OK, 0 rows affected (0.00 sec)

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> set gtid_next='AUTOMATIC';
Query OK, 0 rows affected (0.00 sec)

mysql> start slave;
Query OK, 0 rows affected (0.02 sec)

設(shè)置gtid_next的方法一次只能跳過(guò)一個(gè)事務(wù),要批量的跳過(guò)事務(wù)可以通過(guò)設(shè)置gtid_purged完成蜕乡。


十一奸绷、GTID與crash safe salve

crash safe slave是MySQL 5.6提供的功能,意思是說(shuō)在slave crash后层玲,把slave重新拉起來(lái)可以繼續(xù)從Master進(jìn)行復(fù)制号醉,不會(huì)出現(xiàn)復(fù)制錯(cuò)誤也不會(huì)出現(xiàn)數(shù)據(jù)不一致。

1称簿、基于binlog文件位置的復(fù)制

在基于binlog文件位置的復(fù)制下,要保證crash safe slave惰帽,配置下面的參數(shù)即可憨降。
relay_log_info_repository = TABLE
relay_log_recovery = ON

這樣可行的原因是,relay_log_info_repository = TABLE時(shí)该酗,apply event和更新relay_log_info表的操作被包含在同一個(gè)事務(wù)里授药,innodb要么讓它們同時(shí)生效,要么同時(shí)不生效,保證位點(diǎn)信息和已經(jīng)應(yīng)用的事務(wù)精確匹配呜魄。同時(shí)relay_log_recovery = ON時(shí)悔叽,會(huì)拋棄master_log_info中記錄的復(fù)制位點(diǎn),根據(jù)relay_log_info的執(zhí)行位置重新從Master獲取binlog爵嗅,這就回避了由于未同步刷盤(pán)導(dǎo)致的binlog文件接受位置和實(shí)際不一致以及relay log文件被截?cái)嗟膯?wèn)題娇澎。

在同時(shí)使用MTS(multi-threaded slave)時(shí),為保證crash safe slave基于binlog文件位置的復(fù)制還需要設(shè)置sync_relay_log=1,因?yàn)镸ySQL在Crash恢復(fù)時(shí)必須先通過(guò)讀取relay log補(bǔ)齊MTS導(dǎo)致的事務(wù)空洞睹晒。

2趟庄、基于GTID的復(fù)制

上面的設(shè)置并不適用于基于GTID的復(fù)制。在基于GTID的復(fù)制下伪很,crash的Slave重啟后戚啥,從binlog中解析的gtid_executed決定了要apply哪些binlog記錄,所以binlog必須和innodb存儲(chǔ)引擎的數(shù)據(jù)保持一致锉试。要做到這一點(diǎn)猫十,需要把sync_binlog和innodb_flush_log_at_trx_commit都設(shè)置為1,即所謂的"雙1"呆盖。

另外MySQL啟動(dòng)時(shí)拖云,會(huì)從relay log文件中獲取已接收的GTIDs并更新Retrieved_Gtid_Set。由于relay log文件可能不完整应又,所以需要拋棄已接收的relay log文件江兢。因此relay_log_recovery = ON也是必須的。

這樣丁频,對(duì)于基于GTID的復(fù)制杉允,保證crash safe slave的設(shè)置就是下面這樣邑贴。

sync_binlog = 1
innodb_flush_log_at_trx_commit = 1
relay_log_recovery = ON

關(guān)于如何設(shè)置以確保crash safe slave,官方文檔有明確記載叔磷,見(jiàn) 17.3.2 Handling an Unexpected Halt of a Replication Slave拢驾。

但是其中關(guān)于GTID的記載中存在筆誤,將relay_log_recovery=1寫(xiě)成了relay_log_recovery=0 (#83711)。同時(shí)也沒(méi)有提到必須設(shè)置"雙1"改基,但是"雙1"是必要的繁疤,否則crash的Slave重啟后,可能會(huì)重復(fù)應(yīng)用binlog event也可能會(huì)遺漏應(yīng)用binlog event(#70659)秕狰。其中遺漏應(yīng)用binlog event的情況更可怕稠腊,因?yàn)镾lave在不觸發(fā)SQL錯(cuò)誤的情況下就默默的和Master不一致了。

3鸣哀、設(shè)置"雙1"對(duì)性能的影響

出于安全考慮架忌,強(qiáng)烈推薦設(shè)置"雙1"。"雙1"會(huì)增大每個(gè)事務(wù)的RT我衬,但得益于MySQL的組提交機(jī)制叹放,高并發(fā)下"雙1"對(duì)系統(tǒng)整體tps的影響在可接受范圍內(nèi)。

sysbench oltp.lua 10張表每張表100w記錄(qps/并發(fā)數(shù))

對(duì)更新同一行這樣無(wú)法有效并行的場(chǎng)景挠羔,"雙1"對(duì)性能的影響非常大井仰。

sysbench update_non_index.lua 1張表1條記錄(qps/并發(fā)數(shù))

對(duì)不能有效并行的Slave replay,存在同樣的問(wèn)題破加。

通過(guò)指定tx-rate執(zhí)行sysbench的update_non_index.lua腳本壓測(cè)30秒俱恶,完成后檢查主備延遲。

可以發(fā)現(xiàn)在Slave被配置為"雙1"的情況下范舀,延遲非常嚴(yán)重,1000以上的QPS就會(huì)出現(xiàn)延遲速那,非"雙1"下QPS到5000以上才會(huì)出現(xiàn)延遲(主庫(kù)配置為"雙1")。

sysbench update_non_index.lua 1張表100w條記錄 128并發(fā)(延遲/qps)

以上測(cè)試環(huán)境是Percona Server 5.6運(yùn)行在配置HDD的8 core虛機(jī)尿背,由于測(cè)試結(jié)果和系統(tǒng)IO能力有很大關(guān)系端仰,僅供參考。

4田藐、如何在非"雙1"下保證crash safe slave

如果是MySQL 5.7可以關(guān)閉log_slave_updates荔烧,這樣MySQL會(huì)將已執(zhí)行的GTIDs實(shí)時(shí)記錄到系統(tǒng)表mysql.gtid_executed中,mysql.gtid_executed是和用戶(hù)事務(wù)一起提交的汽久,因此可以保證和實(shí)際的數(shù)據(jù)一致鹤竭。

log_slave_updates = OFF
relay_log_recovery = ON

如果是MySQL 5.6可以采用如下變通的方式。

按照基于binlog文件復(fù)制時(shí)crash safe slave的要求設(shè)置

relay_log_info_repository = TABLE
relay_log_info_repository = TABLE
relay_log_recovery = ON

在Slave crash后景醇,根據(jù)relay_log_info_repository設(shè)置相應(yīng)的gitd_purged再開(kāi)啟復(fù)制臀稚,
步驟如下:

1.啟動(dòng)MySQL,但不開(kāi)啟復(fù)制
mysqld --skip-slave-start

2.在Slave上修改為基于binlog文件位置的復(fù)制
change master to MASTER_AUTO_POSITION = 0

3.啟動(dòng)slave IO線(xiàn)程
start slave io_thread
這里不能啟動(dòng)SQL線(xiàn)程三痰,如果接受到的GTID已經(jīng)在Slave的gtid_executed里了吧寺,會(huì)被Slave skip掉窜管。

4.檢查binlog傳輸?shù)拈_(kāi)始位置(即Retrieved_Gtid_Set的值)
show slave status\G
假設(shè)輸出的Retrieved_Gtid_Set值為e10c75be-5c1b-11e6-ab7c-000c296078ae:7-10

5.在Master上檢查gtid_executed
show master status
假設(shè)輸出的Executed_Gtid_Set值為e10c75be-5c1b-11e6-ab7c-000c296078ae:1-10

6.在Slave上設(shè)置gitd_purged為binlog傳輸位置的前面的GTID的集合
reset master;
set global gitd_purged='e10c75be-5c1b-11e6-ab7c-000c296078ae:1-6';

7.修改回auto position的復(fù)制
change master to MASTER_AUTO_POSITION = 1

8.啟動(dòng)slave SQL線(xiàn)程
start slave sql_thread

但是,這種變通的方法不適合多線(xiàn)程復(fù)制稚机。因?yàn)槎嗑€(xiàn)程復(fù)制可能產(chǎn)生gtid gap和Gap-free low-watermark position幕帆,這會(huì)導(dǎo)致Salve上重復(fù)apply已經(jīng)apply過(guò)的event赖条。后果就是數(shù)據(jù)不一致或者復(fù)制中斷失乾,除非設(shè)置binlog格式為row模式并且slave_exec_mode=IDEMPOTENT,slave_exec_mode=IDEMPOTENT允許Slave回放binlog時(shí)忽略重復(fù)鍵和找不到鍵的錯(cuò)誤,使得binlog回放具有冪等性,但這也意味著如果真的出現(xiàn)了主備數(shù)據(jù)不一致也會(huì)被它忽略诅蝶。

5、MTS下特有的問(wèn)題

在同時(shí)使用MTS(slave_parallel_workers > 1)時(shí),即使按上面crash safe slave的要求設(shè)置了基于GTID的復(fù)制代嗤,Slave crash后再重啟還是會(huì)導(dǎo)致復(fù)制中斷硝逢。

通過(guò)強(qiáng)制殺掉MySQL所在虛機(jī)的方式模擬Slave宕機(jī),然后再啟動(dòng)MySQL憨奸,MySQL日志中有如下錯(cuò)誤消息:
啟動(dòng)slave時(shí)也會(huì)報(bào)錯(cuò)

mysql> start slave;
ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository

出現(xiàn)這種現(xiàn)象的原因在于额各,relay_log_recovery=1 且 slave_parallel_workers>1的情況下傲醉,mysql啟動(dòng)時(shí)會(huì)進(jìn)入MTS Group恢復(fù)流程,即讀取relay log逻悠,嘗試填補(bǔ)由于多線(xiàn)程復(fù)制導(dǎo)致的gap饥伊。然后relay log文件由于不是實(shí)時(shí)刷新的茫因,在relay log文件中找不到gap對(duì)應(yīng)的relay log記錄(覆蓋了gap的relay log起始和結(jié)束位置分別被稱(chēng)為低水位和高水位,低水位點(diǎn)即slave_relay_log_info.Relay_log_pos的值)就會(huì)報(bào)這個(gè)錯(cuò)翼雀。

實(shí)際上狈邑,在GTID模式下城须,slave在apply event的時(shí)候可以跳過(guò)重復(fù)事件,所以可以安全的從低水位點(diǎn)應(yīng)用日志米苹,沒(méi)必要解析relay log文件糕伐。 這看上去是一個(gè)bug,于是提交了一個(gè)bug報(bào)告#83713蘸嘶,目前還沒(méi)有收到回復(fù)良瞧。

作為回避方法,可以通過(guò)清除relay log文件训唱,跳過(guò)這個(gè)錯(cuò)誤褥蚯。執(zhí)行步驟如下:

reset slave;
change master to MASTER_AUTO_POSITION = 1
start slave;

在這里,單純的調(diào)reset slave不能把狀態(tài)清理干凈况增,內(nèi)部的Relay_log_info.inited標(biāo)志位仍然處于未被初始化狀態(tài),此時(shí)調(diào)用start slave仍然會(huì)失敗赞庶。因此需要補(bǔ)一刀change master。

6澳骤、Master的crash safe

前面一直在講crash safe slave歧强,Master的crash safe同樣重要。 要想Master保持crash safe需要按下面的參數(shù)進(jìn)行設(shè)置为肮,否則不僅會(huì)丟失事務(wù)摊册,gtid_executed還可能和實(shí)際的innodb存儲(chǔ)引擎中的數(shù)據(jù)不一致。

sync_binlog = 1
innodb_flush_log_at_trx_commit = 1

在Master配置為"雙1"的情況下弥锄,Master crash后丧靡,如果沒(méi)有發(fā)生failover蟆沫,可以繼續(xù)作為Master籽暇。 如果發(fā)生了failover,可以檢查舊Master和新Master上由舊Master執(zhí)行的事務(wù)集合是否一致饭庞。
show master status

如果一致戒悠,可以按MASTER_AUTO_POSITION = 1的方式將舊Master作為Slave和新Master建立復(fù)制關(guān)系。否則舟山,考慮做事務(wù)補(bǔ)償或從新Master上拉取備份進(jìn)行恢復(fù)绸狐。

在Master配置不是"雙1"的情況下,在Master crash后由于難以準(zhǔn)確知道舊Master上究竟執(zhí)行了哪些事務(wù)累盗,安全的做法是實(shí)施主備切換寒矿,并從新Master上拉取備份,把舊Master作為新Master的Slave進(jìn)行恢復(fù)若债。
文章轉(zhuǎn)載https://www.cnblogs.com/icyblog/p/7241040.htm

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末符相,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌啊终,老刑警劉巖镜豹,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蓝牲,居然都是意外死亡趟脂,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)例衍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)昔期,“玉大人,你說(shuō)我怎么就攤上這事佛玄≌蚓欤” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵翎嫡,是天一觀的道長(zhǎng)欠动。 經(jīng)常有香客問(wèn)我,道長(zhǎng)惑申,這世上最難降的妖魔是什么具伍? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮圈驼,結(jié)果婚禮上人芽,老公的妹妹穿的比我還像新娘。我一直安慰自己绩脆,他們只是感情好萤厅,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著靴迫,像睡著了一般惕味。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上玉锌,一...
    開(kāi)封第一講書(shū)人閱讀 49,821評(píng)論 1 290
  • 那天名挥,我揣著相機(jī)與錄音,去河邊找鬼主守。 笑死禀倔,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的参淫。 我是一名探鬼主播救湖,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼涎才!你這毒婦竟也來(lái)了鞋既?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎涛救,沒(méi)想到半個(gè)月后畏邢,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡检吆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年舒萎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蹭沛。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡臂寝,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出摊灭,到底是詐尸還是另有隱情咆贬,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布帚呼,位于F島的核電站掏缎,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏煤杀。R本人自食惡果不足惜眷蜈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望沈自。 院中可真熱鬧酌儒,春花似錦、人聲如沸枯途。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)酪夷。三九已至榴啸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間捶索,已是汗流浹背插掂。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工灰瞻, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留腥例,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓酝润,卻偏偏與公主長(zhǎng)得像燎竖,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子要销,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容