分析一下OpenGauss的等待事件
DBA行業的老司機知道等待事件分析對數據庫運維來說有多么重要,等待事件分析是Oracle在7.3版本中推出OWI后才變得可能的,必須在數據庫核心層提供接口才能實現。
國產數據庫在等待事件接口方面也做了很多的工作,我第一次用達夢數據庫的時候就發現居然有等待事件,雖然達夢數據庫的等待事件還比較簡單,不過對于運維來說還是很有價值的。最近和Oceanbase、Polardb的朋友交流中也發現他們也在等待事件分析方面做很多突破性的功能增強,一些能力可能很快就可以合并到主線版本中了。
PostgreSQL是在9.6版本首先引入等待事件的,雖然openGauss的基礎PostgreSQL版本(9.2.4)并不支持等待事件,不過openGauss從1.0開始就支持等待事件了,當然2.0之后openGauss的等待事件有了極大的提升,支持了等待時間。對于等待事件分析來說,支持等待時間分析是一個巨大的提升,這可以讓等待事件分析更為有效。
openGauss的等待事件并沒有放在pg_stat_activity中,而是另外使用了一個視圖接口。這種設計我猜想是為了避免對PG內核做過多的修改,從而影響PG核心的穩定性。因為等待事件采集和會話的活動有直接的關系,涉及到數據庫最核心的代碼。openGauss通過兩張表分別來實現等待事件分析。
一張是thread_wat_status,另外一張是等待事件匯總信息wait_events,記錄了數據庫啟動以來每個等待事件發生的次數、平均等待時間,最大等待時間,最小等待時間等信息。這張視圖有點類似Oracle的v$eventmetric。
比較Oracle(上圖是11g)的這張視圖,openGauss提供了一些類似信息最大值,最小值,平均值的數據,只是有經驗的DBA都知道全局的最大值最小值是沒有意義的,數據庫啟動后只要出現過一次極端現象,就會把這些值固化了,反而對于運維來說沒有價值了。
看樣子這個功能模塊的產品經理運維實戰的經驗還略顯不足,實際上如果能夠保存最近1分鐘,最近5分鐘,最近10分鐘,最近半小時這些最大最小值,或者僅僅保存最近1分鐘的最大/最小值對于運維來說更有價值。不管如何,這種設計體現了openGauss數據庫產品的開發者是考慮了運維的需求的。
上面是openGauss 2.1的等待事件數量-321個,比PG 12足足多了一倍,openGauss 3.0的數量差不太多。
總數是353,多了30多個,每個版本等待事件數量都在增加,說明這個接口的活躍度是可以的,如此發展下去,這個功能會越來越完善。
不過比起Oracle 11g的1367還是有差距,Oracle 19c,這個數量贏又快翻了一倍了。國貨還是有很大的發展余地。不過看等待事件,不僅僅要看數量,而是要看是不是都是一些有效的等待事件。我們在openGauss3上做了幾次小的benchmark壓測(我們的環境只是功能測試環境,一臺虛擬機上部署了多套數據庫,因此只能做一些小壓測),大概平均TPMC為2500左右。然后來看看有哪些等待事件是非零的。
相當不錯了,有66個等待事件的等待次數是非零的。類似的情況,在Oracle 11g里,大約也只有100多個等待事件是非零的,因為很多等待事件是某些場景下才會發生的。
從這個查詢中我們可以看到等待事件排序比較靠前的基本上都是和IO相關的。具體某個等待事件的含義我們后面再慢慢研究,我們也會在PG知識圖譜的基礎上構建支持openGaus等待事件分析的知識圖譜。
接下來我們先來看幾個openGauss 等待事件性能視圖的考慮的比較好的地方。除了剛才說的并均值之類的,還有就是failed_wait字段和last_updated。正常的系統中一般不會出現failed wait,如果某個時間段里出現了較多的failed wait,說明這個等待存在較大的問題。而last_updated則記錄了該等待事件最后一次等待的時間,這在運維中遇到了性能問題,需要分析根因的時候十分重要,有可能這個時間戳就可以幫你過濾掉一些重要的等待事件,從而幫你更精準的定位問題。
說完優點,我們就要說說缺點了,Oracle在v$event_histogram中保留了非零等待事件的直方圖數據。
這個數據對于做深度的分析十分有價值。通過定期采集數據,可以了解很多等待事件的詳情。
我們再回過頭來看看Oracle的v$eventmetric視圖,通過begin_time/end_time我們會發現,對于大多數EVENT,oracle記錄的都是1分鐘的采樣周期內的情況。WAIT EVENT是一種瞬間發生的等待,在具體的性能分析工作中,長時間的累計值實際上并不重要,更為重要的是最近的情況,而1分鐘的統計值十分有助于幫助DBA進行分析。哪怕存在一些特殊的異常值,通過觀察幾次一分鐘的數值,就可以基本了解某個等待事件在此期間的異常情況。
Oracle的v$sysstat中記錄的是一些系統統計數據,這些數據記錄一個統計值就夠用了,我們可以通過多個SNAP的差異來進行分析。如果我們沒有采集歷史的SNAP,那么分析歷史數據還是有些困難的。不過這些指標在AWR中都有采集。而對于等待事件這種分析,和統計數據的分析需求是不同的。因此簡單的記錄統計值是不夠的,openGauss的研發人員也發現了這方面的問題,因此增加了一些平均值之類的屬性。不過個人以多年的運維經驗來看,還是更喜歡使用Oracle的這種模式。有可能是我已經在多年的Oracle數據庫運維中被洗腦了,不過似乎Oracle的方式在現場分析時效果更好。我們的國產數據庫企業還是需要多學習學習Oracle在一些細節上的處理的。這些細節都是多年數據庫產品發展中積累下來的,技術含量并不一定很高,但是實戰效果確實很好。
最后我們再來看看thread_wait_status,令人略感遺憾的是在會話級的等待事件上并沒有包含等待時間,我想以后的版本應該會慢慢的加上,能做系統級的等待事件分析已經為具有細粒度等待事件分析的能力提供了一個基礎。