如何查看PostgreSQL数据库内部的可用闲置空间(Slack)
PostgreSQL 13 查看内部闲置空间(Slack Space)的实用方法
方法1:使用官方pg_freespacemap扩展(精度最高)
该扩展可以直接读取PostgreSQL内核维护的空闲空间映射(FSM),对应VACUUM后标记的可复用闲置空间,精度到页级别,查询过程不会锁表、也不会额外占用磁盘资源。
- 首先安装扩展:
CREATE EXTENSION IF NOT EXISTS pg_freespacemap; - 查看单张表的可用空闲空间:
替换SELECT sum(available) AS table_free_bytes, pg_size_pretty(sum(available)) AS table_free_pretty FROM pg_freespace('your_table_name');your_table_name为实际表名,返回结果单位默认是字节,pg_size_pretty会自动转换为KB/MB/GB的易读格式。 - 查看全库所有表的空闲空间排序(倒序,优先展示空闲最多的表):
SELECT c.relname AS table_name, pg_size_pretty(sum(f.available)) AS total_free_space, round(100 * sum(f.available) / pg_total_relation_size(c.oid), 2) AS free_space_ratio FROM pg_class c JOIN pg_freespace(c.oid) f ON true WHERE c.relkind = 'r' AND c.relnamespace NOT IN ('pg_catalog', 'information_schema') GROUP BY c.oid, c.relname ORDER BY sum(f.available) DESC;
方法2:使用系统统计视图(无需安装扩展)
如果没有权限安装扩展,可以通过内置的pg_stat_user_tables视图估算空闲空间,精度稍低,误差范围在5%~15%之间,适合快速排查:
SELECT relname AS table_name, n_dead_tuples AS dead_tuple_count, pg_size_pretty(round(n_dead_tuples * (8192 / (reltuples / relpages::float)))::bigint) AS estimated_free_space, round(100 * (n_dead_tuples * (8192 / (reltuples / relpages::float))) / pg_total_relation_size(oid), 2) AS estimated_free_ratio FROM pg_stat_user_tables WHERE relpages > 0;
方法3:整库级别闲置空间总览
如果只需要看整个数据库的总闲置空间占比,使用以下查询即可:
SELECT pg_size_pretty(sum(pg_total_relation_size(oid)) - sum(pg_relation_size(oid))) AS total_slack_space, round(100 * (sum(pg_total_relation_size(oid)) - sum(pg_relation_size(oid))) / sum(pg_total_relation_size(oid)), 2) AS total_slack_ratio FROM pg_class WHERE relkind = 'r' AND relnamespace NOT IN ('pg_catalog', 'information_schema');
说明:
pg_total_relation_size是表含索引、闲置空间在内的总磁盘占用,pg_relation_size是表实际存储有效数据的大小,两者差值就是全库整体的闲置空间总量,包含FSM标记的可复用空间和还未被VACUUM清理的死元组占用空间。
日常监控建议
可以每天定时执行上述pg_freespacemap相关查询,记录空闲空间占比变化趋势,当占比低于5%时说明现有闲置空间即将耗尽,可提前规划数据清理或扩容方案。
内容的提问来源于stack exchange,提问作者Watusimoto
相关产品推荐
相关产品推荐

