Postgresql

發出 truncate 命令後,表的外部大小仍未釋放(作為磁碟空間)

  • March 16, 2017

在 PostgreSQL 9.3.10 (Ubuntu 14.04 OS) 中,我有一個名為的表groupseen,其大小如下:

             Table               |  Size   | External Size 
----------------------------------+---------+---------------
         links_groupseen         | 394 MB  | 362 MB

我知道這External Size是該表的相關對象(如索引)所採用的大小。

發出命令後truncate links_groupseen;,只394 MB釋放了磁碟空間(我在之後檢查過,通過df -h)。我的兩個問題是:

  1. External Size我能做些什麼來擺脫這個表的索引( )佔用的空間呢?不應該truncate照顧一切嗎?
  2. 我正在使用以下命令來檢查該表的大小。即使External Size尚未發布,現在使用此命令也不會顯示未完成的362 MB. 如何監控External Size與該表相關的未完成項?
SELECT
  relname as "Table",
  pg_size_pretty(pg_total_relation_size(relid)) As "Size",
  pg_size_pretty(pg_total_relation_size(relid) - pg_relation_size(relid)) as "External Size"
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC;

如果需要,表格如下所示:

                           Table "public.links_groupseen"
    Column     |           Type           |                          Modifiers                           
----------------+--------------------------+--------------------------------------------------------------
id             | integer                  | not null default nextval('links_groupseen_id_seq'::regclass)
seen_user_id   | integer                  | not null
seen_at        | timestamp with time zone | not null
which_reply_id | integer                  | not null
Indexes:
   "links_groupseen_pkey" PRIMARY KEY, btree (id)
   "links_groupseen_seen_user_id" btree (seen_user_id)
   "links_groupseen_which_reply_id" btree (which_reply_id)
Foreign-key constraints:
   "links_groupseen_seen_user_id_fkey" FOREIGN KEY (seen_user_id) REFERENCES auth_user(id) DEFERRABLE INITIALLY DEFERRED
   "links_groupseen_which_reply_id_fkey" FOREIGN KEY (which_reply_id) REFERENCES links_reply(id) DEFERRABLE INITIALLY DEFERRED

注意:這個 SO 答案並不能解決我的問題,因為問題中的 OP 說明了根本沒有為他釋放磁碟空間。就我而言,微妙之處在於只有External Size出色。

我認為即使沒有VACUUM FULL空間也可以通過截斷將空間釋放回作業系統。我的猜測是根據另一個問題,您有一個保持底層文件打開的後端程序。

  1. 找出文件是什麼。SELECT pg_relation_filepath('links_groupseen');
  2. 找到數據目錄SHOW data_directory;
  3. 執行截斷。
  4. 看看是什麼讓它打開了。lsof $data_directory/$relation_filepath

我認為最有可能的賭注是保持它打開,如果沒有,我們必須知道 Pg 是否relation_filepath在 truncate 命令之前和之後刪除底層,以及是否有任何東西打開了該文件(如果它存在)。您可能也必須lsof在截斷之前執行。

394 MB 是總大小,包括索引和 toast 表等外部項目。如果 394 MB 是您看到的被釋放的,那麼這就是全部。

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