大多數人最初意識到這個問題,認為他們需要監控的問題,就是事務 ID 回卷本身,但從技術上講,事務 ID 的耗盡才是真正的問題。PostgreSQL 在技術上能夠很好地處理事務 ID 的回卷。但是,如果達到回卷點,事務 ID 會即將用完,這才是為什么回卷本身會令人擔憂的原因。
以下查詢可以提供非常簡單的數據,來指示問題的趨勢/警報。
WITH max_age AS ( SELECT 2000000000 as max_old_xid , setting AS autovacuum_freeze_max_age FROM pg_catalog.pg_settings WHERE name = 'autovacuum_freeze_max_age' ), per_database_stats AS ( SELECT datname , m.max_old_xid::int , m.autovacuum_freeze_max_age::int , age(d.datfrozenxid) AS oldest_current_xid FROM pg_catalog.pg_database d JOIN max_age m ON (true) WHERE d.datallowconn )SELECT max(oldest_current_xid) AS oldest_current_xid , max(ROUND(100*(oldest_current_xid/max_old_xid::float))) AS percent_towards_wraparound , max(ROUND(100*(oldest_current_xid/autovacuum_freeze_max_age::float))) AS percent_towards_emergency_autovacFROM per_database_stats;
percent_towards_wraparound 指標是設置警報的真正關鍵指標。由于它使用 age() 函數來確定事務 ID 值,因此它會考慮它們是否真的處于耗盡點,以查看回卷是否是一個真正的問題。如果達到耗盡,數據庫將被迫關閉,并可能導致不確定的停機時間,以進行修復。此查詢中有一點緩沖,因為它檢查的上限(確切地說是 20 億)小于導致耗盡的實際最大整數值。但它已經足夠接近了,應該立即對達到 100% 的警報采取行動。
percent_towards_emergency_autovac 指標是我們建議監控的一個附加值,特別是對于以前從未監控過此指標的系統(請參閱下面有關凍結的近期好處的說明,了解何時可以調低該警報優先級或移除它)。它將監視數據庫中達到 autovacuum_freeze_max_age 的最高事務 ID 值。
這是一個用戶可調的值,默認值為 2 億,當任何表的最高事務 ID 值達到該值時,在該表上會啟動一次更高優先級的自動清理。您可以識別出這個特殊的清理會話,因為在 pg_stat_activity 中,它會被標記為 (to prevent wraparound)。從某種意義上說,它的優先級更高,即使禁用了自動清理,它也會運行,如果手動取消該清理,它幾乎會立即再次重新啟動。它還需要一些不同的內部低級鎖,因此根據它們在緊急清理期間的鎖定方式,可能會在這些表上引起稍高的爭用。
如果您確實遇到爭用/鎖定問題,并且可以確認問題來源于緊急清理,那么取消它以完成其他事務也是完全安全的。請注意,它會繼續重新啟動,直到能夠成功完成回卷式清理或運行了一次手動清理。
對于每秒事務數很高的數據庫,想要避免緊急清理期的頻繁出現,增加 autovacuum_freeze_max_age 可能是有益的。增加此值的主要問題是,它可能會增加數據目錄下 pg_xact 和 pg_commit_ts 文件夾中的存儲空間。同樣,請閱讀上面鏈接中的日常清理文檔,了解調整此設置時的這些存儲要求。一般可以將此值設置為 10 億,不會有太大問題,但前提是需要確定有在監控回卷并且磁盤空間足夠。
要使最高事務 ID 的 age 值回落,最簡單(但不一定是最快)的方法是,強制對整個數據庫集群進行一次清理。要實現這種集群范圍的清理,最好方法是用 PostgreSQL 附帶的 vacuumdb 二進制實用程序。
vacuumdb --all --freeze --jobs=2 --echo --analyze
--all 選項可確保對所有數據庫都進行清理,因為事務 ID 是一個全局值。--freeze 選項可確保運行更激進的清理,以確保在該表中凍結盡可能多的元組(有關凍結的詳細信息,請參閱日常清理)。
--jobs=2 允許并行運行多個清理。這應該設置在系統處理能力的范圍內,以加快速度,但要小心設置得太高,因為它會導致額外的 IO 和更快地生成 WAL(增加磁盤使用率)。--echo 只是提供一些很小的反饋,以讓您可以看到一些進度。--analyze
在這里要提到的 --freeze 選項的另一個好處是,在未來的清理操作中,可以大大減少 IO 和 WAL 的產生。PostgreSQL 9.6 引入了一項功能,如果頁面中的所有元組都已標記為凍結,則 vacuum 能夠跳過該頁面。PostgreSQL 11 在索引方面對此進行了進一步改進。
因此,如果您有很多舊表不再被寫入,那么當它們因任何原因需要 vacuum 時,這是一個成本低得多的操作。這也讓 percent_towards_emergency_autovac 警報不那么令人擔憂,因為它不會產生太多意外的突發活動。因此,一旦你把事情調整好了,你可以把這個警報看作是低優先級的警告,甚至可以刪除它,只用擔心對回卷本身的監控。
本文鏈接:http://www.tebozhan.com/showinfo-26-88733-0.htmlPostgreSQL 的事務 ID 回卷,應對措施也很簡單
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: 從零開始搭建 Kafka 集群
下一篇: 我們一起聊聊Go語言中的數組和切片