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
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 errors 和 key-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。