一主多重的切換正確性:
1、基于位點的主備切換
通常情況下,在切換任務的時候,要先主動跳過這些錯誤,有兩種常用的方法:
1、主動跳過一個事物,跳過的命令的寫法是:
set global sql_slave_skip_counter=1;
start slave;
因為切換過程中,可能會不止重復執(zhí)行一個事物,所以需要在從庫持續(xù)觀察,每次碰到這些錯誤就停下來,執(zhí)行一次跳過命令,直到不再出現(xiàn)停下來的情況,以此來跳過可能涉及的所有事務。
2、通過設置slave_skip_errors參數(shù),直接設置跳過指定的錯誤:
在執(zhí)行主備切換時,有這么兩類錯誤,是經(jīng)常會遇到的:
1062 錯誤是插入數(shù)據(jù)時唯一鍵沖突;
1032錯誤是刪除數(shù)據(jù)時找不到行。
因此,可以把slave_skip_errors設置為“1032,1062”,這樣中間碰到這兩個錯誤時就直接跳過
2、GTID
通過sql_slave_skip_counter跳過事務和通過slave_skip_errors 忽略錯誤的方法,雖然都最終可以建立從庫B和主庫A'的主備關系,但這兩種操作都很復雜,而且容易出錯,所以MySQL5.6版本引入了GTID,徹底解決了這個困難。
GTID的全程是Global Transaction Identifier,也就是全局事務ID,是一個事務在提交的時候生成的,是這個事務的唯一標識。它由兩部分組成,格式是:GTID=server_uuid:gno.
其中:server_uuid是一個實例第一次啟動時自動生成的,是一個全局唯一的值;
gno是一個整數(shù),初始值是1,每次提交事務的時候分配給這個事務,并加1.
在MySQL的官方文檔里,GTID格式是這么定義的:
GTID=source_id:transaction_id
GTID模式的啟動:在啟動一個MySQL實例的時候,加上參數(shù)gtid_mode=on 和enforce_gtid_consistency=on。
在GTID模式下,每個事務都會跟一個GTID——對應。這個GTID有兩種生成方式,而使用哪種方式取決于session變量gtid_next的值。
1、如果gtid_next=automatic,代表使用默認值。這時,MySQL就會把server_uuid:gno分配給這個事務? ?。
? ? a、記錄binlog的時候,先記錄一行 SET @@SESSION.GTID_NEXT='server_uuid:gno';
? ? b、把這個GTID加入本實例的GTID集合。
2、 如果gtid_next是一個指定的GTID的值,比如通過set gtid_next='current_gtid'指定為current_gtid,那么就有兩種可能:
? ? a、如果current_gtid已經(jīng)存在于實例的GTID集合中,接下來執(zhí)行的這個事務會直接被系統(tǒng)忽略;
? ? b、如果current_gtid沒有存在于實例的GTID集合中,就將這個current_gtid分配給接下來要執(zhí)行的事務,也就是說系統(tǒng)不需要給這個事務生成新的GTID,因此gno也不用加1
GTID實例:
CREATE TABLE `t` (
? `id` int(11) NOT NULL,
? `c` int(11) DEFAULT NULL,
? PRIMARY KEY (`id`)
) ENGINE=InnoDB;
insert into t values(1,1);
假設,現(xiàn)在這個實例X是另外一個實例Y的從庫,并且此時在實例Y上執(zhí)行了下面這條語句:
insert into t values(1,1);
并且,這條語句在實例Y上的GTID是: aaaaaaaa-cccc-dddd-eeee-ffffffffffff:10.
那么,實例X作為Y的從庫,就要同步這個事務過來執(zhí)行,顯然會出現(xiàn)主鍵沖突,導致實例X的同步線程停止。
處理方法就是,可以執(zhí)行下面的這個語句序列:
set gtid_next='aaaaaaaa-cccc-dddd-eeee-ffffffffffff:10';?
begin; commit;?
set gtid_next=automatic;?
start slave;???
其中,前三條語句的作用,是通過提交一個空事務,把這個GTID加到實例X的GTID集合中。這樣,再執(zhí)行start slave命令讓同步縣城執(zhí)行起來的時候,雖然實例X上還是會繼續(xù)執(zhí)行實例Y傳過來的事務,但是由于 'aaaaaaaa-cccc-dddd-eeee-ffffffffffff:10'已經(jīng)存在于實例X的GTID集合中了,所以實例X就會直接跳過這個事務,就不會再出現(xiàn)主鍵沖突的錯誤。
在上面的這個語句序列中,start slave命令之前還有一句 set gtid_next=automatic。這句話的作用是“恢復GTID的默認分配行為”,也就是說如果之后有新的事務再執(zhí)行,就還是按照原來的分配方式,繼續(xù)分配gno=3.