1. 程式人生 > 其它 >MySQL-跳過主從複製環境中錯誤

MySQL-跳過主從複製環境中錯誤

跳過主從複製環境的錯誤,恢復同步狀態

簡述

mysql在主從複製過程中,由於各種的原因,從庫可能會遇到執行BINLOG中的SQL出錯的情況,在預設情況下,將停止複製程序,不再進行同步,等到人工干預來處理。

slave-skip-errors

slave-skip-errors的作用就是用來定義複製過程中從庫可以自動跳過的錯誤號,當複製過程中遇到定義的錯誤號,就可以自動跳過,直接執行後面的SQL語句。

--slave-skip-errors=[err_code1,err_code2,...|all|ddl_exist_errors]

全域性靜態引數,不可動態修改

引數值

  • OFF: 預設值

  • [list of error codes]:

  • all:忽略所有錯誤訊息並繼續執行。無法保證資料的完整性

  • ddl_exist_errors:

    • 等價於錯誤程式碼列表 1007,1008,1050,1051,1054,1060,1061,1068,1094,1146
常見錯誤號
  • 1007:資料庫已存在,建立資料庫失敗
  • 1008:資料庫不存在,刪除資料庫失敗
  • 1050:資料表已存在,建立資料表失敗
  • 1051:資料表不存在,刪除資料表失敗
  • 1054:欄位不存在,或程式檔案跟資料庫有衝突
  • 1060:欄位重複,導致無法插入
  • 1061:重複鍵名
  • 1068:定義了多個主鍵
  • 1094:位置執行緒ID
  • 1146:資料表缺失,請恢復資料庫
  • 1053:複製過程中主伺服器宕機
  • 1062:主鍵衝突 Duplicate entry '%s' for key %d

示例

--slave-skip-errors=1062,1053
--slave-skip-errors=all
--slave-skip-errors=ddl_exist_errors

檢視當前引數值

show variables like 'slave_skip_errors';

sql_slave_skip_counter

sql_slave_skip_counter引數用於複製過程中從庫可以自動跳過N個events。該引數不會立即生效,它從下一個START REPLICA開始生效。

從MySQL 8.0.26開始,sql_slave_skip_counter 已經被 sql_replica_skip_counter

引數取代,已棄用sql_slave_skip_counter。

START REPLICA

START REPLICA [thread_types] [until_option] [connection_options] [channel_option]

thread_types:
    [thread_type [, thread_type] ... ]

thread_type:
    IO_THREAD | SQL_THREAD

until_option:
    UNTIL {   {SQL_BEFORE_GTIDS | SQL_AFTER_GTIDS} = gtid_set
          |   MASTER_LOG_FILE = 'log_name', MASTER_LOG_POS = log_pos
          |   SOURCE_LOG_FILE = 'log_name', SOURCE_LOG_POS = log_pos
          |   RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos
          |   SQL_AFTER_MTS_GAPS  }

connection_options:
    [USER='user_name'] [PASSWORD='user_pass'] [DEFAULT_AUTH='plugin_name'] [PLUGIN_DIR='plugin_dir']


channel_option:
    FOR CHANNEL channel

gtid_set:
    uuid_set [, uuid_set] ...
    | ''

uuid_set:
    uuid:interval[:interval]...

uuid:
    hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh

h:
    [0-9,A-F]

interval:
    n[-n]

    (n >= 1)

MySQL 8.0.22 開始,start slave已經被start replica取代,此版本已棄用start slave。在8.0.22以前版本使用start slave

取值範圍

sql_slave_skip_counter 引數的取值範圍:[0, 4294967295]

注意:

  • sql_slave_skip_counter 引數與基於 GTID 的複製不相容,並且在設定 gtid_mode=ON 時不得將其設定為非零值

示例

-- 在Slave跳過一個 Update_rows event 複製
set global sql_slave_skip_counter=1;
start slave sql_thread;

show slave status\G

slave_exec_mode

slave_exec_mode 控制複製執行緒如何解決複製期間的衝突和錯誤。 設定此變數會立即對所有複製通道生效,包括正在執行的通道。

從MySQL 8.0.26開始,slave_exec_mode 已經被 replica_exec_mode 引數取代

引數值

  • IDEMPOTENT:忽略 duplicate-key errorskey-not-found errors 錯誤。即:可以讓從庫避免1032(從庫上不存在的鍵)和1062(重複鍵,需要存在主鍵或則唯一鍵)的錯誤

    • 主要用於多主複製和NDB CLUSTER的環境
  • STRICT: 嚴格模式,不會跳過任何錯誤。(MySQL Server 8.0 預設值)

示例

使用slave_skip_errors跳過複製錯誤

建立測試資料

create table tb1 (id int not null primary key, name varchar(10));  

insert into tb1 values (1, 'test1');id
insert into tb1 values (2, 'test2');
commit;

模擬故障

從庫插入一條記錄
insert into tb1 values (3, 'test3');
commit;
主庫執行相同的操作
insert into tb1 values (3, 'test3');
commit;

檢視從庫複製狀態

show slave status \G

處理

方案1:從庫配置引數啟動
/usr/local/mysql/bin/mysqld_safe --user=mysql --basedir=/usr/local/mysql --datadir=/data --slave-skip-errors=1062 &
方案2:修改my.cnf檔案

在my.cnf中加入如下選項,則可跳過此錯誤,資料同步繼續進行

[mysqld]  
slave_skip_errors=1062
# DDL 衝突
# slave_skip_errors=ddl_exist_errors
注意事項
  • 處理不當,很可能造成主從資料庫的資料不一致

使用sql_slave_skip_counter引數跳過複製錯誤

模擬故障

slave庫刪除一條記錄
DELETE FROM `tb1` WHERE `id` = 2;
commit;
主庫剛好也執行刪除同一條記錄的事務
BEGIN;
DELETE FROM tb1 WHERE id = 2;
insert into tb1 values (5, 'test5');
COMMIT;

檢查slave狀態

show slave status\G

處理

在Master上檢視對應的position操作
show binlog events in 'mysql-bin.000002' from 6840;
slave上處理跳過一個事務
set global sql_slave_skip_counter=1;
start slave sql_thread;

show slave status\G

在使用sql_slave_skip_counter跳過由多條SQL(event)組成的事務時,雖然主從複製恢復了,但是資料仍處於不一致狀態,要抓緊時間補齊資料或重做Slave

可以配合slave_exec_mode引數一起使用,就可以達到只跳過由多個SQL語句組成單個事務中有問題的event。