當前位置:編程學習大全網 - 源碼下載 - 如何判斷MSSQL數據庫磁盤出現了瓶頸

如何判斷MSSQL數據庫磁盤出現了瓶頸

? 具體問題具體分析,舉例來說明為什麽磁盤IO成瓶頸數據庫的性能急速下降了。

?為什麽當磁盤IO成瓶頸之後, 數據庫的性能不是達到飽和的平衡狀態,而是急劇下降。為什麽數據庫的性能有非常明顯的分界點,原因是什麽?

? 相信大部分做數據庫運維的朋友,都遇到這種情況。 數據庫在前壹天性能表現的相當穩定,數據庫的響應時間也很正常,但就在今天,在業務人員反饋業務流量沒有任何上升的情況下,數據庫的變得不穩定了,有時候壹個最簡單的insert操作, 需要幾十秒,但99%的insert卻又可以在幾毫秒完成,這又是為什麽了?

dba此時心中有無限的疑惑,到底是什麽原因呢? 磁盤IO性能變差了?還是業務運維人員反饋的流量壓根就不對? 還是數據庫內部出問題?昨天不是還好好的嗎?

當數據庫出現響應時間不穩定的時候,我們在操作系統上會看到磁盤的利用率會比較高,如果觀察仔細壹點,還可以看到,存在壹些讀的IO. 數據庫服務器如果存在大量的寫IO,性能壹般都是正常跟穩定的,但只要存在少量的讀IO,則性能開始出現抖動,存在大量的讀IO時(排除配備非常高速磁盤的機器),對於在線交易的數據庫系統來說,大概性能就雪崩了。為什麽操作系統上看到的磁盤讀IO跟寫IO所帶來的性能差距這麽大呢??

如果親之前沒有註意到上述的現象,親對上述的結論也是懷疑。但請看下面的分解。

在寫這個文章之前,作者閱讀了大量跟的IO相關的代碼,如異步IO線程的相關的,innodb_buffer池相關的,以及跟讀數據塊最相關的核心函數buf_page_get_gen函數以及其調用的相關子函數。為了將文章寫得通俗點,看起來不那麽累,因此不再壹行壹行的將代碼解析寫出來。

咱們先來提問題。?buf_page_get_gen函數的作用是從Buffer bool裏面讀數據頁,可能存在以下幾種情況。

提問. 數據頁不在buffer bool 裏面該怎麽辦??

回答:去讀文件,將文件中的數據頁加載到buffer pool裏面。下面是函數buffer_read_page的函數,作用是將物理數據頁加載到buffer pool, 圖片中顯示

buffer_read_page函數棧的頂層是pread64(),調用了操作系統的讀函數。

buf_read_page的代碼

如果去讀文件,則需要等待物理讀IO的完成,如果此時IO沒有及時響應,則存在堵塞。這是壹個同步讀的操作,如果不完成該線程無法繼續後續的步驟。因為需要的數據頁不再buffer 中,無法直接使用該數據頁,必須等待操作系統完成IO .

再接著上面的回答提問:

當第二會話線程執行sql的時候,也需要去訪問相同的數據頁,它是等待上面的線程將這個數據頁讀入到緩存中,還是自己再發起壹個讀磁盤的然後加載到buffer的請求呢?? 代碼告訴我們,是前者,等待第壹個請求該數據頁的線程讀入buffer pool。

試想壹下,如果第壹個請求該數據頁的線程因為磁盤IO瓶頸,遲遲沒有將物理數據頁讀入buffer pool, 這個時間區間拖得越長,則造成等待該數據塊的用戶線程就越多。對高並發的系統來說,將造成大量的等待。 等待數據頁讀入的函數是buf_wait_for_read,下面是該函數相關的棧。

通過解析buf_wait_for_read函數的下層函數,我們知道其實通過首先自旋加鎖pin的方式,超過設定的自旋次數之後,進入等待,等待IO完成被喚醒。這樣節省不停自旋pin時消耗的cpu,但需要付出被喚起時的開銷。

再繼續擴展問題: 如果會話線程A 經過物理IO將數據頁1001讀入buffer之後,他需要修改這個頁,而在會話線程A之後的其他的同樣需要訪問數據頁1001的會話線程,即使在數據頁1001被入讀buffer pool之後,將仍然處於等待中。因為在數據頁上讀取或者更新的時候,同樣需要上鎖,這樣才能保證數據頁並發讀取/更新的壹致性。

由此可見,當壹個高並發的系統,出現了熱點數據頁需要從磁盤上加載到buffer pool中時,造成的延遲,是難以想象的。因此排在等待熱點頁隊列最後的會話線程最後才得到需要的頁,響應時間也就越長,這就是造成了壹個簡單的sql需要執行幾十秒的原因。

再回頭來看上面的問題,mysql數據庫出現性能下降時,可以看到操作系統有讀IO。 原因是,在數據庫對數據頁的更改,是在內存中的,然後通過檢查點線程進行異步寫盤,這個異步的寫操作是不堵塞執行sql的會話線程的。所以,即使看到操作系統上有大量的寫IO,數據庫的性能也是很平穩的。但當用戶線程需要查找的數據頁不在buffer pool中時,則會從磁盤上讀取,在壹個熱點數據頁不是非常多的情況下,我們設置足夠大的innodb_buffer_pool的size, 基本可以緩存所有的數據頁,因此壹般都不會出現缺頁的情況,也就是在操作系統上基本看不到讀的IO。 ?當出現讀的IO時,原因時在執行buf_read_page_low函數,從磁盤上讀取數據頁到buffer pool, 則數據庫的性能則開始下降,當出現大量的讀IO,數據庫的性能會非常差。

  • 上一篇:latex book類:每章頁眉頁腳和標題格式 以及 去除章與章之間空白頁的問題
  • 下一篇:Vue 中 Flex布局
  • copyright 2024編程學習大全網