Postgresql

臨時文件和 work_mem

  • November 16, 2021

我的 Postgres 實例正在記錄如下內容:

2021-11-16 22:18:52.491 UTC [1808765]: [3-1] db=xxx,user=xxx LOG: temporary file: path "base/pgsql_tmp/pgsql_tmp1808765.0", size 262144

我的理解是,如果work_mem太低,Postgres 可以使用臨時文件進行排序。但是如果我執行show work_mem;,我會看到目前值為 86000kB,這比我在日誌中看到的臨時文件的大小要大得多。還有什麼我應該在這裡看的嗎?

請務必了解該work_mem設置的實際作用。手冊:

work_mem( integer)

在寫入臨時磁碟文件之前,設置查詢操作(例如排序或雜湊表)使用的基本最大記憶體量。如果此值指定為不帶單位,則以千字節為單位。預設值為四兆字節 ( 4MB)。請注意,對於復雜的查詢,可能會並行執行多個排序或散列操作;在開始將數據寫入臨時文件之前,通常允許每個操作使用此值指定的記憶體量。此外,幾個正在執行的會話可以同時執行此類操作。因此,使用的總記憶體可能是值的許多倍work_mem;在選擇值時必須牢記這一事實。排序操作用於ORDER BY,DISTINCT, 並合併連接。雜湊表用於雜湊連接、基於雜湊的聚合、結果記憶體節點和基於雜湊的 IN 子查詢處理。

基於雜湊的操作通常比等效的基於排序的操作對記憶體可用性更敏感。可用於雜湊表的記憶體是通過乘以 來計算work_memhash_mem_multiplier。這使得基於散列的操作可以使用超過通常 work_mem基本數量的記憶體量。

hash_mem_multiplier在 Postgres 13 中添加。

如果 Postgres 需要的記憶體超出work_mem任何給定操作所允許的範圍,它就會開始溢出到磁碟。所以你觀察到的是多餘的:

我看到目前值為 86000kB,比我在日誌中看到的臨時文件的大小要大得多。

將您的work_mem設置(至少)增加觀察到的臨時文件的大小,它應該會消失。

但是,也不要設置work_mem得太高,因為這可能會耗盡記憶體和並發事務。work_mem對於異常大的操作,人們總是可以在本地設置一個更高的值。看:

引用自:https://dba.stackexchange.com/questions/302734