為什么平均等待時長對于數(shù)據(jù)庫運維十分關(guān)鍵
?昨天我談到第二次使用人大金倉數(shù)據(jù)庫的時候,能夠從可觀測性接口中獲得等待事件的等待時間信息,感受到了數(shù)據(jù)庫在易用性上的進(jìn)步。有些朋友十分不解,不就是等待時間的長度數(shù)據(jù)采集嗎?有這么重要嗎!說實在的,運維人員獲得數(shù)據(jù)庫的等待事件的等待時長,是比重要還要重要的。
我們很容易從數(shù)據(jù)庫中獲得等待事件的次數(shù),等待事件次數(shù)統(tǒng)計對于數(shù)據(jù)庫內(nèi)核來說,實現(xiàn)起來并不麻煩,只要維護(hù)一個內(nèi)存數(shù)據(jù)結(jié)構(gòu),通過輕量級鎖來保護(hù)這個內(nèi)存結(jié)構(gòu)就可以了。數(shù)據(jù)庫的會話可以通過向數(shù)組累計統(tǒng)計數(shù)據(jù)來獲得這些統(tǒng)計數(shù)據(jù)。甚至很多數(shù)據(jù)庫根本不需要統(tǒng)計等待次數(shù),只需要在會話信息中增加一些等待事件的相關(guān)數(shù)據(jù)項就可以了。每個會話都會維護(hù)自己的會話狀態(tài)塊,每次產(chǎn)生某個等待的時候只需要對其進(jìn)行累加就可以了,其維護(hù)成本很低。但是要統(tǒng)計某個等待事件的等待時長那就不同了。
十多年前我和一個國產(chǎn)數(shù)據(jù)庫廠商交流的時候,他們就提出來他們在新版本中引入了等待事件,但是目前只能提供等待次數(shù),無法提供等待時長。他們測試過在會話信息中加入等待時長的統(tǒng)計信息,但是加入后,數(shù)據(jù)庫的整體性能下降超過了10%,想了解一下Oracle數(shù)據(jù)庫是怎么在OWI接口中實現(xiàn)等待時長的統(tǒng)計的。當(dāng)時我對這個問題研究也不深,為了回答這個問題,我也研究了Oracle OWI接口的發(fā)展歷史。實際上Oracle對這些數(shù)據(jù)的統(tǒng)計也是經(jīng)歷過一些波折的,最初甚至通過CPU周期、resource manager等去粗略的估算時長。到后來采用統(tǒng)一時間戳去做近似估算。其目的是以最低的成本,對數(shù)據(jù)庫運行影響最小的方式較為近似的統(tǒng)計等待時長。
既然獲得等待事件的時長需要付出如此的代價,那么為什么DBA還是需要獲得這些數(shù)據(jù)呢?從等待事件的等待次數(shù)上不就可以知道數(shù)據(jù)庫在干什么,在等什么了嗎?實際上等待事件分析是十分復(fù)雜的事情,并不像某些DBA認(rèn)為的,看到某個等待事件,去百度上搜一搜就可以定位數(shù)據(jù)庫的問題。某個等待事件是否引發(fā)了某個數(shù)據(jù)庫問題,并不僅僅要看這個等待事件是否出現(xiàn),而是要看它占總等待的比例。這個比例可以是等待次數(shù),也可以使等待時長,而等待時長的準(zhǔn)確性更高。如果某個等待事件出現(xiàn)的次數(shù)很高,只能說這方面的負(fù)載很高,如果每次等待的時長都很低,或者說和日常數(shù)據(jù)庫沒出問題時候的平均等待時長十分接近,那么可能說明數(shù)據(jù)庫在這方面的并發(fā)性能并沒有出現(xiàn)問題,數(shù)據(jù)庫的問題很可能并不是因為這個等待事件引起的。
比如說上圖,我們發(fā)現(xiàn)了IO延時突然增加,那么我們就可以通過突發(fā)IO延時的增加與十幾分鐘后的服務(wù)器重啟進(jìn)行綜合分析,從而把故障原因縮小到一個較為狹窄的分析面上,通過這個問題去做下一步的問題定位。
而如果我們只知道IO等待的次數(shù),那么我們只能知道當(dāng)前SQL讀寫IO的負(fù)載很高,可能有一些產(chǎn)生大IO的SQL,或者有大量的并發(fā)訪問。但是我們無法知道當(dāng)前的IO負(fù)載是否會引發(fā)數(shù)據(jù)庫的問題,或者說數(shù)據(jù)庫是否存在宕機(jī)的風(fēng)險。十分高興的是,我們看到目前大多數(shù)國產(chǎn)數(shù)據(jù)庫都開始提供等待事件等待時長數(shù)據(jù)了,這對于DBA運維國產(chǎn)數(shù)據(jù)庫十分關(guān)鍵。
而采集等待事件的等待時長對于數(shù)據(jù)庫核心來說也是一個挑戰(zhàn),用最小的成本,對數(shù)據(jù)庫性能影響最小的方式采集等待事件時長十分關(guān)鍵。記得去年我在測試Polardb-O的可觀測性能力的時候,驚喜的發(fā)現(xiàn)了Polardb能夠?qū)σ恍┲攸c等待事件采集等待時長,這些重點等待事件主要是lwlock和數(shù)據(jù)庫IO相關(guān)的。而對于其他的等待事件,Polardb并沒有提供等待時長,這種設(shè)計也體現(xiàn)了運維與數(shù)據(jù)庫性能之間的平衡。一般來說,對于現(xiàn)代硬件,如果開啟了這些采集,增加的數(shù)據(jù)庫開銷低于5%,甚至在一些系統(tǒng)中,低于10%都是可以接受的。但是如果太高,則無法接受了。
當(dāng)時我發(fā)現(xiàn)商用版的Polardb-O中的針對IO的等待時長的采集數(shù)據(jù)是空的,而開源版的Polardb-PG中是能夠看到這些數(shù)據(jù)的。當(dāng)時我們也沒有深究這個問題。今年我們加入了Polardb社區(qū),同時在D-SMART中也開始針對Polardb做深度對接,將Polardb-PG數(shù)據(jù)庫與社區(qū)版的PG數(shù)據(jù)庫獨立開來,利用Polardb的可觀測性能力增強(qiáng)來加強(qiáng)Polardb的監(jiān)控診斷與分析能力,所以我們重新對這些可觀測性接口做了分析。通過與阿里的技術(shù)人員的溝通發(fā)現(xiàn),要想在商用版的Polardb上采集到Polar_stat_io_latency等IO相關(guān)的等待時長數(shù)據(jù),哪怕我們使用的是本地文件系統(tǒng)的單機(jī)版,也必須將數(shù)據(jù)庫存放在Polar自帶的PFS文件系統(tǒng)上,并設(shè)置polar_enable_shared_storage_mode = on,才能采集到相關(guān)的數(shù)據(jù)。
完成這些設(shè)置后,我們就可以從polar_stat_io_info/polar_stat_io_latency視圖中看到數(shù)據(jù)了。在開源版本中,采集IO延時的時長的采集采用的是大多數(shù)數(shù)據(jù)庫使用的原生模式,在數(shù)據(jù)庫內(nèi)核中直接實現(xiàn)就可以了。但是在商用版中,這些優(yōu)化是利用云原生數(shù)據(jù)庫的特性,通過PFS底層實現(xiàn)來完成的,這樣可以大大降低數(shù)據(jù)庫內(nèi)核采集IO等待時長的成本開銷。