1. 程式人生 > >mysql主從複製延遲問題的相關知識與解決方案

mysql主從複製延遲問題的相關知識與解決方案

一、如何監控發生了主從延遲?

在從庫機器上,執行show slave status,檢視Seconds_Behind_Master值,代表主從同步從庫落後主庫的時間,單位為秒,若同從同步無延遲,這個值為0。

Mysql主從延遲一個重要的原因之一是:mysql是以單執行緒序列執行。

主從複製資料時,在從伺服器上的mysql,是一個執行緒在同步資料。

序列的方式,它是指,執行一個後才繼續執行下一個。如果一個卡住了,要等待時間,才會繼續下一個。序列與並行是相反的。

二、同步延遲發生的場景

當主庫的TPS併發較高時,產生的DDL(修改類的sql語句)數量,超過了slave機器sql執行緒所能承受的能力,那麼延時就會產生了。

主庫寫binlog日誌到檔案的時候,是順序寫入到磁碟,順序寫入速度是很快,避免了磁碟隨機定址。

從庫的同步執行緒(Slave_IO_Running),將binlog在slave上執行的時候,實際上是隨機的,速度肯定要慢點。

 從庫的同步執行緒(Slave_IO_Running)只有應該執行緒在操作,整個mysql例項就一個這樣的執行緒,那麼,如果mysql有n個庫的資料需要同步,全部要這個執行緒來處理。人手不夠啊(mysql-5.6.3)

三、解決思路

如何避免或解決主從延遲?可以用來解決的辦法,有如下的:

  • 從庫優化Mysql引數。比如增大innodb_buffer_pool_size,讓更多操作在Mysql記憶體中完成,減少磁碟操作。

  • 從庫使用高效能主機。包括cpu強悍、記憶體加大。避免使用虛擬雲主機,使用物理主機,這樣提升了i/o方面性。

  • 從庫使用SSD磁碟。機械硬碟是靠磁頭旋轉到指定位置來讀資料、寫資料。轉來轉去的,我們叫做i/o。磁碟i/o存在速度瓶頸。固態硬碟是一個電子裝置,電子裝置不需要機械旋轉,讀寫固態硬碟上任意位置的資料,速度都是一樣的。

  • 業務程式碼的妥協。將實時性要求高的某些操作,使用主庫做讀操作。比如我寫了資料到主庫了,需要馬上展示資料,不要到從庫去讀資料,因為從庫可能還沒同步過去呢。直接從主庫讀資料,保證是最新的資料展示。

  • 從庫的執行緒改為多個同步執行緒同步資料。mysql-5.6.3為了解決這個問題,從伺服器上,每一個庫開一個執行緒來同步。
  • 網路優化。網路堵塞,也會導致同步延遲。跨機房的資料庫同步,會存在同步延遲。保證主從在同一個機房裡面去。

附:mysql主從複製的三種格式資料

第一種是,statement格式。也就是記錄下原來執行的sql語句。

這是最早的一種方式,後來發現也不是很完美,在複製的過程中會存在一些問題。

舉例:由於sql語句中使用了某些mysql函式,而這個mysql函式是特定版本才有的,其他版本是沒有這個函式,放到slave端執行,假如slave的mysql版本不一樣,就可能執行出現問題。

使用了特定的功能,如果sql中使用了last_insert_id()函式,當同樣的sql語句複製到slave端執行的時候,last_insert_id()所得到的結果是不同的。

上面兩種情況導致了:複製過程中,slave端的結果沒有完全與master端一致了。

而基於row格式的就不會。於是發明了row格式的。

第二種,基於row格式的。會記錄下每一行修改前和修改後的值。binlog中儲存的就是被修改行的修改前和修改後的值,直接拿到結果即可。重做。

基於row的格式有個缺點:涉及到ddl操作,比如alter table,加一個欄位,那麼意味著整個表的行都要進行修改。那麼binlog中記錄的是整個表中行的資料,造成binlog中的資料量很大。

於是,又發明了基於statement格式和基於row格式的綜合版,叫做mixed

第三種:mixed

遇到ddl表變更操作,則使用statement格式,遇到delete或update格式,則使用row格式。

三種格式的發展過程總結:

一直使用statement格式,到了5.1.5版本才支援row格式。後來儲存過程的出現,又帶來了新的問題。儲存過程中呼叫一些函式,在slave端執行結果會不同。所以5.1.8版本開始支援mixed格式。上面所有策略的做法目標是,讓master與slave的資料保持一致。從這個角度出發。