有同事反饋他們搭建的MySQL庫主從同步報錯了,需要協助幫忙修復。檢查同步報錯如下
可以看到是由於兩邊數據不一致,主庫host表的某條數據在從庫不存在,導致同步時執行update報錯。
修復的原理很簡單,找到主從不一致的這條數據,在從庫補上,讓update能執行就好。由於需要從binlog裏找數據,需要確保中斷之後的binlog沒被刪除,否則就只能重搭了。
1. 主庫查詢對應binlog記錄
注意如果裝了多個版本的mysql,mysqlbinlog命令需要寫全路徑。其中stop-position和binlog名就對應的是前面報錯中的信息。生成的文件可能比較大,最慢的情況下會跟這個binlog文件一樣大,需要等一會。
mysqlbinlog -v --stop-position=537973695 /binlog_path/mysql-bin.000001 > /tmpbinlog.log
2. 查詢記錄end_log_pos=537973695所在位置,找到對應update語句
當然如果生成的文件很小可以直接打開搜索,但處理的時候文件有2G,顯然不合適
cat tmpbinlog.log | awk '/end_log_pos 537973695/ {print NR}'
#輸出所在行數爲:68381343
#查看其前後行(50行左右差不多夠了),找出其對應的sql語句
cat tmpbinlog.log | awk 'NR==68381330,NR==68381380'
hosts表第一個字段是主鍵hostid,拿該條件來查即可,查完發現從庫果然沒有
--從庫查詢
select hostid from hosts where hostid = 18013;
Empty set (0.00 sec)
3. 數據修復
如果表結構和值特別簡單,可以直接寫insert語句在從庫插入。
如果較爲複雜,則在主庫創建臨時表並dump,在從庫執行dump文件中的insert語句。
主庫執行
create table tmphost like hosts;
insert into tmphost select * from hosts where hostid=18013;
commit
dump數據
mysqldump -uroot -p zabbix tmphost > tmphost.sql
找到對應insert語句並在從庫執行
4. 恢復同步
stop slave;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; -- 跳過一個事務,可選
start slave;
show slave status\G;
如果沒有其他報錯,主從同步就順利恢復啦~
參考