在配置好主從同步以後, 主服務器會把更新語句寫入binlog, 從服務器的IO線程(5.6.3 之前的IO線程僅有一個,5.6.3之後的有多線程去讀了,速度自然也就加快了)回去讀取主服務器的binlog 並且寫到從服務器的Relay log 裏面,然後從服務器的SQL thread會一個一個執行 relay log 裏面的sql , 進行數據恢復。
1. 主從同步的延遲的原因
當某個SQL在從服務器上執行的時間稍長或者由於某個SQL要進行鎖表就會導致主服務器的SQL大量積壓,未被同步到從服務器裏。這就導致了主從不一致, 也就是主從延遲。
2. 主從同步延遲的解決辦法
a. 主服務器要負責更新操作, 他對安全性的要求比從服務器高, 所有有些設置可以修改,比如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的執行效率,這個能很大程度上提高效率。
b. 使用比主庫更好的硬件設備作爲slave。
c. 增加從服務器,分散從服務器讀壓力, 從而降低服務器負載。
參數解釋:
1、innodb_flush_log_at_trx_commit
取值:0/1/2
innodb_flush_log_at_trx_commit=0,表示每隔一秒把log buffer刷到文件系統中(os buffer)去,並且調用文件系統的“flush”操作將緩存刷新到磁盤上去。也就是說一秒之前的日誌都保存在日誌緩衝區,也就是內存上,如果機器宕掉,可能丟失1秒的事務數據。
innodb_flush_log_at_trx_commit=1,表示在每次事務提交的時候,都把log buffer刷到文件系統中(os buffer)去,並且調用文件系統的“flush”操作將緩存刷新到磁盤上去。這樣的話,數據庫對IO的要求就非常高了,如果底層的硬件提供的IOPS比較差,那麼MySQL數據庫的併發很快就會由於硬件IO的問題而無法提升。
innodb_flush_log_at_trx_commit=2,表示在每次事務提交的時候會把log buffer刷到文件系統中去,但並不會立即刷寫到磁盤。如果只是MySQL數據庫掛掉了,由於文件系統沒有問題,那麼對應的事務數據並沒有丟失。只有在數據庫所在的主機操作系統損壞或者突然掉電的情況下,數據庫的事務數據可能丟失1秒之類的事務數據。這樣的好處,減少了事務數據丟失的概率,而對底層硬件的IO要求也沒有那麼高(log buffer寫到文件系統中,一般只是從log buffer的內存轉移的文件系統的內存緩存中,對底層IO沒有壓力)。
2、sync_binlog
sync_binlog:是MySQL 的二進制日誌(binary log)同步到磁盤的頻率。
取值:0-N
sync_binlog=0,當事務提交之後,MySQL不做fsync之類的磁盤同步指令刷新binlog_cache中的信息到磁盤,而讓Filesystem自行決定什麼時候來做同步,或者cache滿了之後才同步到磁盤。這個是性能最好的。
sync_binlog=1,當每進行1次事務提交之後,MySQL將進行一次fsync之類的磁盤同步指令來將binlog_cache中的數據強制寫入磁盤。
sync_binlog=n,當每進行n次事務提交之後,MySQL將進行一次fsync之類的磁盤同步指令來將binlog_cache中的數據強制寫入磁盤。
大多數情況下,對數據的一致性並沒有很嚴格的要求,所以並不會把 sync_binlog 配置成 1. 爲了追求高併發,提升性能,可以設置爲 100 或直接用 0.
而和 innodb_flush_log_at_trx_commit 一樣,對於支付服務這樣的應用,還是比較推薦 sync_binlog = 1
3.判斷主從延遲的方法
MySQL提供了從服務器狀態命令,可以通過 show slave status 進行查看, 比如可以看看Seconds_Behind_Master參數的值來判斷,是否有發生主從延時。
其值有這麼幾種:
NULL - 表示io_thread或是sql_thread有任何一個發生故障,也就是該線程的Running狀態是No,而非Yes.
0 - 該值爲零,是我們極爲渴望看到的情況,表示主從複製狀態正常