如何在postgresql中准确获取数据库大小?

Dev*_*evy 5 postgresql database-administration

我们正在 PostgreSQL 版本 9.1 上运行,之前我们在一张表中有超过 10 亿行,并且已被删除。然而,看起来该\l+命令仍然不准确地报告实际数据库大小(它报告了 568GB,但实际上远小于)。

证明 568GB 错误的证据是,单个表大小统计并没有达到这个数字,如您所见,前 20 个关系的大小为 4292MB,其余 985 个关系的大小都远低于 10MB。事实上,所有这些加起来大约不到 6GB。

知道为什么 PostgreSQL 如此膨胀吗?如果确认的话,我该如何消肿?我不太熟悉VACUUM,这是我需要做的吗?如果是这样,怎么办?

非常感谢。

pmlex=# \l+
                                                                       List of databases
      Name       |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   |  Size   | Tablespace |                Description                 
-----------------+----------+----------+-------------+-------------+-----------------------+---------+------------+--------------------------------------------
 pmlex           | pmlex    | UTF8     | en_US.UTF-8 | en_US.UTF-8 |                       | 568 GB  | pg_default | 
 pmlex_analytics | pmlex    | UTF8     | en_US.UTF-8 | en_US.UTF-8 |                       | 433 MB  | pg_default | 
 postgres        | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |                       | 5945 kB | pg_default | default administrative connection database
 template0       | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +| 5841 kB | pg_default | unmodifiable empty database
                 |          |          |             |             | postgres=CTc/postgres |         |            | 
 template1       | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +| 5841 kB | pg_default | default template for new databases
                 |          |          |             |             | postgres=CTc/postgres |         |            | 
(5 rows)

pmlex=# SELECT nspname || '.' || relname AS "relation",
pmlex-#     pg_size_pretty(pg_relation_size(C.oid)) AS "size"
pmlex-#   FROM pg_class C
pmlex-#   LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
pmlex-#   WHERE nspname NOT IN ('pg_catalog', 'information_schema')
pmlex-#   ORDER BY pg_relation_size(C.oid) DESC;
              relation               |  size   
-------------------------------------+---------
 public.page_page                    | 1289 MB
 public.page_pageimagehistory        | 570 MB
 pg_toast.pg_toast_158103            | 273 MB
 public.celery_taskmeta_task_id_key  | 233 MB
 public.page_page_unique_hash_uniq   | 140 MB
 public.page_page_ad_text_id         | 136 MB
 public.page_page_kn_result_id       | 125 MB
 public.page_page_seo_term_id        | 124 MB
 public.page_page_kn_search_id       | 124 MB
 public.page_page_direct_network_tag | 124 MB
 public.page_page_traffic_source_id  | 123 MB
 public.page_page_active             | 123 MB
 public.page_page_is_referrer        | 123 MB
 public.page_page_category_id        | 123 MB
 public.page_page_host_id            | 123 MB
 public.page_page_serp_id            | 121 MB
 public.page_page_domain_id          | 120 MB
 public.celery_taskmeta_pkey         | 106 MB
 public.page_pagerenderhistory       | 102 MB
 public.page_page_campaign_id        | 89 MB
...
...
...
 pg_toast.pg_toast_4354379           | 0 bytes
(1005 rows)
Run Code Online (Sandbox Code Playgroud)

bma*_*bma 3

您的选择包括:

1)。确保自动清理已启用并积极设置。

2)。正如我在之前的评论中提到的那样重新创建表(create-table-as-select + truncate + 重新加载原始表)。

3)。如果您可以承受被锁定在该表之外的情况(独占锁),则在该表上运行 CLUSTER。

4). VACUUM FULL,尽管 CLUSTER 更高效并且推荐使用。

5)。运行几次普通的 VACUUM ANALYZE 并保持表不变,最终在新数据进入时填充空间。

6). 通过 pg_dump 转储并重新加载表

7). pg_repack(虽然我没有在生产中使用它)