一、環境及問題:
兩台redhat 服務器A和B 上各跑着mysql5.6, 互為主備,使用虛地址對外提供服務。虛地址一直在A主機上,某天單獨連B庫發現,數據與A庫不一致,一開始以為認為更改,但是人為更改也會同步至另外一個庫的啊,所以應該是同步出問題導致的。
二、原因及解決
原因:
在A庫上執行show slave status,查看Slave_IO_Running 和Slave_SQL_Running都是YES,在B庫上查看這兩個也是YES,至少數據庫是同步的。
但是在B庫上執行show slave status,發現Seconds_Behind_Master很大,算下來2天多,根據兩個庫的數據更新時間字段來看,正好差2天多。
應該是同步延時導致的數據不一致。
解決:
本想着重啟下兩個庫,看看是否能解決,但想着這也不是根本辦法,時間長了還會同步延時的,繼續查找。。。
執行show processlist 查看線程,select * from information_schema.processlist where command <> 'sleep' 發現A庫上一直有update XXtabele 的語句執行,該語句為業務的正常操作。
show index from database.tables(表名)查看該表,沒有建索引。update該表的時候應該是全表掃描,比較耗時。
對該表增加組合索引,延時問題解決。
三、mysql主備同步原理(拷貝別人的哈)
mysql在主庫上記錄binlog。在准備提交事務完成數據更新前,主庫把數據更新的事件記錄到binlog中。 mysql通過上面說的binlog用3個線程來實現主從同步,master上的Binlog Dump Thread
, slave上的Slave I/O Thread
和Slave SQL Thread
- Slave I/O Thread: I/O線程跟主庫建立一個普通的客戶端連接,並請求從指定日志文件的指定位置(或者從最開始的日志)之后的日志內容, 存到relaylog中, 然后將讀取到的主庫binlog的文件名和位置記錄到master-info文件中
- Binlog Dump Thread: 讀取主庫上的binlog中的事件,根據請求信息讀取制定日志指定位置之后的日志信息,返回給
Slave I/O Thread
。返回信息中除了日志所包含的信息之外,還包括本次返回的信息已經到Master端的binlog文件的名稱以及binlog的位置。 - Slave SQL Thread: 從relaylog中讀取事件並且在從庫執行,從而實現從庫的更新