注意!!!給正在學習PG數據庫的Oracle DBA提個醒
我認識的很多Oracle DBA都在學習PG,不論是國內還是國外。數據庫多元化發展,擁抱開源是一個趨勢性的東西。對于Oracle DBA來說,PG這樣的學院派數據庫無論從架構上還是從功能上都有一定的相似性,學習起來會感到比較親切。雖然如此,PG數據庫和Oracle是差異很大的,哪怕一些看似近似的概念,因為兩種數據庫的實現方式不同,在實際應用中的差異很大。今天我就通過幾個容易引發誤解的問題,給大家提個醒。
曾經有人和我討論PG的WORK_MEM,他覺得PG的WORK_MEM就有點類似于Oracle的PGA手工管理。粗粗一看,好像還真的像,不過如果你完全按照使用Oracle PGA的*_area_size一樣來使用WORK_MEM,那是早晚會遇到坑的。我們知道,PG數據庫缺少HASH ANTI JION算子,因此在處理一些NOT IN類型的子查詢時往往使用Filter算子,這個算子通過對子查詢的結果集生成HASH表,然后由外表來循環探測,最終完成NOT IN過濾。
圖片
這種執行計劃,雖然外表比較大的時候效率不高,不過總體執行性能大多數情況下還是能接受的。如果我們繼續加大T2表符合條件的結果集的數據量,再來執行一下這條SQL。
圖片
當內表的結果集需要生成的HASH表的大小大于WORK_MEM的時候,執行計劃居然變了。在不使用HASH表的情況下,這條SQL的執行時間惡化到75146毫秒。我的測試環境是PG 14,起碼在這個當前使用量比較大的版本中,PG是不會使用多個WORK_MEM,或者采用類似Oracle的2-PASS HASH TABLE的機制來動態處理的。在這種情況下,我們只能通過會話級臨時加大WORK_MEM來解決問題。
圖片
上面的例子可以看出,當WORK_MEM加大到128MB的時候,又開始使用HASH表了,執行效率也回來了。
對Oracle DBA的第一個認知挑戰是,WORK_MEM設置的改變會影響SQL的執行計劃。可能現在的Oracle DBA已經忘記PGA手工管理了,在當年服務器內存資源有限,磁盤IO性能極差的年代里,設置合理的PGA參數并非易事。目前面對PG,可能這個問題會更加嚴峻,在一些大型關鍵企業應用系統中,設置適當的WORK_MEM的重要性比PGA手工管理時代更加重要。設置過大的WORK_MEM,有可能導致物理內存不足,設置太小,會讓有些SQL跑不出來。對于特殊的SQL,設置會話級的WORK_MEM可能是更好的解決方案。
第二個容易讓學習PG的Oracle DBA困惑的是CURSOR SHARING機制。在Oracle數據庫中,CURSOR SHARING的性能十分關鍵,對于高并發的應用來說,這一點尤為重要。如果硬解析過多,會消耗不必要的CPU資源,嚴重時會引發性能危機。與Oracle不同的是,PG雖然學習了Oracle的CURSOR共享機制,采用了一種類似的方法來解決共享CURSOR和避免多種最優執行計劃導致的SQL性能問題。PG沒有類似Oracle的共享池機制,因此不可能有全局CURSOR的概念。PG的CURSOR共享是會話級的,不是實例級的。在PG的一個會話中,一條SQL的前五次執行,每次都會重新生成執行計劃,如果前五次編譯發現存在通用執行計劃,那么這個通用執行計劃就會被共享。
與Oracle的CURSOR SHARING相比,這種機制要難管理多了,對于類似的SQL,很可能因為綁定變量的不同,導致不同的會話中某條SQL 的執行計劃是不同的,執行效率存在很大的差異。在Oracle數據庫中如果我們發現某個SQL的執行計劃因為BIND PEEKING 等方面的原因發生了錯誤,那么我們在共享池中將這個CURSOR PURGE掉,下一次SQL被執行時就會重新生成執行計劃,大概率會糾正以前的錯誤了。不過在PG里,因為沒有全局共享CURSOR而變得十分困難了。當然通過對相關表做DDL會讓所有會話的執行計劃失效,或者殺掉某個存在問題的會話可以解決這個問題。
實際上在一個并發相當高的PG數據庫中要對執行頻繁的表做DDL,其副作用也遠遠大于Oracle數據庫,突如其來的SQL解析風暴很可能打爆服務器的CPU,從而引發性能故障。
基于上面的一些問題,作為DBA,應該盡可能為自己的PG數據庫申請更多的CPU和物理內存資源。在服務器資源相對充足的系統中,上述兩個問題帶來的影響都可以得到一定程度的控制。
今天的時間關系,我們先討論這兩個問題,如果PG數據庫承擔了高負載的關鍵業務系統,那么DBA也許真的會在生產環境中遇到這些問題,希望今天的文章對于正在學習或者轉型到PG數據庫的Oracle DBA有所幫助。也給這些DBA提個醒,有些表面上的概念,實際上PG和Oracle是有本質差異的。比如流復制VS DATAGUARD ,WAL VS REDO,分區表,CHECKPOINT,等等等等。