弄明白DOUBLE BUFFERING對PG數(shù)據(jù)庫的運(yùn)維與優(yōu)化有什么意義
?昨天的案例講了因為PG的DOUBLE BUFFERING導(dǎo)致的SQL執(zhí)行忽快忽慢的問題,有些朋友在問是不是Oracle之外的很多數(shù)據(jù)庫都是用類似的方式讀取文件,這種Double Buffering技術(shù)是不是很落后,是不是必須加以改進(jìn)。實際上,只要是使用文件系統(tǒng),并且在讀數(shù)據(jù)時沒有采用DIO的數(shù)據(jù)庫都會存在DOUBLE BUFFERING的問題,早期的Oracle也存在類似問題。
上圖比較清晰的說明了DOUBLE BUFFERING問題,對于寫的情況,因為先寫入CACHE,再由OS把CACHE寫入磁盤,中間會有一些性能損失,不過對于現(xiàn)代的數(shù)據(jù)庫來說,只有REDO/WAL是需要強(qiáng)一致性寫入的,數(shù)據(jù)文件的寫入不會阻塞數(shù)據(jù)庫的讀寫訪問,因此這種性能損失是可以接受的。并且現(xiàn)代硬件上,IO延時已經(jīng)極大的降低了,這點(diǎn)損失也沒有太大的問題。
對于讀操作來說,就涉及到我們的數(shù)據(jù)庫共享緩沖池如何設(shè)計的問題了。比較新的MySQL版本在支持DIO的操作系統(tǒng)上默認(rèn)使用DIO讀取文件,因此設(shè)置一個足夠大的innodb buffer就可以了,采用默認(rèn)的配置就不存在PG類似Double Buffering的問題。PG數(shù)據(jù)庫使用者對此爭論較多,PG官方文檔也是建議shared_buffers不用太大,給OS留下足夠的內(nèi)存用于優(yōu)化IO。
為什么PG還會堅持這樣模式來實現(xiàn)數(shù)據(jù)庫緩沖呢?實際上維護(hù)一個極大的共享緩沖區(qū),保持并發(fā)讀寫性能也是十分難做好的。對于不同的應(yīng)用場景,緩沖的策略也會不同。如果經(jīng)常由一些大表的掃描訪問,往往數(shù)據(jù)不會重復(fù)被訪問,這種情況如果加載到共享緩沖中再去訪問,會加大共享緩沖的閂鎖(對于PG來說就是輕量級鎖)爭用,引起數(shù)據(jù)庫的性能問題,加大熱塊沖突的延時,這樣就得不償失了。Oracle在對待此類問題,也采用了直接路徑讀這樣的方式來解決。
目前使用MySQL的大型數(shù)據(jù)庫比較少,即使有些MySQL庫的總?cè)萘恳策_(dá)到數(shù)個TB,但是實際上被經(jīng)常訪問的數(shù)據(jù)也不過幾百M(fèi),因此不太容易碰到共享緩沖性能帶來的總體性能問題。而在一些比較大的PG數(shù)據(jù)庫上,并發(fā)讀寫較高場景下,我們已經(jīng)遇到過不少LWLOCK帶來的性能問題,我以前的文章中也提到過從算法上看,PG的shared buffers算法效率會略低于Oracle的DB CACHE,這些現(xiàn)象似乎也是對此的一種佐證。
在某些場景下,不把shared buffers設(shè)置的過大,使用OS FILE CACHE來作為輔助,也是一種優(yōu)化策略,就像前幾天討論過的數(shù)據(jù)庫可以把一些復(fù)雜的不太容易做好的事情交給OS去做。有些應(yīng)用系統(tǒng)中給shared buffer配置了絕大多數(shù)的OS內(nèi)存效果也不錯,但是這種模式下訪問冷數(shù)據(jù)的性能會打折扣。通過pgfincore這樣的工具來做預(yù)熱可以大幅度提升某些定期的分析任務(wù)對大表掃描的執(zhí)行效率。
今天不討論shared buffer配置策略的問題,這方面我以前已經(jīng)寫過幾篇文章探討了,有興趣的朋友可以去公眾號上搜索一下。今天我們討論一個因為double buffering機(jī)制導(dǎo)致的幾個PG指標(biāo)指示性失效的問題。在PG的shared buffer的不同配置策略下,有些情況下的物理讀可能并不是真正的物理讀,而是“假物理讀”,因此針對PG數(shù)據(jù)庫,共享緩沖池命中率和物理讀這兩個指標(biāo)是會存在比較嚴(yán)重的誤解的。
在Oracle數(shù)據(jù)庫中,我們會針對物理讀的突然增加產(chǎn)生一個性能告警。因為這可能意味著某些SQL執(zhí)行存在異常,或者IO負(fù)載突然增加,可能會引發(fā)一些不確定的數(shù)據(jù)庫性能問題。
這個故障模型在D-SMART里也被拷貝到了PG數(shù)據(jù)庫中,但是這個故障模型的告警,在PG數(shù)據(jù)庫中可能沒有在Oracle上那么有效。因為不同的shared buffers配置策略可能會導(dǎo)致某些時候產(chǎn)生的物理讀實際上并不是真正的從存儲設(shè)備上讀取數(shù)據(jù),而是從FILE CACHE中讀取數(shù)據(jù)。很可能這種突發(fā)的物理讀增加并不是一個需要告警的故障,而是一種被預(yù)先設(shè)計好的正常現(xiàn)象,如果不分青紅皂白的去告警就會不準(zhǔn)確了。作為一個通用的運(yùn)維工具產(chǎn)品,我們又無法預(yù)知用戶的應(yīng)用場景與設(shè)計理念,因此這個故障模型必須做改造。
數(shù)據(jù)庫緩沖命中率指標(biāo)也存在類似問題,某些場景中,數(shù)據(jù)庫緩沖命中率低有可能是PG數(shù)據(jù)庫設(shè)定好的場景,無需告警。我們?nèi)绻€是模仿Oracle的方式來預(yù)警則可能會產(chǎn)生大量的誤報。如果新增的“數(shù)據(jù)庫物理讀”大部分都產(chǎn)生了操作系統(tǒng)的物理讀,那么才需要進(jìn)行告警,而如果新增的“數(shù)據(jù)庫物理讀”并沒有大幅增加OS的物理IO,那么這種現(xiàn)象可能是數(shù)據(jù)庫參數(shù)配置的正常現(xiàn)象,應(yīng)該被自動排除。
針對數(shù)據(jù)庫緩沖區(qū)命中率的理解也是如此,當(dāng)數(shù)據(jù)庫緩沖區(qū)命中率較低的時候,我們沒有必要直接報警,而是要看操作系統(tǒng)IO總量是否大幅度增加,如果操作系統(tǒng)IO總量沒有明顯增加,那么這種數(shù)據(jù)庫緩沖命中率的下降應(yīng)該是正常的。
這兩個在Oracle中可以使用的故障模型必須進(jìn)行優(yōu)化,加入實際物理讀大幅增加的條件。但是如何描述大幅增加呢?這里就需要用到異常檢測算法了。
在D-SMART中,1000105這個指標(biāo)的含義是關(guān)鍵指標(biāo)異常,這是一個復(fù)合指標(biāo),是針對基礎(chǔ)指標(biāo)進(jìn)行異常檢測生成的。比如30000100是操作系統(tǒng)的IOPS指標(biāo),當(dāng)這個指標(biāo)出現(xiàn)大幅上升的時候,就意味著IO異常增長。因此在那兩個故障模型中,可以加入1000105[30000100]=4這個規(guī)則,從而讓告警更為精準(zhǔn)。?