診斷資料表和索引膨脹 - Amazon Aurora

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

診斷資料表和索引膨脹

您可以使用 PostgreSQL 多版本並行控制 (MVCC) 來協助維護資料的完整性。PostgreSQL MVCC 的運作方式是儲存更新或刪除的資料列 (元組) 內部複本,直到交易提交或復原。使用者看不到這份儲存的內部複本。但是,若 VACUUM 或 AUTOVACUUM 公用程式未定期清理這些隱藏複本,便可能發生資料表膨脹。不選取,資料表膨脹可能會增加儲存成本並降低處理速度。

在許多情況下,Aurora 上 VACUUM 或 AUTOVACUUM 的預設設定足夠處理不需要的資料表膨脹。但是,若您的應用程式遇到以下情況,可能需要檢查膨脹情形:

  • 在 VACUUM 程序間的較短時間內處理大量交易。

  • 執行效果不佳且儲存空間不足。

若要開始使用,請取得失效元組使用空間量的準確資訊,以及您能透過清理資料表和索引膨脹來復原的空間量。若要這麼做,請使用 pgstattuple 擴充功能來取得 Aurora 叢集上的統計資料。如需更多詳細資訊,請參閱 pgstattuple。只有 pg_stat_scan_tables 角色和資料庫超級使用者能使用 pgstattuple 擴充功能。

若要在 Aurora 上建立 pgstattuple 擴充功能,請將用戶端工作階段連線到叢集,例如 psql 或 pgAdmin,然後使用下列命令:

CREATE EXTENSION pgstattuple;

在您要設定的每個資料庫中建立擴充功能。建立擴充功能之後,請使用命令列界面 (CLI) 來計算您可以收回多少無法使用的空間。在取得統計資料之前,請先將 AUTOVACTURE 設為 0,以修改叢集參數群組。將該值設為 0 可防止 Aurora 自動清除應用程式留下的任何失效元組,進而影響結果準確性。輸入下列命令建立簡易資料表:

postgres=> CREATE TABLE lab AS SELECT generate_series (0,100000); SELECT 100001

在下方範例中,我們在啟用 AUTOVACUUM 的情況下執行資料庫叢集查詢。dead_tuple_count 為 0,表示 AUTOVACUUM 已從 PostgreSQL 資料庫刪除過時的資料或元組。

若要以 pgstattuple 來取得資料表相關資訊,請在查詢中指定資料表名稱或物件識別碼 (OID):

postgres=> SELECT * FROM pgstattuple('lab');
table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent -----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+-------------- 3629056 | 100001 | 2800028 | 77.16 | 0 | 0 | 0 | 16616 | 0.46 (1 row)

在下方的查詢中,我們關閉 AUTOVACUUM 並輸入命令,從資料表中刪除 25,000 資料列。結果是,dead_tuple_count 增加到 25000。

postgres=> DELETE FROM lab WHERE generate_series < 25000; DELETE 25000
SELECT * FROM pgstattuple('lab');
table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent -----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+-------------- 3629056 | 75001 | 2100028 | 57.87 | 25000 | 700000 | 19.29 | 16616 | 0.46 (1 row)

若要回收這些無效元組,請啟動 VACUUM 程序。

在不中斷應用程式的情況下觀察膨脹情形

Aurora 叢集上的設定經過最佳化,可為多數工作負載提供最佳實務。不過,您可能想最佳化叢集,以更符合您的應用程式和使用模式。在此情況下,您可以使用 pgstattuple 擴充功能,且不會中斷忙碌的應用程式。若要這麼做,請執行下列步驟:

  1. 複製您的 Aurora 執行個體。

  2. 修改參數檔案,以關閉複製中的 AUTOVACUUM。

  3. 執行 pgstattuple 查詢時以範例工作負載或 pgbench 測試複製,pgbench 是在 PostgreSQL 上執行基準測試的程式。如需更多詳細資訊,請參閱 pgbench

執行應用程式並檢視結果之後,請在還原的複本上使用 pg_repack 或 VACUUM FULL 並比較差異。若 dead_tuple_count、dead_tuple_len 或 dead_tuple_percent 的值顯著下降,請調整生產叢集上的真空排程,盡量減少膨脹。

避免暫存資料表膨脹

若您的應用程式要建立暫存資料表,請確認應用程式會在不需要暫存資料表後進行移除。自動清空程序找不到暫存資料表。保持不選取,暫存資料表可以快速建立資料庫膨脹。此外,膨脹可以擴展到系統資料表,也就是追蹤 PostgreSQL 物件和屬性的內部資料表,例如 pg_attribute 和 pg_depend。

當不再需要暫存資料表時,您可以使用 TRUNCATE 陳述式來清空資料表並釋放空間。然後,手動清空 pg_attribute 和 pg_depend 資料表。清空這些資料表,確保不斷建立和截斷/刪除暫存資料表時,不會新增元組並導致系統膨脹。

您可以在建立暫存資料表時避免這個問題,方法是加入下列語法,在提交內容時刪除新資料列:

CREATE TEMP TABLE IF NOT EXISTS table_name(table_description) ON COMMIT DELETE ROWS;

遞交交易時,ON COMMIT DELETE ROWS 子句會截斷暫存資料表。

避免索引膨脹

變更資料表的索引欄位時,索引更新會導致該索引出現一或多個失效元組。根據預設,自動清空程序會清除索引中的膨脹,但是該清理程序會佔用大量時間和資源。若要在建立資料表時指定索引清理偏好設定,請包括 vacuum_index_cleanup 子句。根據預設,建立資料表時,子句會設為 AUTO,表示伺服器會決定索引在清空資料表時是否需要進行清除。您可以將子句設為 ON 以開啟特定資料表的索引清除,或設為 OFF 關閉該資料表的索引清除。請留意,關閉索引清除可能會節省時間,但同時也可能導致索引膨脹。

清空資料表時,您可以在命令列中手動控制索引清除。若要清空資料表並從索引中刪除失效元組,請包括值設為 ON 的 INDEX_CLEANUP 子句和資料表名稱:

acctg=> VACUUM (INDEX_CLEANUP ON) receivables; INFO: aggressively vacuuming "public.receivables" VACUUM

若要在不清除索引的情況下清空資料表,請將值設為 OFF:

acctg=> VACUUM (INDEX_CLEANUP OFF) receivables; INFO: aggressively vacuuming "public.receivables" VACUUM