# 策展 · X (Twitter) 🔥

> 📖 本站完整內容索引（documentation index）：[llms.txt](/llms.txt)

> 作者：PlanetScale (@PlanetScale) · 平台：X (Twitter) · 日期：2026-04-10

> 原始來源：https://x.com/planetscale/status/2042655644784955416

## 中文摘要

如何保持 Postgres 佇列的健康與效能。

Postgres 雖非專為佇列設計，但常被用於處理混合工作負載。本文探討如何透過管理 MVCC 與清理機制，解決佇列效能退化問題，並強調在混合環境下維持系統健康的重要性。

**Postgres 佇列的運作機制**
許多開發者選擇將 Postgres 作為佇列使用，主要優勢在於能將工作狀態與應用程式邏輯保持在同一交易中，確保資料一致性。
- 透過 `FOR UPDATE SKIP LOCKED` 語法，開發者可以實現併發處理，確保多個工作者 (Worker) 不會重複執行相同的任務。
- 這種模式的核心在於：工作者呼叫交易、取得任務、執行工作，成功後刪除該列並提交交易；若失敗則回滾，任務將重新變為可見。

**效能殺手：死元組 (Dead Tuples) 與清理機制**
Postgres 的多版本併發控制 (MVCC) 設計意味著 `DELETE` 操作不會立即移除資料，而是將其標記為「死元組」。這些死元組會導致嚴重的效能隱患：
- 堆疊掃描 (Heap scan)：執行器必須讀取死元組並檢查其可見性，這會增加不必要的 I/O。
- 索引掃描 (Index scan)：B-tree 索引會累積指向死元組的參考，導致掃描時遍歷無效指標，造成額外開銷。
- 若資料庫無法在死元組累積的速度下完成清理 (Vacuum)，效能將顯著下降，甚至拖垮整個資料庫。

**混合工作負載帶來的清理瓶頸**
在混合工作負載環境中，佇列效能往往受限於其他並行運行的查詢。自動清理 (Autovacuum) 無法移除仍對活躍交易可見的死元組，這導致了常見的失敗模式：
- 長時間運行的交易會鎖定 MVCC 水平線 (Horizon)，導致清理機制無法運作。
- 即使是多個短暫但重疊的分析查詢，也可能持續鎖定該水平線，導致清理停滯。
- 問題的根源不在於 Postgres 不適合做佇列，而在於當佇列與其他高資源消耗的查詢共存時，缺乏有效的資源隔離與流量控制。

**優化策略與流量控制**
傳統的逾時設定（如 `statement_timeout` 或 `transaction_timeout`）屬於較粗糙的手段，無法解決併發資源爭用的問題。針對此類場景，PlanetScale 提出了「Database Traffic Control™」：
- 該工具允許針對不同流量類別進行細粒度控制，為特定查詢設定資源預算。
- 當查詢超過資源限制時，系統可將其阻擋，從而確保高優先級任務不受影響，並讓自動清理機制有機會運作。
- 關鍵提醒：採用此類控制手段時，應用程式必須具備完善的重試邏輯，以應對被阻擋的查詢，確保系統在平滑處理負載的同時，維持整體穩定性。

## 標籤

教學資源, 其他, PostgreSQL
