天天看點

快速定位解決myslq主從延遲問題

Mysql主從延遲

主從延遲的主要有兩個方面:

  1. 主資料庫的寫操作過快而從資料庫的單線程操作跟不上導緻
  2. 從資料讀取查詢導緻鎖表,而不能執行同步主資料庫的操作。
快速定位解決myslq主從延遲問題

一:如果是主庫原因

檢視主從延遲的方法:

NULL,表示io_thread或是sql_thread有任何一個發生故障;

0,該值為零,表示主從複制良好;

正值,表示主從已經出現延時,數字越大表示從庫延遲越嚴重

一般情況下都是主庫原因

  1. )是主庫執行DDL和DML語句過快而從庫隻是單線程處理導緻資料延遲。

(mysql的主從是單線程的  mysql主可以同時執行DDL和DLM語句因為他可以并發線程,但是從slave隻能單線程執行 如果DDL語句過長,他必須執行完這個操作才能執行下一個操作。)

主庫執行DDL.DML語句是按照順序執行的,而slave執行語句是随機的是以成本高很多。

  1. 從庫在執行操作時候可能造成lock的争奪,鎖表。

解決辦法:

1. 半同步複制

從MySQL5.5開始,MySQL已經支援半同步複制了,半同步複制介于異步複制和同步複制之間,主庫在執行完事務後不立刻傳回結果給用戶端,需要等待至少一個從庫接收到并寫到relay log中才傳回結果給用戶端。相對于異步複制,半同步複制提高了資料的安全性,同時它也造成了一個TCP/IP往返耗時的延遲。

2. 主庫配置sync_binlog=1,innodb_flush_log_at_trx_commit=1

sync_binlog的預設值是0,MySQL不會将binlog同步到磁盤,其值表示每寫多少binlog同步一次磁盤。

innodb_flush_log_at_trx_commit為1表示每一次事務送出或事務外的指令都需要把日志flush到磁盤。

最簡單的減少slave同步延時的方案就是在架構上做優化,盡量讓主庫的DDL快速執行。還有就是主庫是寫,對資料安全性較高,比如 sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之類的設定,而slave則不需要這麼高的資料安全,完全可以講sync_binlog設定為0或者關閉binlog,innodb_flushlog也 可以設定為0來提高sql的執行效率。另外就是使用比主庫更好的硬體裝置作為slave。

innodb_flush_log_at_trx_commit = 0 :每秒将日志緩沖區寫入log file,并同時flush到磁盤。跟事務送出無關。在機器crash并重新開機後,會丢失一秒的事務日志資料(并不一定是1s,也許會有延遲,跟作業系統排程有關)。

innodb_flush_log_at_trx_commit = 1:每次事務送出将日志緩沖區寫入log file,并同時flush到磁盤。(crash不會丢失事務日志)

innodb_flush_log_at_trx_commit = 2:每次事務送出将日志緩沖區寫入log file,每秒flush一次到磁盤。(crash有可能丢失資料)

附加:

sync_binlog 配置說明:

sync_binlog”:這個參數是對于MySQL系統來說是至關重要的,他不僅影響到Binlog對MySQL所帶來的性能損耗,而且還影響到MySQL中資料的完整性。對于“sync_binlog”參數的各種設定的說明如下:

sync_binlog=0,當事務送出之後,MySQL不做fsync之類的磁盤同步指令重新整理binlog_cache中的資訊到磁盤,而讓Filesystem自行決定什麼時候來做同步,或者cache滿了之後才同步到磁盤。

sync_binlog=n,當每進行n次事務送出之後,MySQL将進行一次fsync之類的磁盤同步指令來将binlog_cache中的資料強制寫入磁盤。

在MySQL中系統預設的設定是sync_binlog=0,也就是不做任何強制性的磁盤重新整理指令,這時候的性能是最好的,但是風險也是最大的。因為一旦系統Crash,在binlog_cache中的所有binlog資訊都會被丢失。而當設定為“1”的時候,是最安全但是性能損耗最大的設定。因為當設定為1的時候,即使系統Crash,也最多丢失binlog_cache中未完成的一個事務,對實際資料沒有任何實質性影響。

從以往經驗和相關測試來看,對于高并發事務的系統來說,“sync_binlog”設定為0和設定為1的系統寫入性能差距可能高達5倍甚至更多。

innodb_flush_log_at_trx_commit 配置說明:

預設值1的意思是每一次事務送出或事務外的指令都需要把日志寫入(flush)硬碟,這是很費時的。特别是使用電 池供電緩存(Battery backed up cache)時。設成2對于很多運用,特别是從MyISAM表轉過來的是可以的,它的意思是不寫入硬碟而是寫入系統緩存。日志仍然會每秒flush到硬 盤,是以你一般不會丢失超過1-2秒的更新。設成0會更快一點,但安全方面比較差,即使MySQL挂了也可能會丢失事務的資料。而值2隻會在整個作業系統 挂了時才可能丢資料。

解決從庫複制延遲的問題:

1. 優化網絡

2. 更新Slave硬體配置

3. Slave調整參數,關閉binlog,修改innodb_flush_log_at_trx_commit參數值

4. 更新MySQL版本到5.7,使用并行複制

1)、架構方面

1.業務的持久化層的實作采用分庫架構,mysql服務可平行擴充,分散壓力。

2.單個庫讀寫分離,一主多從,主寫從讀,分散壓力。這樣從庫壓力比主庫高,保護主庫。

3.服務的基礎架構在業務和mysql之間加入memcache或者redis的cache層。降低mysql的讀壓力。

4.不同業務的mysql實體上放在不同機器,分散壓力。

5.使用比主庫更好的硬體裝置作為slave總結,mysql壓力小,延遲自然會變小。

2)、硬體方面

1.采用好伺服器,比如4u比2u性能明顯好,2u比1u性能明顯好。

2.存儲用ssd或者盤陣或者san,提升随機寫的性能。

3.主從間保證處在同一個交換機下面,并且是萬兆環境。

總結,硬體強勁,延遲自然會變小。一句話,縮小延遲的解決方案就是花錢和花時間。

3)、mysql主從同步加速

1、sync_binlog在slave端設定為0

2、–logs-slave-updates 從伺服器從主伺服器接收到的更新不記入它的二進制日志。

3、直接禁用slave端的binlog

4、slave端,如果使用的存儲引擎是innodb,innodb_flush_log_at_trx_commit =2

4)、從檔案系統本身屬性角度優化

從庫的原因: 

從庫執行過長的查詢語句 而導緻鎖表,在主庫執行的操作恰巧也是從庫那個被鎖的表,導緻了資料隻能等待查詢結束後才能繼續對表進行操作。導緻資料庫延遲。

一般情況是檢視慢查詢日志找到 需要優化的語句發給後端處理。

Ps:如果是雲資料庫 可以通過監控

快速定位解決myslq主從延遲問題
快速定位解決myslq主從延遲問題