1. 程式人生 > >【MySQL】【復制】利用slave_exec_mode處理復制過程中出現的1062與1032錯誤

【MySQL】【復制】利用slave_exec_mode處理復制過程中出現的1062與1032錯誤

cati 事務 thead 組成 .cn 推薦 ren 報錯 引入

背景:

? 今天張師兄在群裏問了主從之間出現1032錯誤後,使用pt-slave-restart跳過後又出現了1062錯誤,該如何快速處理。

問題解析:

? 1032錯誤:主庫傳遞過來的binlog中包含了刪除某些數據的語句,但在從庫中部分數據或者全部這些數據被提前手工刪除了,或者根本就不存在。

? 1062錯誤:主庫傳遞過來的binlog中包含了更新(或插入)某些數據的語句,但在從庫中部分數據已經存在,或者被其他的數據占據了唯一性索引的入口。

? 問題出在binlog重放時是以一個事務作為一個原子單位進行重放。正如原子中是由三個誇克組成一樣,一個事務一般也會由若幹個event組成。一個event視為一條語句。

? 若主庫傳過來一個包含刪除三行數據(r1,r2,r3)的事務,但在從庫中只有兩個個對應的行(r1,r2)。

begin;
delete from t1 where row=r3; #假設row列為唯一性索引
delete from t1 where row=r2;
delete from t1 where row=r1;
commit;

? 那麽當執行第一條的時候,從庫就會報1032 delete a not exist row錯誤。使用Pt-slave-restart --error-numbers=1032 就會把這整個事務都跳過去,導致後面的r1,r2行都沒有被刪除。下一次若從主庫傳來

begin;
insert into t1(row) values(r1,r2)
commit;

? 那麽從庫執行插入的時候肯定會報1062 duplicate entry錯誤。

問題處理:

方法一:

? 使用Pt-table-sync進行主從數據同步,但是在雙主條件或者主庫相關表不停的更新的狀況下,這種數據同步會導致比較致命的數據混亂。

方法二:

? 使用slave_exec_mode參數。

? 先看下官方手冊描述:

參數名稱: slave_exec_mode
變量範圍: 全局
動態修改:
默認值: NDB集群默認IDEMPOTENT,其他模式STRICT
有效值: STRICT/IDEMPOTENT
設置方式: SET GLOBAL slave_exec_mode = ‘IDEMPOTENT‘

? Controls how a slave thread resolves conflicts and errors during replication. IDEMPOTENT mode
causes suppression of duplicate-key and no-key-found errors; STRICT means no such suppression
takes place.
IDEMPOTENT mode is intended for use in multi-master replication, circular replication, and some
other special replication scenarios for NDB Cluster Replication

? 此參數最初作為在NDB模式中被引進,後來在多主和環形復制都有用武之地。主要的作用就是在slave_exec_mode=‘IDEMPOTENT時,slave會忽略在插入時的遇到重復的唯一性索引節點和刪除時的未發現對應記錄的復制錯誤即1062和1032。但是,當從庫從 主庫接收到了一條嘗試update一條自己不存在的記錄時還是會報錯1032。

? 問題到此就很簡單了,應進行如下步驟:

stop slave;
SET GLOBAL  slave_exec_mode = ‘IDEMPOTENT‘
start slave;

? 再次show slave status\G 應該可以看到從庫的復制SQL線程已經恢復正常。

? 但是這畢竟是非常規手段,在執行完後且主從一致後,應抽空進行數據校驗。且不推薦作為默認參數直接打開。

附:

5.7.0以後可以將idempotent作為mysqld啟動參數調用,即:mysqld --defaults-file =my.cnf --indempotent& 當然,也可以將其寫入my.cnf中。

? --idempotent
Tell the MySQL Server to use idempotent mode while processing updates; this causes suppression
of any duplicate-key or key-not-found errors that the server encounters in the current session while
processing updates. This option may prove useful whenever it is desirable or necessary to replay
one or more binary logs to a MySQL Server which may not contain all of the data to which the logs
refer.
The scope of effect for this option includes the current mysqlbinlog client and session only.
The --idempotent option was introduced in MySQL 5.7.0.

5.7.1以後可以引入了此參數的會話級別版 rbr_exec_mode,只對當前會話生效,且限制行復制模式。

? rbr_exec_mode
This variable switches the server between IDEMPOTENT mode and STRICT mode. IDEMPOTENT
mode causes suppression of duplicate-key and no-key-found errors. This mode is useful when
replaying a row-based binary log on a server that causes conflicts with existing data. mysqlbinlog
uses this mode when you set the --idempotent option by writing the following to the output:
SET SESSION RBR_EXEC_MODE=IDEMPOTENT;

【MySQL】【復制】利用slave_exec_mode處理復制過程中出現的1062與1032錯誤