本文提供適用於 PostgreSQL 的 Azure 資料庫 自動清空功能的概觀,以及可用來監視資料庫膨脹和自動清空封鎖程式的功能疑難排解指南。 它也會提供有關資料庫距離發生緊急情況或「循環覆寫」(wraparound) 情況還有多遠的資訊。
附註
本文將說明「適用於 PostgreSQL 的 Azure 資料庫 - 彈性伺服器」中所有受支援的 PostgreSQL 版本的自動清理程式 (autovacuum) 微調。 提及的某些功能是特定於版本的 (例如 vacuum_buffer_usage_limit PostgreSQL 16 和更新版本,以及 autovacuum_vacuum_max_threshold PostgreSQL 18 和更新版本)。
什麼是自動真空?
自動資料清理是一種 PostgreSQL 背景處理程序,可自動清除無效 Tuple 和更新統計資料。 此功能可自動執行兩項主要維護工作來協助維護資料庫效能:
- VACUUM - 移除死元組,並將該空間標示為PostgreSQL可重複使用,以回收資料庫檔案內的空間。 它不一定會減少磁碟上資料庫檔案的實體大小。 若要將空間傳回作業系統,請使用重寫資料表的作業 (例如 VACUUM FULL 或 pg_repack),這些作業具有其他考量,例如專用鎖定或維護時段。
- ANALYZE - 收集 PostgreSQL 查詢規劃器用來選擇高效執行計劃的資料表和索引統計資料。
若要確保自動清空正常運作,請將自動清空伺服器參數設為 ON。 啟用時,PostgreSQL 會自動決定何時在資料表上執行 VACUUM 或 ANALYZE,確保資料庫保持效率和最佳化。
自動資料清理內部
自動清理程式會讀取資料頁面,以尋找裡面沒用的 Tuple (dead tuples)。 如果未找到任何沒用的 Tuple,自動清理程式就會捨棄該頁面。 自動資料清理找到無效 Tuple 時,就會將它們移除。 成本基於以下參數:
| 參數 | 描述 |
|---|---|
vacuum_cost_page_hit |
讀取已在共用緩衝區中且不需要磁碟讀取的頁面的成本。 預設值為 1。 |
vacuum_cost_page_miss |
擷取不在共用緩衝區內頁面的成本。 預設值為 10。 |
vacuum_cost_page_dirty |
在找到無效 Tuple 的頁面中來進行寫入的成本。 預設值為 20。 |
自動清空執行的工作量取決於兩個參數:
| 參數 | 描述 |
|---|---|
autovacuum_vacuum_cost_limit |
自動資料清理的工作量一次執行完成。 |
autovacuum_vacuum_cost_delay |
當自動資料清理達到 autovacuum_vacuum_cost_limit 參數指定的成本限制後,自動資料清理進入睡眠狀態的毫秒數。 |
在目前支援的所有 PostgreSQL 版本中,預設 autovacuum_vacuum_cost_limit 值為 200 (實際上,設定為 -1,這使得它等於常規 vacuum_cost_limit的值,預設為 200)。
在PostgreSQL版本12和更新版本中,預設 autovacuum_vacuum_cost_delay 值為2毫秒(在版本11中為20毫秒)。
緩衝區使用限制 (PostgreSQL 16+)
從 PostgreSQL 第 16 版開始,您可以使用參數 vacuum_buffer_usage_limit 來控制 VACUUM、ANALYZE 和自動清理作業期間的記憶體用量。
| 參數 | 描述 |
|---|---|
vacuum_buffer_usage_limit |
設定 VACUUM、ANALYZE 及自動清理程式作業的緩衝池大小。 此參數會限制這些作業可以使用的共用緩衝區快取數量,防止它們耗用過多的記憶體資源。 |
此參數有助於防止 VACUUM 和自動清理程式作業從共用緩衝區中移除過多有用的資料頁面,從而可以在維護作業期間提升整體資料庫的效能。 預設值通常是根據 shared_buffers設定的,您可以對其進行配置,以平衡真空效能與一般資料庫作業的需求。
自動清理的最大閾值(PostgreSQL 18+)
從 PostgreSQL 第 18 版開始,您可以使用參數 autovacuum_vacuum_max_threshold 來設定觸發自動清空的元組更新或刪除次數上限。
| 參數 | 描述 |
|---|---|
autovacuum_vacuum_max_threshold |
設定在執行 VACUUM 作業之前,Tuple 最多可以被更新或刪除的次數。 當設定為 -1時,會停用臨界值上限。 可以使用這個參數來精細控制自動清理程式在超大資料表上何時觸發啟動。 |
這個參數對於大型資料表特別有用,因為預設依照比例 (scale factor) 決定觸發啟動時機的方式,可能會讓自動清理程式等太久才開始執行。
自動資料清理每秒喚醒 50 次 (50*20 毫秒=1000 毫秒)。 每次喚醒時,自動資料清理都會讀取 200 頁。
這意味著在一秒鐘內自動吸塵可以做到:
- ~80 MB/秒 [ (200 頁/
vacuum_cost_page_hit) * 50 * 每頁 8 KB];如果在共用緩衝區中找到所有含無效 Tuple 的頁面。 - ~8 MB/秒 [ (200 頁/
vacuum_cost_page_miss) * 50 * 每頁 8 KB];如果從磁碟讀取到所有含無效 Tuple 的頁面。 - ~4 MB/秒 [ (200 頁/
vacuum_cost_page_dirty) * 50 * 每頁 8 KB] 自動資料清理寫入速度最高可達 4 MB/秒。
監視自動資料清理
適用於 PostgreSQL 的 Azure 資料庫提供下列計量來監視自動清空。
自動真空指標可用來監控和調整 Azure Database for PostgreSQL 彈性伺服器的自動真空效能。 每個計量都會以 30 分鐘的間隔發出,而且最多有 93 天的保留期。 您可以建立特定計量的警示,並可以使用 DatabaseName 維度分割和篩選計量資料。
如何啟用自動清理計量
- 自動清理計量依預設為停用。
- 若要啟用這些計量,請將伺服器參數
metrics.autovacuum_diagnostics設定為ON。 - 此參數是動態,因此不需要執行個體重新啟動。
自動清理計量清單
| 顯示名稱 | 計量識別碼 | 單位 | 描述 | 尺寸 | 預設為啟用 |
|---|---|---|---|---|---|
| 分析計數器使用者資料表 | analyze_count_user_tables |
Count | 已手動分析此資料庫中用戶專用資料表的次數。 | 資料庫名稱 | 否 |
| 自動分析計數器使用者資料表 | autoanalyze_count_user_tables |
Count | 此資料庫中自動清理精靈已分析僅限使用者資料表的次數。 | 資料庫名稱 | 否 |
| AutoVacuum 計數器用戶資料表 | autovacuum_count_user_tables |
Count | 此資料庫中自動清理精靈已清理僅限使用者資料表的次數。 | 資料庫名稱 | 否 |
| 膨脹百分比 (預覽) | bloat_percent |
百分比 | 僅限使用者資料表的預估膨脹百分比。 | 資料庫名稱 | 否 |
| 預估的無效資料列使用者資料表 | n_dead_tup_user_tables |
Count | 此資料庫中僅限使用者資料表的預估無效資料列數目。 | 資料庫名稱 | 否 |
| 預估的有效資料列使用者資料表 | n_live_tup_user_tables |
Count | 此資料庫中只包含使用者資料表的現有資料列的預估數目。 | 資料庫名稱 | 否 |
| 預估的修改使用者資料表 | n_mod_since_analyze_user_tables |
Count | 自上次分析僅限使用者的資料表後所修改的預估資料列數目。 | 資料庫名稱 | 否 |
| 已分析的使用者資料表 | tables_analyzed_user_tables |
Count | 此資料庫中已分析的僅限使用者資料表數目。 | 資料庫名稱 | 否 |
| 已自動分析的使用者資料表 | tables_autoanalyzed_user_tables |
Count | 此資料庫中自動清理精靈已分析的僅限使用者資料表數目。 | 資料庫名稱 | 否 |
| 已自動清理的使用者資料表 | tables_autovacuumed_user_tables |
Count | 此資料庫中自動清理程序已清理的僅由使用者建立的資料表數目。 | 資料庫名稱 | 否 |
| 使用者資料表計數器 | tables_counter_user_tables |
Count | 此資料表中僅限使用者資料表的數目。 | 資料庫名稱 | 否 |
| 使用者資料表已執行真空處理 | tables_vacuumed_user_tables |
Count | 此資料庫中已清理的僅限使用者資料表數目。 | 資料庫名稱 | 否 |
| 真空計數器用戶表 | vacuum_count_user_tables |
Count | 此資料庫中已手動清理僅限使用者資料表的次數 (不計算 VACUUM FULL)。 |
資料庫名稱 | 否 |
使用自動清理計量的考量
- 使用 DatabaseName 維度的自動清理指標限制於 30 個資料庫。
- 在「可高載」SKU 上,使用 DatabaseName 維度的計量有 10 個資料庫的限制。
- DatabaseName 維度限制會套用在 OID 資料行上,以反映資料庫建立的順序。
如需詳細資訊,請參閱自動清理程式的度量指標。
使用下列查詢來監視自動資料清理:
select schemaname,relname,n_dead_tup,n_live_tup,round(n_dead_tup::float/n_live_tup::float*100) dead_pct,autovacuum_count,last_vacuum,last_autovacuum,last_autoanalyze,last_analyze from pg_stat_all_tables where n_live_tup >0;
下面這些欄位可以幫助您判斷自動清理程式是否跟得上資料表的變動情況:
| 參數 | 描述 |
|---|---|
dead_pct |
相較於即時 Tuple 的無效 Tuple 百分比。 |
last_autovacuum |
上次自動清理資料表的日期。 |
last_autoanalyze |
上次自動分析資料表的日期。 |
觸發自動資料清理
當死元組數目超過特定數目時,會觸發自動清空動作 (ANALYZE 或 VACUUM)。 此數字取決於兩個因素:表格中的列總數,加上固定閾值。 預設情況下,當資料表的 10% 加上 50 列變更發生時觸發 ANALYZE,而 VACUUM 會在資料表的 20% 加上 50 列變更發生時觸發。 由於 VACUUM 臨界值是 ANALYZE 臨界值的兩倍,因此 ANALYZE 比 VACUUM 更早觸發。
對於 PostgreSQL 版本 13 及更高版本,預設情況下,當 20% 的資料表以及 1,000 個資料列插入時,ANALYZE 會自動觸發。
每個動作的確切方程式如下:
- Autoanalyze = autovacuum_analyze_scale_factor * tuples + autovacuum_analyze_threshold 或 autovacuum_vacuum_insert_scale_factor * tuples + autovacuum_vacuum_insert_threshold (適用於 PostgreSQL 版本 13 及更新版本)
- 自動資料清理 = autovacuum_vacuum_scale_factor * Tuple + autovacuum_vacuum_threshold
例如,如果您有包含 100 行的資料表,則下列方程式會顯示何時觸發分析和真空動作:
對於更新和刪除: Autoanalyze = 0.1 * 100 + 50 = 60Autovacuum = 0.2 * 100 + 50 = 70
ANALYZE 會在資料表上變更 60 列之後觸發,而 VACUUM 會在資料表上變更 70 列時觸發。
對於插入:Autoanalyze = 0.2 * 100 + 1000 = 1020
ANALYZE 會在資料表上插入了 1,020 筆資料列後觸發。
以下是方程式使用的參數描述:
| 參數 | 描述 |
|---|---|
autovacuum_analyze_scale_factor |
在資料表上觸發 ANALYZE 的插入、更新和刪除百分比。 |
autovacuum_analyze_threshold |
觸發 ANALYZE 資料表所需的最少 Tuple 數 (插入、更新或刪除的 Tuple 數)。 |
autovacuum_vacuum_insert_scale_factor |
觸發對資料表執行 ANALYZE 的插入數百分比。 |
autovacuum_vacuum_insert_threshold |
觸發 ANALYZE 資料表所需的最少 Tuple 數 (插入的 Tuple 數)。 |
autovacuum_vacuum_scale_factor |
觸發對資料表執行 VACUUM 的更新數與刪除數百分比。 |
使用下列查詢列出資料庫中的資料表,並找出符合自動資料清理流程的資料表:
SELECT *
,n_dead_tup > av_threshold AS av_needed
,CASE
WHEN reltuples > 0
THEN round(100.0 * n_dead_tup / (reltuples))
ELSE 0
END AS pct_dead
FROM (
SELECT N.nspname
,C.relname
,pg_stat_get_tuples_inserted(C.oid) AS n_tup_ins
,pg_stat_get_tuples_updated(C.oid) AS n_tup_upd
,pg_stat_get_tuples_deleted(C.oid) AS n_tup_del
,pg_stat_get_live_tuples(C.oid) AS n_live_tup
,pg_stat_get_dead_tuples(C.oid) AS n_dead_tup
,C.reltuples AS reltuples
,round(current_setting('autovacuum_vacuum_threshold')::INTEGER + current_setting('autovacuum_vacuum_scale_factor')::NUMERIC * C.reltuples) AS av_threshold
,date_trunc('minute', greatest(pg_stat_get_last_vacuum_time(C.oid), pg_stat_get_last_autovacuum_time(C.oid))) AS last_vacuum
,date_trunc('minute', greatest(pg_stat_get_last_analyze_time(C.oid), pg_stat_get_last_autoanalyze_time(C.oid))) AS last_analyze
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE C.relkind IN (
'r'
,'t'
)
AND N.nspname NOT IN (
'pg_catalog'
,'information_schema'
)
AND N.nspname !~ '^pg_toast'
) AS av
ORDER BY av_needed DESC ,n_dead_tup DESC;
附註
此查詢未考量您可以使用 “alter table” DDL 命令,以每個資料表為基礎設定自動清理。
常見的自動資料清理問題
檢閱下列自動清空程序的常見問題清單。
跟不上忙碌的伺服器
自動真空程序會預估每個 I/O 作業的成本,並累積執行過程中每個作業的總成本。一旦達到成本上限,程序便會暫停。 此程序使用兩個伺服器參數: autovacuum_vacuum_cost_delay 和 autovacuum_vacuum_cost_limit。
依預設, autovacuum_vacuum_cost_limit 設定為 -1,這表示自動清空成本限制使用與參數相同的 vacuum_cost_limit 值。 的 vacuum_cost_limit 預設值為 200。
vacuum_cost_limit 代表手動吸塵的成本。
如果您設定 autovacuum_vacuum_cost_limit 為 -1,則自動清空會使用參數 vacuum_cost_limit 。 如果您設定 autovacuum_vacuum_cost_limit 為大於 -1 的值,則自動清空會使用參數 autovacuum_vacuum_cost_limit 。
如果自動清真空跟不上,請考慮變更下列參數:
| 參數 | 描述 |
|---|---|
autovacuum_vacuum_cost_limit |
預設:200。 您可以增加成本限制。 在進行變更之前和之後監控資料庫上的 CPU 和 I/O 使用率。 |
autovacuum_vacuum_cost_delay |
PostgreSQL 12 版和更新版本 - 預設值: 2 ms。 您可以降低此值,以進行更積極的自動清空。 |
vacuum_buffer_usage_limit |
PostgreSQL 第 16 版和更新版本 - 設定 VACUUM 和自動清理作業的緩衝池大小。 調整此參數可控制在清理作業期間使用的共用緩衝區快取量,以協助平衡自動清理效能與整體系統效能。 |
附註
-
autovacuum_vacuum_cost_limit值會按比例在執行中的自動清理工作程序之間進行分配。 如果有多個工作者,各工作者的限制總和不會超過autovacuum_vacuum_cost_limit參數的值。 -
autovacuum_vacuum_scale_factor是另一個參數,可根據沒用的 Tuple 的累積情況來觸發對資料表執行 VACUUM。 預設:0.2、允許的範圍:0.05 - 0.1。 比例因素是工作負載特有的,應該根據資料表中的資料量來設定。 變更值之前,請先調查工作負載和個別資料表磁碟區。
自動資料清理作業持續執行
如果自動清空持續執行,可能會影響伺服器上的 CPU 和 I/O 使用率。 以下是一些可能的原因:
maintenance_work_mem
autovacuum 常駐程式會使用 autovacuum_work_mem,依預設會設定為 -1 。 此預設設定表示 autovacuum_work_mem 使用與參數相同的 maintenance_work_mem 值。 本文假設 autovacuum_work_mem 已設為 -1,且自動清理常駐程式會使用 maintenance_work_mem。
如果 maintenance_work_mem 為低,您可以在 Azure 資料庫 PostgreSQL 彈性伺服器實例上將其增加至 2 GB。 一般經驗法則是針對每 1 GB RAM 配置 50 MB 至 maintenance_work_mem。
大量資料庫
自動資料清理會每 autovacuum_naptime 秒嘗試在每個資料庫上啟動背景工作角色。
例如,如果伺服器有 60 個資料庫且 autovacuum_naptime 設定為 60 秒,則自動資料清理背景工作角色每秒會啟動 [autovacuum_naptime/資料庫數量]。
如果叢集中有更多資料庫,請增加 autovacuum_naptime。 同時,通過增加 autovacuum_cost_limit 和減少 autovacuum_cost_delay 參數使自動真空過程更具侵略性。 您也可以將 autovacuum_max_workers 從預設的 3 增加到 4 或 5。
記憶體不足錯誤
過於激進的 maintenance_work_mem 值有可能導致系統發生記憶體不足錯誤。 在變更 maintenance_work_mem 參數之前,請先瞭解伺服器上的可用 RAM。
自動資料清理造成太大干擾
如果自動清理耗用太多資源,請嘗試下列動作:
自動資料清理參數
評估參數 autovacuum_vacuum_cost_delay、 autovacuum_vacuum_cost_limit和 autovacuum_max_workers。 自動資料清理參數設定有誤可能會導致自動資料清理造成太大干擾的情況。
如果自動資料清理造成太大干擾,請考慮採取下列動作:
- 如果您將其設定為高於預設值 200,則增加
autovacuum_vacuum_cost_delay和減少autovacuum_vacuum_cost_limit。 - 如果您將 的數目設定為高於預設值 3,請減少 的
autovacuum_max_workers數目。
自動資料清理背景工作角色過多
增加自動資料清理背景工作角色的數量並不會提升資料清理的速度。 不要使用過多的自動清理工作程序。
增加自動清理工作程序的數目會導致更多的記憶體耗用量。 視 的 maintenance_work_mem值而定,可能會導致效能降低。
每個自動資料清理背景工作處理序只會獲得總 autovacuum_cost_limit 的 (1/autovacuum_max_workers),因此使用大量的背景工作角色會導致每個背景工作角色速度變慢。
如果您增加工人數量,請增加 autovacuum_vacuum_cost_limit 和/或減少 autovacuum_vacuum_cost_delay 以使真空過程更快。
不過,如果您在資料表層級上設定autovacuum_vacuum_cost_delay或autovacuum_vacuum_cost_limit參數,那麼在這些資料表上運行的工作者將不會被納入平衡演算法 [autovacuum_cost_limit/autovacuum_max_workers] 的考量。
自動資料清理交易識別碼 (TXID) 環繞保護
當資料庫執行交易識別碼環繞保護時,您會看到類似下列錯誤的錯誤訊息:
Database isn't accepting commands to avoid wraparound data loss in database 'xx'
Stop the postmaster and vacuum that database in single-user mode.
附註
此錯誤訊息為長期監督。 通常,您不需要切換到單一使用者模式。 相反地,您可以執行必要的 VACUUM 命令,並針對 VACUUM 執行微調以加速執行。 雖然您無法執行任何資料操作語言 (DML),但仍可執行 VACUUM。
當資料庫未被清理 (vacuum) 或自動清理程式 (autovacuum) 未移除過多沒用的 Tuple 時,就會發生「循環覆寫」的問題。
造成此問題的可能原因包括以下原因:
工作負載過重
繁重的工作負載會在短時間內產生過多沒用的 Tuple,使得自動清理程式難以跟上。 系統中的無效 Tuple 會隨著時間累積,導致查詢效能降低,並造成環繞情況。 這種情況的其中一個原因可能是因為自動資料清理參數未能適當設定,而且跟不上忙碌的伺服器。
長時間執行的交易
系統中任何長時間執行的交易都不會允許自動清理程式移除沒用的 Tuple。 這對資料清理流程來說是種阻礙。 移除長時間執行的交易會在執行自動資料清理時釋出無效 Tuple 以進行刪除。
您可以使用下列查詢來偵測長時間執行的交易:
SELECT pid, age(backend_xid) AS age_in_xids,
now () - xact_start AS xact_age,
now () - query_start AS query_age,
state,
query
FROM pg_stat_activity
WHERE state != 'idle'
ORDER BY 2 DESC
LIMIT 10;
備妥語句
如果存在未提交的已備妥陳述式,它們會阻止自動清理程式移除沒用的 Tuple。 下列查詢有助於尋找未認可的備妥語句:
SELECT gid, prepared, owner, database, transaction
FROM pg_prepared_xacts
ORDER BY age(transaction) DESC;
使用 COMMIT PREPARED 或 ROLLBACK PREPARED 來認可或復原這些陳述式。
未使用的複寫位置
未使用的複寫位置可防止自動資料清理宣告無效 Tuple。 下列查詢有助於辨識未使用的複寫位置:
SELECT slot_name, slot_type, database, xmin
FROM pg_replication_slots
ORDER BY age(xmin) DESC;
使用 pg_drop_replication_slot() 來刪除未使用的複寫位置。
當資料庫遇到交易識別碼環繞保護時,請檢查先前提及的任何阻礙,然後手動移除這些阻礙,讓自動資料清理作業能夠繼續並完成。 您也可以將 autovacuum_cost_delay 設為 0,並將 autovacuum_cost_limit 增加為大於 200 的值,以提升自動資料清理的速度。 不過,這些參數的變更不會套用至現有的自動資料清理背景工作角色。 請將資料庫重新開機,或是手動終止現有的背景工作角色,以套用參數變更。
資料表特定需求
您可以為個別資料表設定自動清空參數。 這些設定對於小型和大型表格尤其重要。 例如,對於僅包含 100 列的小型資料表,自動清空會在 70 列變更時觸發 VACUUM 作業 (如先前計算)。 如果您經常更新此表格,則每天可能會看到數百個自動清空作業。 這些作業會阻止自動清理程式維護其他變更百分比不那麼顯著的資料表。 或者,包含 10 億個資料列的資料表必須變更 2 億個資料列,以觸發自動資料清理作業。 適當設定自動資料清理參數可防止這類情況發生。
若要設定每個資料表的自動清空設定,請變更伺服器參數,如下列範例所示:
ALTER TABLE <table name> SET (autovacuum_analyze_scale_factor = xx);
ALTER TABLE <table name> SET (autovacuum_analyze_threshold = xx);
ALTER TABLE <table name> SET (autovacuum_vacuum_scale_factor = xx);
ALTER TABLE <table name> SET (autovacuum_vacuum_threshold = xx);
ALTER TABLE <table name> SET (autovacuum_vacuum_cost_delay = xx);
ALTER TABLE <table name> SET (autovacuum_vacuum_cost_limit = xx);
-- For PostgreSQL 16 and later:
ALTER TABLE <table name> SET (vacuum_buffer_usage_limit = 'xx MB');
僅限插入的工作負載
在 PostgreSQL 版本 13 和更早版本中,自動清理不會在僅限插入工作負載的資料表上執行,因為沒有死元組,也沒有需要回收的可用空間。 不過,因為有新的資料,所以會針對僅限插入的工作負載執行自動分析。 這種行為的缺點是:
- 資料表的可見度對應不會更新,因此查詢效能會隨著時間開始受到影響,特別是在僅索引掃描的情況下。
- 資料庫可能會遇到交易識別碼環繞保護。
- 未設定提示位元。
方案
PostgreSQL 13 版和更早版本
透過使用 pg_cron 延伸模組,您可以設定 cron 作業來排程對資料表進行週期性的資料清理分析 (vacuum analyze)。 cron 作業的頻率取決於工作負載。
如需指導,請參閱在 適用於 PostgreSQL 的 Azure 資料庫中使用 pg_cron 的特殊考量。
PostgreSQL 13 及更新版本
自動資料清理會在具有僅插入工作負載的資料表上執行。 兩個伺服器參數 autovacuum_vacuum_insert_threshold 和 autovacuum_vacuum_insert_scale_factor 有助於控制何時可以在僅插入資料表上觸發自動真空。
疑難排解指南
適用於 PostgreSQL 的 Azure 資料庫彈性伺服器會在入口網站中提供疑難排解指南,協助您監視資料庫或個別結構描述層級的膨脹,並識別自動清空程式的潛在封鎖因素。
有兩個疑難排解指南可用:
- 自動清空監控 — 使用本指南來監控資料庫或個別結構描述層級的膨脹。
- 自動清空封鎖程式和環繞 - 本指南可協助您識別潛在的自動清空封鎖程式,並提供伺服器上資料庫與環繞或緊急情況相差多遠的資訊。
疑難排解指南也會分享減輕潛在問題的建議。 如需如何設定和使用疑難排解指南的相關資訊,請參閱 設定疑難排解指南。
終止自動清理程序:pg_signal_autovacuum_worker 角色
自動清理是一個重要的背景過程,因為它有助於在資料庫中進行高效的儲存和效能維護。 在一般自動資料清理流程中,它會在 deadlock_timeout 之後自行取消。 如果使用者在資料表上執行 DDL 陳述式,使用者可能必須等到指定的間隔deadlock_timeout。 自動真空不允許對不同連線請求所要求的資料表執行讀取或寫入,這會增加交易中的延遲。
我們從 PostgreSQL 引進了一個新角色 pg_signal_autovacuum_worker,它允許非超級使用者成員終止正在進行的自動資料清理任務。 新角色可協助使用者安全且受控地存取自動清空程序。 非超級使用者在被授予pg_signal_autovacuum_worker角色後,可以使用pg_terminate_backend命令取消自動清理程序。 此角色 pg_signal_autovacuum_worker 可在 Azure 資料庫中的 PostgreSQL 15 版及更新版本中使用。
重複性自動資料清理工作程式的建議方法
在少見的情況下 (例如防「循環覆寫」的自動清理程式),工作程序可能在終止後立即重新啟動,因為它們對防止交易 ID 耗盡至關重要。 若要將重複衝突降到最低,請遵循下列步驟:
在終止之前,將 DDL 作業排入佇列中:
階段 1:準備並執行 DDL 陳述式。
階段作業 2:終止自動清理程序。
這很重要
這兩個步驟必須背對背執行。 如果 DDL 陳述式保持封鎖狀態太久,它可能保持鎖定並封鎖伺服器上的其他 DML 作業。
終止自動清理並執行 DDL:如果 DDL 必須立即執行:
- 使用 pg_terminate_backend() 終止自動清空程序。
- 終止後立即執行 DDL 陳述式。
避免重複衝突的步驟:
將角色指派給使用者
GRANT pg_signal_autovacuum_worker TO app_user;- 識別自動清理程序 ID
SELECT pid, query FROM pg_stat_activity WHERE query LIKE '%autovacuum%' and pid!=pg_backend_pid();終止自動資料清理
SELECT pg_terminate_backend(<pid>);立即執行 DDL 陳述式
ALTER TABLE my_table ADD COLUMN new_col TEXT;
附註
我們不建議終止進行中的自動清空程序,因為這樣做可能會導致資料表和資料庫膨脹,進而進一步導致效能下降。 不過,如果有業務關鍵需求,涉及與自動清理程序一致的 DDL 陳述式的排程執行,則非超級使用者可以使用 pg_signal_autovacuum_worker 角色,以可控且安全的方式終止自動清理程序。
Azure Advisor 建議
Azure Advisor 建議可主動識別伺服器是否存在高膨脹比率,或者伺服器是否接近交易「循環覆寫」的情況。 您也可以針對建議建立 Azure Advisor 警示。
建議如下:
高膨脹率:高膨脹率會以多種方式影響伺服器效能。 其中一個重要問題是 PostgreSQL 引擎最佳化工具可能難以選取最佳執行計畫,導致查詢效能降低。 因此,當伺服器上的膨脹百分比達到特定閾值時即會觸發建議,以避免發生這類效能問題。
交易環繞:這種情況是伺服器可能遇到的最嚴重的問題之一。 一旦您的伺服器處於此狀態,它可能會停止接受更多交易,導致伺服器變成唯讀。 因此,當伺服器超過十億筆交易閾值時,就會觸發建議。