天天看點

MySQL · 功能介紹 · binlog拉取速度的控制

mysql 主備之間資料同步是通過binlog進行的,當主庫更新産生binlog時,備庫需要同步主庫的資料,通過binlog協定從主庫拉取binlog進行資料同步,以達到主備資料一緻性的目的。但當主庫tps較高時會産生大量的binlog,以緻備庫拉取主庫産生的binlog時占用較多的網絡帶寬,引起以下問題:

在mysql中,寫入與讀取binlog使用的是同一把鎖(lock_log),頻繁的讀取binlog,會加劇lock_log沖突,影響主庫執行,進而造成tps降低或抖動;

當備庫數量較多時,備庫拉取binlog會占用過多的帶寬,影響應用的響應時間。

為了解決上面提到的問題,需要對binlog的拉取速度進行限制。

備庫或應用通過binlog協定向主庫發送消息,告訴主庫要拉取binlog,主庫經過權限認證後,以binlog_event為機關讀取在本地的binlog,然後将這些binlog_event發送給應用,其過程簡單描述如下:

從mysql-bin.index中找到使用者消息中的指定檔案,如果沒有指定要拉取的binlog檔案名稱,則用第一個;

上lock_log鎖,從1)或4) 中的binlog file中讀取一個binlog_event,釋放lock_log鎖,判斷binlog_event的類型;

如果是普通binlog_event,則将binlog_event發送到net 緩沖區;

如果是rotate_log_event,則取出要rotate到的檔案,執行2);

如果目前讀的檔案是最後一個檔案且已經讀到了檔案的結尾,則會釋放lock_log鎖,并等待新的log_event信号。

從以上過程可以看出,binlog的發送速度和io、網絡有很大的關系,隻要這三者不受限制,程式會就盡力發送binlog而沒有限制。

由3、4可以看出,程式在讀取和發送之間是沒有其它工作的,如果io很強,讀取的速度很快,那麼binlog的發送速度就會很快且不受限制,進而造成本文開始所描述的問題;針對binlog發送速度的問題,rds_mysql 通過設定binlog發送線程的發送頻率、休眠時間來調整binlog的發送速度,是以 rds_mysql 引入了兩個新的參數:

1. binlog_send_idle_period binlog發送線程的每次休眠時間,機關微秒,預設值100;

2. binlog_send_limit_users binlog發送線程的速度配置,預設值”“。

舉例如下:

set global binlog_send_limit_users=”rep1:3,rep2:10” 的作用是設定rep1拉取binlog的上限速度是3m/s, rep2拉取binlog的上限速度是10m/s,其中rep2、rep2指的是應用連接配接的使用者名,對于binlog的拉取速度控制主要分為兩個方面:

速度監控線程随着mysqld的啟動而啟動,用于定時掃描限速清單,計算清單中的每一個binlog dump線程的binlog發送速度,并根據計算的速度調整binlog的發送頻率,其工作過程描述如下:

速度監控線程随着mysqld的啟動而啟動,并初始化限速清單;

對限速清單進行依次掃描,如果取到的線程不為空,轉2);

計算目前線程的發送速度,與使用者設定的速度進行比較,大于設定的發送速度,轉3),如果小于使用者設定的發送速度,則轉4)

通過調整目前線程的net_thread_frequency 成員,降低發送頻率;

通過調整目前線程的net_thread_frequency 成員,增加發送頻率;

周遊完限速清單後讓出cpu 1毫秒,轉1)

由以上描述可以看出,監控線程每毫秒執行一次,根據發送的位元組數來計算binlog發送線程的發送速度是否超過設定的速度,并通過調整發送頻率來調整binlog的發送速度,監控線程的限速清單是這樣構造的:

binlog dump 線程在拉取binlog前會先根據連接配接的使用者名判斷是否應該對該使用者限速,如果需要限速,則需要将目前dump線程加入限速清單;

當binlog dump結束或斷開連接配接時,從限速清單移除;

當設定參數binlog_send_limit_users時,會對目前所有線程進行周遊,将被限制的使用者加入限速清單,對不受限制的使用者移出限制清單,所有受影響的線程不需要重新連接配接,可以實時生效。

dump 線程用于發送binlog,在發送過程中會根據監控線程設定的發送頻率來調整binlog發送的速度,可以分為以下幾步:

1. binlog dump 線程在拉取binlog前會先根據連接配接的使用者名判斷是否将本使用者的線程加入限速清單;

2. 讀取binlog,并檢視是否需要休眠,需要休眠轉3),否則轉4);

3. 休眠binlog_send_idle_period;

4. 發送讀取到的binlog event,轉2。

是以可以通過設定binlog的發送頻率及休眠時間精确調整binlog的發送速度

繼續閱讀