一. 如何檢測主從延遲
可以通過監控 show slave status\G
命令輸出的Seconds_Behind_Master
參數值來判斷,是否存在主從延時。
NULL
- 表示io_thread或sql_thread發生故障,也就是該線程的Running狀態是No。**(有故障)
0 - 該值為零,是我們極為渴望看到的情況,表示主從復制良好,可以認為lag不存在。
(無延遲)
正值 - 表示主從已經出現延時,數字越大表示從庫落后主庫越多。
(有延遲)
負值
- 幾乎很少見,只是聽一些資深的DBA說見過,其實這是一個BUG值,該參數是不支持負值的,也就是不應該出現。
二. 主從庫延遲產生的原因
在分析延遲產生原因之前,我們先來熟悉一下主從同步的工作原理和步驟:
步驟1: 所有數據更新都會被主庫記錄到主庫的二進制日志。
步驟2: 與此同時從庫的IO線程會從主庫上讀取二進制日志,寫入到從庫的中繼日志上。
步驟3: 從庫的SQL線程讀取中繼日志上的內容來更新從庫。
到底是什么原因導致了主從的延遲呢?問題無非出在這三個步驟或過程中:
主庫對DDL和DML產生binlog,和slave的Slave_IO_Running線程從主庫取日志,效率都比較高。但是,由于從庫的Slave_SQL_Running是單線程作業,不能并發執行,所以當主庫的TPS并發較高時,就容易產生延遲。
三. 如何解決主從延遲
- 最簡單的減少slave同步延時的方案就是在架構上做優化,盡量讓主庫的DDL快速執行。
- 還有就是主庫寫對數據安全性較高,比如sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之類的設置,而slave則不需要這么高的數據安全,完全可以將sync_binlog設置為0或者關閉binlog,innodb_flushlog也可以設置為0來提高sql的執行效率。
- 另外就是使用比主庫更好的硬件設備作為slave。
- 另外,mysql-5.6.3已經支持了多線程的主從復制。
注釋:innodb_flush_log_at_trx_commit默認值1的意思是每一次事務提交或事務外的指令都需要把日志寫入(flush)硬盤,這是很費時的。特別是使用電池供電緩存(Battery backed up cache)時。設成2對于很多運用,特別是從MyISAM表轉過來的是可以的,它的意思是不寫入硬盤而是寫入系統緩存。日志仍然會每秒flush到硬,所以你一般不會丟失超過1-2秒的更新。設成0會更快一點,但安全方面比較差,即使MySQL掛了也可能會丟失事務的數據。而值2只會在整個操作系統 掛了時才可能丟數據。