在我們執行sql的時候偶爾會抖一下的原因:數據庫對髒頁進行了flush操作。
髒頁:當內存數據頁跟磁盤數據頁不一樣的時候,就叫髒頁。
乾淨頁:當內存數據頁跟磁盤數據一樣的時候,叫乾淨頁。
mysql flush四種場景:
1.當redo log的內存片(粉版)已經記錄滿,這個時候會停止所有的更新操作,對checkpoint往前推,推進的日誌對應的所有髒頁將flush進磁盤。
2.當內存用完,這個時候需要淘汰部分數據,如果剛好淘汰的是髒頁,那麼會直接flush後再淘汰。
3.當空閒時,會進行flush。
4.當正常關閉mysql。
innodb_io_capacity設置問題
innodb_io_capacity告訴mysql io的處理能力,如果innodb_io_capacity設置過小,mysql刷髒頁的速度就很慢,甚至小於生成的速度,導致了查詢和更新新能差。
合理地設置innodb_io_capacity的值,並且平時要多關注髒頁比例,不要讓它經常接近75%。
其中,髒頁比例是通過Innodb_buffer_pool_pages_dirty/Innodb_buffer_pool_pages_total得到的,具體的命令參考下面的代碼:
mysql> select VARIABLE_VALUE into @a from global_status where VARIABLE_NAME = 'Innodb_buffer_pool_pages_dirty';
select VARIABLE_VALUE into @b from global_status where VARIABLE_NAME = 'Innodb_buffer_pool_pages_total';
select @a/@b;
一旦一個查詢請求需要在執行過程中先flush掉一個髒頁時,這個查詢就可能要比平時慢了。而MySQL中的一個機制,可能讓你的查詢會更慢:在準備刷一個髒頁的時候,如果這個數據頁旁邊的數據頁剛好是髒頁,就會把這個“鄰居”也帶着一起刷掉;而且這個把“鄰居”拖下水的邏輯還可以繼續蔓延,也就是對於每個鄰居數據頁,如果跟它相鄰的數據頁也還是髒頁的話,也會被放到一起刷。
在InnoDB中,innodb_flush_neighbors 參數就是用來控制這個行爲的,值爲1的時候會有上述的“連坐”機制,值爲0時表示不找鄰居,自己刷自己的。