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指令碼。