科技 · 實用指南
PostgreSQL 顯示「could not resize shared memory segment」?先證明哪個檔案系統耗盡
ENOSPC 不代表資料庫磁碟已滿。先保留完整分配錯誤,從 PostgreSQL 所在命名空間檢查掛載,把峰值連到失敗工作負載,再只改一個已證實的邊界並重跑同一操作。

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 錯誤且記憶體壓力在預算內才驗收;否則回滾並重算。
