在使用Mysql的主從複製架構中,有兩個比較頭疼的問題:mysql
一、主從數據不一樣步後如何處理sql
二、主從同步延遲問題如何解決數據庫
本文將根據實際案例來分析下問題1,至於問題2多數文檔介紹的辦法是啓用多線程複製來解決,言歸正傳,這裏的問題1還能夠細分紅兩種狀況。session
一、Slave_IO_Running和Slave_SQL_Running在YES情況下,主從數據不一樣步如何處理?多線程
二、Slave_SQL_Running在NO狀況下,主從數據不一樣步如何處理?架構
出現第一種狀況一般緣由是手工去修改了從庫的數據致使主從數據不一致,這種狀況若是不及時處理,當主庫也更新了對應的數據的時候,就會演變爲第二種狀況。app
舉個例子:dom
在一主一從的條件下,當前主從的數據是同步的。ide
人爲去操做從庫的某張表數據,本例中以asm_user表爲演示,其中id字段爲主鍵工具
mysql> insert into test.asm_user (id,name,salary) values (1,'a',10000);
當主庫的這條數據未變更的時候,當前主從同步進程中Slave_IO_Running和Slave_SQL_Running仍是爲YES,目前只是asm_user這張表的數據不一樣步而已,對應其餘schema上的數據仍是會保持主從同步;
但若是這個狀況,主庫執行相同的SQL語句:
mysql> insert into test.asm_user (id,name,salary) values (1,'a',10000);
對應的SQL apply到從庫的時候就會發現duplicate key,這個時候主從的同步就會中止掉。
# tail -f /home/mydata/localhost.localdomain.err
這種狀況下,通常咱們採用maatkit工具來校驗主從數據庫的數據差別狀況。
這個辦法其實回答了前面的問題1,Slave_IO_Running和Slave_SQL_Running在YES狀況下,主從數據不一樣步如何處理?
# yum -y install perl-TermReadKey # wget ftp://ftp.netbsd.org/pub/pkgsrc/distfiles/maatkit-7540.tar.gz # tar -zxvpf maatkit-7540.tar.gz # cd maatkit-7540 # perl Makefile.PL # make && make install # mk-table-checksum h=192.168.115.6,u=root,p=123456,P=3306 \ h=192.168.115.7,u=root,p=123456,P=3306 -d test | mk-checksum-filter # mk-table-checksum h=192.168.115.6,u=root,p=123456,P=3306 \ h=192.168.115.7,u=root,p=123456,P=3306 -d test
若是主從數據不一致則採用mk-table-sync進行數據同步
# mk-table-sync --execute --print --no-check-slave --transaction --databases test \ h=192.168.115.6,u=root,p=123456 h=192.168.115.7,u=root,p=123456
很明顯當前test庫數據是一致的,目前主從同步這個錯誤是能夠忽略的,所以咱們採用跳過這個事務的辦法來處理主從數據庫不一樣步問題。一般在生產環境中,主庫的數據是不斷的更新的,這裏咱們在主從數據不一樣步的狀況下在主庫繼續插入一條數據,方便後續驗證。
下面咱們開始處理主從不一樣步問題:
在未啓用GTID複製的狀況下采用下面的方法跳過事務:
mysql>slave stop; mysql>SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; //跳過一個事務 mysql>slave start;
Mysql5.6以後支持GTID複製,開啓GTID複製的好處不少,具體能夠百度一下!但當開啓gtid後就不能採用前面那種辦法來跳過事務。
在show slave status \G;輸出中的最後幾條裏面,
Retrieved_Gtid_Set項:記錄了relay日誌從Master獲取了binlog日誌的位置
Executed_Gtid_Set項:記錄本機執行的binlog日誌位置(若是是從機,包括Master的binlog日誌位置和slave自己的binlog日誌位置)
咱們要跳過事務的GTID在錯誤日誌中有記錄
# tail -f /home/mydata/localhost.localdomain.err
mysql> set session gtid_next='bd9e9912-2bc7-11e6-bade-000c29b8871c:1440'; mysql> begin;commit; mysql> set session gtid_next=automatic;
mysql> start slave; mysql> show slave status \G;
驗證從庫數據是否和主庫一致
mysql> select * from test.asm_user;
前面模擬了Slave_SQL_Running在NO狀況下,主從數據不一樣步狀況的處理過程,在現實的環境中,每每狀況要複雜的多,下面分享一則內存開發庫由於斷電致使主從數據不一致的故障處理:
一、由於電源故障,致使主從數據庫所有宕機,電源恢復後,主庫啓動正常,從庫沒法啓動,經過分析日誌發現多是電源故障致使從庫的固態盤異常,許多的binlog文件權限出現???,這些文件甚至沒法正常查看
一、經過fsck -y進行文件系統校驗修復壞塊,修復完成後從庫數據庫能夠啓動,但開啓複製進程的時候報中繼日誌丟失
二、在沒有辦法的狀況下,採用主庫dump數據,從庫從新source的辦法在線重作主從數據同步。整個操做過程當中,主庫的數據不斷的寫入。
下面是大體的步驟:
3.1、主庫導出全庫數據,注意必定要使用--single-transaction參數
# /usr/local/mysql/bin/mysqldump --all-databases --single-transaction --triggers --routines > /tmp/1.sql
3.2、將備份文件拷貝到從庫進行source
3.3、開啓從庫的複製進程
mysql> change master to master_host='192.168.1.15',
master_user='rep1',master_password='123456',MASTER_AUTO_POSITION=1;
mysql> start slave;