Watch at Ease看見世界,讀懂生活。

科技 · 實用指南

PostgreSQL 顯示「could not resize shared memory segment」?先證明哪個檔案系統耗盡

ENOSPC 不代表資料庫磁碟已滿。先保留完整分配錯誤,從 PostgreSQL 所在命名空間檢查掛載,把峰值連到失敗工作負載,再只改一個已證實的邊界並重跑同一操作。

Watch at Ease 原創插畫:主機磁碟有空間但容器 /dev/shm 接近耗盡。
Watch at Ease 原創插畫:先找出真正回傳 ENOSPC 的命名空間。 Watch at Ease

ENOSPC 不代表資料庫磁碟已滿。先保留完整分配錯誤,從 PostgreSQL 所在命名空間檢查掛載,把峰值連到失敗工作負載,再只改一個已證實的邊界並重跑同一操作。

PostgreSQL 的平行操作可使用動態共享記憶體。Linux 的 POSIX 共享記憶體通常由掛載於 /dev/shm 的 tmpfs 承載;容器即使主機與資料卷空間充足,也可能只有很小的私有掛載。

1. 固定分配錯誤與執行身分

保存完整 PostgreSQL 錯誤、要求擴展的大小、SQL 或維護操作、backend PID、時間、資料庫與 request ID,並記錄承載進程的容器 ID、pod UID 或 service task。

不要先以主機資料卷圖表下結論。ENOSPC 只證明分配碰到邊界;路徑或 DSM 實作及進程命名空間才指出要查的資源。

2. 從 PostgreSQL 的命名空間檢查掛載

在同一容器或 pod 執行 df -h /dev/shm、df -i /dev/shm 與 findmnt -T /dev/shm,保存容量、使用量、inode、檔案系統與掛載參數。

在 PostgreSQL 記錄 SHOW dynamic_shared_memory_type 與平行設定。Linux 的 posix DSM 指向 /dev/shm;其他 DSM 類型應依其文件追蹤承載位置。

3. 把峰值連到失敗工作負載

必要時以不執行的 EXPLAIN 查看平行 worker,記錄 max_parallel_workers_per_gather、同查詢併發數與重疊維護,並在受控重現前後量測 /dev/shm。

shared_buffers 或 work_mem 不是通用答案。應比較請求增量與同時 DSM 使用量,對照作用中掛載的實際餘量。

4. 只改一個已證明的邊界

Docker 要為服務設定明確 shm 大小並重建容器;只改設定不替換容器,不會改變現有掛載。Kubernetes 的 memory-backed emptyDir 也必須納入 pod 記憶體預算。

若無法安全增容,就限制已證明的平行度或併發峰值。伺服器運行中不要任意刪除 /dev/shm 內看似屬於 PostgreSQL 的檔案。

5. 用相同負載設退出門檻

重啟或發布後重新進入實際 runtime,保存新的 findmnt 與 df 證據;用同一 SQL、相同平行度與代表性併發重跑,同時監測峰值。

只有原操作完成、掛載保有可量測餘量、沒有新 DSM 錯誤且記憶體壓力在預算內才驗收;否則回滾並重算。

Watch at Ease 原創插畫:量測共享記憶體、修復並成功重測。
Watch at Ease 原創插畫:只改一項並重跑同一工作負載。 Watch at Ease