天天看點

MySQL“異象”分析:備庫的io util比主庫重?

同僚問了個線上現象:主備機器配置一樣,主庫上有更新查詢,備庫設定為主庫的從庫,沒有其他更新和查詢壓力。但備庫的io util比主庫的重。本來看主庫的壓力比較大,想把一部分查詢切到備庫,一看io這樣,不太敢切。

1、原因

這個原因兩年前在之前公司碰到過一次,隻是現象不同。那個現象描述起來比較複雜,這回剛好借這個現象說明一下。

原因還是從srv_master_thread說起。這個innodb背景的主程序一直在循環作各種事情。其中有一個for (i = 0; i < 10; i++) ,循環體每執行一次sleep 1秒,作一些flush和merge的事情,網上這類文章很多,不細數了。我們要關注的是循環中的這句話

if (srv_activity_count == old_activity_count) {

/* there is no user activity at the moment, go to

the background loop */

goto background_loop;

}

注釋也說的明白,如果此時沒有使用者活動,則認為是系統空閑,執行background_loop。這個background_loop流程作的事情包括insert buffer merge和 flush buffer pool pages。 都是些耗系統資源的活兒。做完之後又回到for前面的邏輯。

而對于從庫來說,一直沒有使用者請求,是以一進入for就符合進入background_loop的條件,是以整個線程實際上就是不停的在作background_loop裡面的事情。

是以結論就是由于沒有使用者請求,innodb認為系統空閑,是以玩兒命地刷盤,看上去io就很重。

2、 驗證

既然如此,就想辦法告訴innodb:其實作在很忙。 可以簡單的寫個腳本不停的執行一個簡單的語句,讓if (srv_activity_count == old_activity_count)這條件不滿足就行。比如 select sql_no_cache * from t where key = xxx limit 1;

會看到加了這腳本後,備庫的io util也下去了。

3、 結論

切點查詢流量去備庫沒有問題,反而會讓備庫看上去“正常” ;

innodb的這個判斷機制有點囧,實際上有很多條件都可以比較合理的判斷,不過也不是什麼大問題,好歹還有些方法可以繞過的嘛,就是土了點。。。

繼續閱讀