1. 程式人生 > 其它 >MySQL 傳統複製中常見故障處理和結構優化案例分析

MySQL 傳統複製中常見故障處理和結構優化案例分析

雖然MySQL5.7 的主從複製已經很穩定了,但在備庫可讀寫的情況下,總是會出現部分資料不一致的情況,例如常見的1062、1032和1050錯誤。下面就介紹下這類報錯的常見處理方法和常見主從複製結構的調整。

環境描述

  • 1、mysql 5.7 以上,
  • 2、binlog format 是row格式(5.7預設)
  • 3、傳統複製(生產強烈推薦使用gtid)
  • 4、log-bin , log_slave_updates 開啟
  • 5、複製結構:101:3306> 103:3306 > 104:3306

常見主從複製報錯

1、表重複錯誤: 1050

從庫已經有T2表,再在主庫上建立T2. 處理原則:以主庫為準,在從庫上drop t2。 然後重啟slave。

注意: 在db裡的操作都會記錄到binlog中,如果不想被記錄到binlog中,可以先set sql_log_bin=0.drop完成後,再 set sql_log_bin=1即可。

從5.7 開始,有super read only。

處理方法:

從庫操作:

set sql_log_bin=0;

drop table t2;

set sql_log_bin=1;

start slave;

show slave status;

2、主鍵衝突: 1062

處理方法:

從庫操作:

set sql_log_bin=0;

delete from t2 where id =2;

set sql_log_bin=1;

start slave;

show slave status;

3、主庫上更新後,從庫找不到記錄 :1032

這時需要解析主庫的binlog,把從庫的資料補回來。

這裡就能看到從庫丟失的那條記錄。然後在從庫補充這條記錄即可。

處理方法:

從庫操作:

set sql_log_bin=0;

insert into t2 (id) values (2);

set sql_log_bin=1;

start slave;

show slave status;

4、主庫上delete後,從庫找不到記錄: 1032

想看某段pos內執行過的sql: 主庫執行:

mysqlbinlog --base64-output=decode-rows -v --start-position=2465 
--stop-position=2748 mysql-bin.000050 > 50.sql

輸出如下:

### DELETE FROM `wubx`.`wubx`
### WHERE
###   @1=2###   @2='wubx'
ROLLBACK /* added by mysqlbinlog */ /*!*/; 

注意這裡的rollback。如果以後基於binlog和時間點的恢復。這條資料會被rollback掉,造成一條資料的丟失。所以如果想保留這條資料,需要找到commit的位置,或者下個pos的位置。

處理方法:

從庫操作:

slave stop;

SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1 #跳過一個事務

slave start

常見覆制結構調整

1、一主一從,新增從庫

st=>operation: M 101:3306
e=>end
op=>operation: S1 103:3306
 
st->op->op1

調整為,級聯或星型結構

st=>operation: M 101:3306
e=>end
op=>operation: S1 103:3306
op1=>operation: S11 104:3306
 
st->op->op1

2、級聯複製調整

從103.3306 dump資料

mysqldump --single-transaction --master-data=2 -uroot -p123456  -A -S 
/tmp/mysql3306.sock

104 匯入資料

mysql -S /tmp/mysql3306.sock -uroot -p123456 < /tmp/1203.sql

change 104 到103

change master to master_host='192.168.56.103', master_user='repl', 
master_password='repl4slave', master_port=3306, 
MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=4138, 
master_connect_retry=10;

101 插入測試資料

insert into t2 values (200);

101 持續insert

for ((i=1;i<=1000000;i++))
do

mysql -S /tmp/mysql3306.sock -uroot -p123456 -e 
"insert into enmo.t2 values($i)"done

關閉103 主機,並檢查104 slave 狀態

主從的binlog 都會記錄主庫的server id 和timestamp資訊。可以根據這2個資訊去定位相應的pos資訊。

101:3306

104:3306

這裡可以看到101 結束 insert 1419後,並commit的 pos 是387204,所以104 change 的pos 可以選擇到387204這裡。但是如果104沒有把1419 這條記錄commit的話,就要選擇101 開始 insert 1419 這個事務之間的pos:387020.

104 change 到101

change master to master_host='192.168.56.103', 
master_user='repl', master_password='repl4slave', 
master_port=3306,  MASTER_LOG_FILE='mysql-bin.000093', 
MASTER_LOG_POS=387204, master_connect_retry=10;

作者介紹

張燦 雲和恩墨技術顧問

2015年12月加入雲和恩墨,擅長oracle、mysql資料庫,shell、python指令碼。