咱們知道生產環境中常常會遇到MySQL主從延遲問題,從原理上也能看出主庫的事務提交是併發模式,而從庫只有一個SQL線程負責解析,因此自己上就可能存在延遲。sql
基本原理
MySQL主從複製實際上基於二進制日誌,Mysql 中主從複製時有兩個很重要的日誌文件:binlog(二進制日誌文件),relay log(中繼日誌文件),基本原理看圖片
安全
配置好了, 在主從同步過程當中, 主服務器會把更新語句寫入binlog, 從服務器的IO 線程(這裏要注意, 5.6.3 以前的IO線程僅有一個,5.6.3以後的有多線程去讀了,速度天然也就加快了)回去讀取主服務器的binlog 而且寫到從服務器的Relay log 裏面,而後從服務器的 的SQL thread 會一個一個執行 relay log 裏面的sql , 進行數據恢復。服務器
1. 主從同步的延遲的緣由
一個服務器開放N個連接給客戶端來鏈接的, 這樣有會有大併發的更新操做, 可是從服務器的裏面讀取binlog 的線程僅有一個, 當某個SQL在從服務器上執行的時間稍長 或者因爲某個SQL要進行鎖表就會致使,主服務器的SQL大量積壓,未被同步到從服務器裏。這就致使了主從不一致, 也就是主從延遲。微信
隨機重放
Mysql 主庫中寫 binlog 的操做是順序寫的,以前咱們提到過,磁盤的順序讀寫速度是很快的。一樣的,從庫中的 I/O 線程操做日誌的速度效率也是很高的。可是別忘了,還有一個 SQL 線程來進行數據重放,而重放的過程是隨機寫盤的。到這裏你應該就明白了吧,某一時刻 relay log 裏的數據來不及重放進從庫,就會產生主從延遲的狀況。多線程
主庫併發高
知道了從庫中 SQL 線程的重放狀況,對於主庫併發高致使主從延遲確定就不難理解了。某一時刻,大量寫請求打到主庫上,意味着要不斷對 binlog 進行寫入,此時從庫中的 SQL 線程就會目不暇接,天然會產生主從延遲。併發
鎖等待
對於 SQL 單線程來講,當遇到阻塞時就會一直等待,直到執行成功纔會繼續進行。若是某一時刻從庫由於查詢產生了鎖等待的狀況,此時只有當前的操做執行完成後纔會進行下面的操做,同理也就產生了主從延遲的狀況。線程
2. 主從同步延遲的解決辦法
實際上主從同步延遲根本沒有什麼一招制敵的辦法, 由於全部的SQL必須都要在從服務器裏面執行一遍,可是主服務器若是不斷的有更新操做源源不斷的寫入, 那麼一旦有延遲產生, 那麼延遲加劇的可能性就會原來越大。固然咱們能夠作一些緩解的措施。日誌
改變參數設置
由於主服務器要負責更新操做, 它對安全性的要求比從服務器高, 全部有些設置能夠修改,好比sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之類的設置,而slave則不須要這麼高的數據安全,徹底能夠講sync_binlog設置爲0或者關閉binlog,innodb_flushlog, innodb_flush_log_at_trx_commit 也 能夠設置爲0來提升sql的執行效率 這個能很大程度上提升效率。另外就是使用比主庫更好的硬件設備做爲slave。blog
從服務器做備份使用
把一臺從服務器看成備份使用, 而不提供查詢, 那邊他的負載下來了, 執行relay log 裏面的SQL效率天然就高了。圖片
增長從服務器
這個目的仍是分散讀的壓力, 從而下降服務器負載。
3. 判斷主從延遲的方法
MySQL提供了從服務器狀態命令,能夠經過 show slave status 進行查看, 好比能夠看看Seconds_Behind_Master參數的值來判斷,是否有發生主從延時。
其值有這麼幾種:
NULL - 表示io_thread或是sql_thread有任何一個發生故障,也就是該線程的Running狀態是No,而非Yes.
0 - 該值爲零,是咱們極爲渴望看到的狀況,表示主從複製狀態正常
注:本文轉載自【PHP自學中心】微信公衆號