MVCC缺陷與高負載PG資料庫最佳化要點

DBAIOps社区發表於2024-02-20

PostgreSQL的M VCC 實現機制是採用資料塊中生成多個副本的方式的,這種機制被很多 D BA 和架構師認為是 PostgreSQL資料庫在大型高負載系統中的一個巨大的缺陷。實際上不只是PostgreSQL採用了多副本行元來實現M VCC ,目前比較熱門的基於 LSM-Tree儲存引擎的資料庫系統(比如阿里的Oceanbase,PingCAP的TiDB)也採用了這種方式。L SM- Tree需要透過Compare   And Merge這種開銷更大的方式來進行老元組的合併重組,而PostgreSQL使用Vacuum機制來進行資料整理。

可能很多朋友都認為 Vacuum的開銷很大,對資料庫表的效能影響也很大,甚至在出現過Vacuum影響業務系統之後,關閉了AutoVacuu m 。在 Postgre SQL 9之前,Vacuum的演演算法確實對高負載資料庫的影響很大,甚至那時候筆者認為PostgreSQL的M VCC 的缺陷會影響 PostgreSQL在企業級應用中的使用。不過隨著這些年PostgreSQL資料庫的快速發展,每個版本對Vacuum的演演算法都有了極大的改善,在目前硬體效能極大提升與PostgreSQL   Vacuum的演演算法的最佳化雙重作用下,目前Vacuum對高負載資料庫的影響也越來越低了。

可能還有一些朋友可以舉出一些反例,說我們的資料庫因為 Vacuum而導致資料庫效能出現嚴重問題了。確實可能會出現這樣的反例,不過如果仔細分析一下,透過對PostgreSQL資料庫的效能最佳化,這些反例中遇到的問題大多數都是可以解決的。

前陣子我在網上看到過一個某網際網路汽車租賃公司的案例,他們的 PostgreSQL資料庫的AutoVacuum出現了嚴重的效能問題,租車訂單表每天要消耗幾百萬個x id ,而每天的 autovacuum 只能回收其中 70%的x id ,這意味著一個十分嚴重的問題, x id wraps 的問題。當系統執行一段時間之後,就必須進行停庫維護,透過 v acuum 來完成 x id 的完全回收,從而防止未回收 x id 達到 20億這個可能導致資料庫停庫的問題出現。當時客戶已經在討論是不是要透過更換資料庫來徹底解決這個問題了,不過後來的一次資料庫最佳化讓這個系統擺脫了x id wraps 困境。

整個最佳化工作也十分簡單。僅僅是一些 Postgresql引數的調整:

序號

引數

調整值

1

autovacuum_work_mem

2 GB

2

autovacuum_vacuum_cost_limit

2 000/ 最終調整為 3000

(對於使用 S SD 盤的環境,預設的 200太保守了)

3

maintenance_work_mem

1 GB

4

work_mem

1 6MB

5

autovacuum_max_workers

5

透過上面的引數調整後,每天可回收的 xid 超過了 5億,x id wraps 問題得到了徹底的解決。

實際上我們遇到的很多 PostgreSQL的問題主要是因為我們對PostgreSQL資料庫的認知的不足,從而導致我們遇到問題後不知道該如何去解決。不過PostgreSQL的MVCC帶來的負面問題也並不是總能夠透過調整資料庫引數來解決的。事實上,有些應用對資料庫的隨意使用是導致很多較為難以解決的資料庫效能問題的最主要的原因。記得十多年前幫一個運營商解決的b uffer busy waits 導致的效能問題,最終也是把那張 u pdate 十分頻繁的花費餘額表改造成記憶體資料庫才得以徹底的解決。如果那個場景用 PostgreSQL來實現,哪怕是十多年後的硬體環境下,因為M VCC 實現技術方面的缺陷,恐怕 P G 資料庫依然是搞不定的。

所以說雖然我們能夠透過資料庫最佳化的手段去解決大部分的 PostgreSQL資料庫的問題,我們還需要應用開發者瞭解資料庫存在的一些缺陷,從而在應用架構設計以及應用開發時能夠儘可能規避PostgreSQL的一些缺陷,讓應用系統執行的更好。

 


來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70036742/viewspace-3006849/,如需轉載,請註明出處,否則將追究法律責任。

相關文章