生產 PostgreSQL 空間問題,巨大的 pg_largeobject,新手被扔下深淵!
伺服器:PG 9.4,Linux,設置不佳/預設設置,不關心和餵食
數據庫:6 個使用者數據庫,全部在 pg_default 上
CT 數據庫:~435GB pg_largeobject 在該數據庫表大小:427GB 總大小:433GB 索引大小:5.7GB
所有其他數據庫 < 10GB 的總和
問題:表空間被填滿,應用程序崩潰,沒有頭的雞。我,擁有約 60K 小時經驗的 SQL Server 顧問被告知“看看你能不能解決這個問題,我們沒有人”。我對 PostgreSQL 的經驗為零。
最初的反應:當我對如何連接做最少的研究時,得到了一個工具來做這些,等等等等,並初步尋找我可以刪除的垃圾磁碟文件,以釋放任何空間讓它們恢復線上,神奇地應用程序再次開始工作。
翻來覆去、抽搐和四處搜尋,我發現一個 VACUUM 在損壞和工作之間執行。不過,pg_stats_all_tables 的 last_autovacuum 列為 NULL。
目前狀態:pg_largeobject 現在有 n_live_tup 143M、n_tup_del 55K、n_tup_upd 56K、n_dead_tup 724K(最後一個上升得相當快)
我讓他們配置了一個新磁碟,他們給了我 800GB(文件系統:/dev/stb,安裝在:/data)。我希望我描述得足夠充分
截至目前,我可以完全訪問數據庫伺服器,沒有其他活動(有人告訴我)。
潛在計劃 A:
a) 創建一個包含 800GB 磁碟空間的新表空間
b) 在 CT.pg_largeobject 上執行 VACUUM FULL,同時將來自 VACUUM 的新寫入的新寫入副本從 VACUUM 放置到新表空間中。根據文件,我有足夠的空間。我沒有足夠的空間來存放我發現引用的“re_pack”,這需要~2X 空間。
遺憾的是,我在文件中看不到任何方法來指定 VACUUM FULL 上的表格副本位置。
潛在的 B 計劃:
ALTER TABLE pg_largeobject SET 表空間到新的 800GB 一個
可悲的是,這似乎沒有能力在移動過程中清理桌子上的垃圾。
潛在計劃 C:
只需在 FULL(凍結?)以下做一個 VACUUM 級別,並希望騰出足夠的空間來收工。
恐懼:對於任何一種選擇,我都擔心會炸毀預寫日誌。每個配置的目前設置:
wal_level = ‘邏輯’
最後:
似乎除非我可以進行“compact-during-move-to-new-tablespace”的演進,否則在我得到的約束下,這張表永遠無法完全 VACUUMed。
老實說,我真的不在乎。我想盡可能簡單快速地解決這個問題,並且能夠告訴客戶 PG 正在執行,並且在可預見的將來不會因為空間而再次崩潰。最好不要在過程中完全FUBARing事情!
想法??哪個計劃可以讓他們避免再次用完空間而不會導致諸如填滿日誌之類的問題?還是我需要做一些我還沒有遇到過的事情?
非常感謝幫助!
更新 20220216 1225ish
a) 我在伺服器上的所有 Linux 目錄中尋找“垃圾/臨時/不必要”文件,而不是任何服務/應用程序(如 PG)所需的文件
b)我沒有添加表空間,這是一個可能的計劃。
c) 我還沒有執行任何形式的 VACUUM,更不用說 FULL 了。
d) 我已經嘗試根據我的研究編譯 pgstattuple,它編譯失敗,我確實進一步追求。
e) 我和公司的任何人都有 PG 的經驗,所以升級風險太大。
f) 沒有人有能力在客戶端更改應用程序。
g) 如果 ..stats.. 中的 autovacuum 列全部為 NULL,這是否意味著 AV 尚未執行?
第2部分:
- 這是 VMWare VM 和 centOS。我喜歡擴大體積的想法,我會詢問並希望它是可行的!
- 我如何將整個 PG 實例移動到新卷?
- 應用程序確實需要它包含的所有數據
- VACUUM(和表空間改變表)希望同時清理和移動。大量已知且不斷增加的死亡記錄。我想知道有多少其他行可能處於“可移動”狀態
- 見下文關於 pgstattuple。我可能需要調試並使其正常工作。6) Vacuumlo -n CT 是從 pgsql 命令行執行的,對嗎?
- 如果添加新表空間,我可以讓一個表開始使用它來儲存新數據,而保持現有狀態嗎?在 SQL Server 中,如果您將新文件添加到文件組,則該文件組上的所有對像都可以立即訪問新文件。
更新 20220216 1530ish
管理團隊告訴我,擴展卷不是一種選擇——卷不在伺服器儲存的末尾。伺服器/作業系統的年齡以及缺乏 Linux 經驗以及客戶端無法完全訪問 VMWare 環境的託管安排可能是因素。
更新 20220217 15:15
A) 我終於能夠編譯 pgstattuple。今天,當所有使用者都離開系統時,我將在 1730 之後對 CT.pg_largeobject 表執行這個。
B)我試圖創建擴展vacuumlo,但失敗並顯示“/usr/pgsql-9.4/share/extension/vacuumlo.control”消息:沒有這樣的文件或目錄。雖然我可以在該目錄中看到其他 .sql 和 .control 文件,但 Vacuumlo 文件失去了。然後我去了 /usr/pgsql-9.4/share/contrib 目錄,我以為我看到這些程式碼存在,但那裡只有一個文件,sepgsql.sql。
我迷迷糊糊地在 /bin 目錄中找到了 Vacuumdb、vacuumlo、pgbench 等。但我似乎無法執行或獲取有關 Vacuumlo 的任何資訊。
問:我如何編譯/使用vacuumlo?
詢問負責儲存的人員(假設他們知道自己在做什麼)是否不能將現有捲擴展 800GB,而不是將新空間附加為新分區/卷。一些 RAID 系統或捲管理器將允許這種動態調整大小。如果可以做到,那麼問題就解決了。
如果他們不能擴展它,我不喜歡多表空間選項。這給一個已經比你能處理的更複雜的系統增加了更多的複雜性。與其將主要對象移動到新的表空間留下一個小臀部,不如將整個 PostgreSQL 實例移動到新的更大的磁碟上,完全釋放舊磁碟。它可能會更快。這將需要整個實例關閉以進行移動,但無論如何它在線上遷移期間的可用性是值得懷疑的,它的主要對像被鎖定並且IO系統被淹沒。
詢問這個系統的高級最終使用者,這個數據庫這麼大是否有意義。到底是什麼東西佔用了這麼大的空間?
執行
vacuumlo -n CT
。這將告訴您有多少對象未被數據庫中的其他(明顯)位置引用。您非常關注 VACUUM FULL。僅當 pg_largeobject 臃腫時才有意義。也許它正在有效地儲存它被告知要儲存的所有東西——這只是很多東西。在擔心它是否會膨脹之前,先看看它是否真的膨脹了。一種方法是使用 pgstattuple。更快的方法是使用 pg_freespace,但這取決於可能已過時的元數據,因此您應該首先確保該表最近是 VACUUMed(但無論如何您都應該這樣做)。
至於炸毀 WAL,如果您確實將表移動到新表空間,這是一個問題。但是 的設置
wal_level = 'logical'
並沒有多大意義——它只是未能排除這種擔憂。您需要確定archive_command 是否實際在使用,或者複製槽是否確實存在,並評估它們跟上的能力。
你從所有錯誤的方向開始:
- 不要刪除數據目錄中的文件
- 不要創建表空間
VACUUM (FULL)
除非你知道它被指示,否則不要執行首先,創建
pgstattuple
擴展以檢查是否pg_largeobject
真的臃腫:SELECT tuple_len, tuple_percent, dead_tuple_len, dead_tuple_percent, free_space, free_percent FROM pgstattuple('pg_largeobject');
這將需要一段時間,但會告訴您是否
pg_largeobject
真的臃腫,或者它是否因為包含大量數據而太大。如果它臃腫,通過減少
autovacuum_vacuum_cost_delay
很多來調整autovacuum更快,增加預設表空間中的磁碟空間並在表上執行VACUUM (FULL)
。長期目標:
- 升級(我什至不想知道你正在執行什麼次要版本)
- 更改應用程序,使其不使用存在大量已知問題的大對象