删除索引似乎不会向操作系统释放空间。它可以?

Dan*_*ons 4 postgresql vacuum

我正在运行 PostgreSQL 9.1。我注意到非常糟糕的索引占用了我服务器上的大量空间,例如:

evlampts=# SELECT 
  pg_size_pretty(pg_relation_size('mcdata_2011_07')) AS relation_size, 
  pg_size_pretty(pg_total_relation_size('mcdata_2011_07')) AS total_relation_size, 
  pg_size_pretty(pg_indexes_size('mcdata_2011_07')) AS indexes_size;

 relation_size | total_relation_size | indexes_size
---------------+---------------------+--------------
 43 GB         | 100 GB              | 57 GB
(1 row)
Run Code Online (Sandbox Code Playgroud)

然后我可以看到,虽然其中很大一部分是主键,但我在一个索引中有 11 GB,在另一个索引中有 16 GB:

evlampts=# SELECT
  pg_size_pretty(pg_relation_size('mcdata_2011_07_timestamp_idx')) AS timestamp_idx_size, 
  pg_size_pretty(pg_relation_size('mcdata_2011_07_host_idx')) AS host_idx_size;

 timestamp_idx_size | host_idx_size
--------------------+---------------
 11 GB              | 16 GB
(1 row)
Run Code Online (Sandbox Code Playgroud)

如果我继续删除这些索引,我看不到操作系统中磁盘空间的显着改善:

$ df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/md0              1.8T  1.8T   32G  99% /export/home/lando

$ psql evlampts
evlampts=# drop index mcdata_2011_07_host_idx;
DROP INDEX
evlampts=# \q

$ df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/md0              1.8T  1.8T   32G  99% /export/home/lando
Run Code Online (Sandbox Code Playgroud)

如果空间被释放给操作系统,我希望还有 16 GB 可用。有没有VACUUM我遗漏的步骤?我已将 autovacuum 调整为不那么频繁地运行并且可能已经走得太远了,但是我在文档中没有看到任何内容说 aVACUUM是释放索引空间所必需的。我没有做什么我应该做什么?

kgr*_*ttn 7

删除索引后应立即释放空间。您上面显示的内容的可能解释是:

  1. 该索引位于与您正在检查的文件系统不同的文件系统上的表空间中。
  2. 操作系统/文件系统在提供最新的可用空间信息方面存在一些滞后。
  3. 一旦空闲空间可用,其他东西就会吃掉它。
  4. 有东西持有打开的索引文件;lsof 在这里可能有用。

如果您运行此查询,您可以看到有关索引的一些信息,包括文件系统编号和用于构成索引的文件名的编号。

select oid::regclass, reltuples, relpages, reltablespace, relfilenode
  from pg_class
  where oid = 'mcdata_2011_07_host_idx'::regclass;
Run Code Online (Sandbox Code Playgroud)

根据relfilenode删除索引前后的文件名查找文件。