PostgreSQL空闲空间地图详解

 更新时间:2026年08月30日 09:49:20   作者:BinBin-HF  
本文详细解释FreeSpaceMap(FSM)的作用、存储位置和工作原理,你将学会如何通过pg_freespacemap扩展查看每个数据页的空闲空间,理解INSERT、UPDATE和DELETE操作与FSM的关系,以及VACUUM如何更新空闲空间信息,帮你优化数据库性能

Free Space Map(FSM)是 PostgreSQL 用来记录每个数据页"还剩多少可用空间"的辅助结构。它让 INSERT / UPDATE 能快速找到可复用的页面,避免盲目扩展表文件。

Free Space Map 使用树形结构为每个 Heap Page 记录一个字节的近似空闲空间等级,让 INSERT / UPDATE 能快速定位可复用页面,避免逐页扫描或不必要地扩展表文件。查看 FSM 内容应优先使用 pg_freespacemap 扩展。

1. FSM 保存在哪里?

每个 heap relation 的存储由多个 fork 组成。假设表的 relfilenode 是 16384

16384

主数据文件(main fork)

16384_fsm

空闲空间地图(FSM fork)

16384_vm

可见性地图(VM fork)

查看各 fork 大小:

SELECT
    pg_size_pretty(pg_relation_size('public.test', 'main')) AS main_size,
    pg_size_pretty(pg_relation_size('public.test', 'fsm'))  AS fsm_size,
    pg_size_pretty(pg_relation_size('public.test', 'vm'))   AS vm_size;

FSM 不是整个数据库共享一个文件,而是每个有需要的 relation 都有自己的 FSM fork。表、TOAST 表和部分索引访问方法都可能使用各自的 FSM。

2. FSM 记录的是什么?

对于 Heap 表,FSM 主要记录每个 Heap Page 大约还有多少可用空间。例如:

Heap Page

剩余空间

Page 0

200 bytes

Page 1

3000 bytes

Page 2

7000 bytes

Page 3

1000 bytes

如果 PostgreSQL 需要插入一个约 2 KB 的 tuple,就可以通过 FSM 快速定位到 Page 1 或 Page 2,而不需要依次读取并检查所有 Heap Page。

3. FSM 为什么能快速查找页面?

FSM 不是简单地把所有 Heap Page 顺序列出来,而是使用树形结构。可以简化理解成:

                    7000
                  /      \
              3000        7000
             /    \      /    \
Page 0:200  P1:3000  P2:7000  P3:1000

每个父节点保存子节点中的最大空闲空间。查找至少有 2 KB 空间的页面时:

  • 从根节点开始
  • 选择最大空闲空间不小于 2 KB 的分支
  • 一直向下查找,最终定位到具体 Heap Page
  • 读取 Heap Page,再验证真实空间

如果找不到足够空间,PostgreSQL 通常会扩展表文件,创建新的 Heap Page。

4. INSERT 如何使用 FSM?

执行一条简单的插入:

INSERT INTO test VALUES (1, 'abc');

大致过程如下:

    A[计算新 tuple 所需空间] --> B[查询 FSM]
    B --> C[找到可能有足够空间的 Heap Page]
    C --> D[读取并锁定该 Heap Page]
    D --> E{检查真实空闲空间}
    E -->|空间足够| F[插入 tuple]
    E -->|空间不足| G[更新 FSM,继续寻找]
    G --> B
    E -->|没有合适页面| H[扩展表文件]

5. DELETE 后空间会立即出现在 FSM 中吗?

通常不会立即完全变成可复用空间。

DELETE FROM test WHERE id = 1;

被删除的 tuple 先成为 dead tuple,但它占用的空间暂时不能直接重用——其他持有旧快照的事务可能仍然需要看到它。

    A[DELETE] --> B[旧 tuple 变成可能死亡的版本]
    B --> C[等待不再被任何事务需要]
    C --> D[页面剪枝或 VACUUM 清理]
    D --> E[空间变为可复用]
    E --> F[FSM 更新]

因此:

DELETE FROM test;

不会立刻缩小表文件,也不一定立刻让 FSM 显示出全部空闲空间。执行 VACUUM 可以清理 dead tuple 并更新 FSM:

VACUUM test;

普通 VACUUM 通常只是让空间可供 PostgreSQL 内部复用,不会把整个表文件空间返还给操作系统。

6. UPDATE 和 FSM 的关系

PostgreSQL 的 UPDATE 实际上会创建一个新的 tuple 版本。

优先情况:新版本能放在原来的 Heap Page 中,如果满足索引等条件,还可能形成 HOT Update(Heap-Only Tuple Update)。- 这是什么意思?待更新

非优先情况:如果原页面空间不够,PostgreSQL 通过 FSM 查找其他页面:

    A[原页面空间不足] --> B[通过 FSM 查找其他页面]
    B --> C[将新 tuple 版本写入其他页面]
    C --> D[无法形成 HOT Update]
    D --> E[索引可能需要加入新的索引项]

7. 如何查看 FSM 内容?

最方便的是使用 pg_freespacemap 扩展。

安装扩展

CREATE EXTENSION pg_freespacemap;

查看所有页面的近似可用空间

SELECT * FROM pg_freespace('public.test');
select *, round(100 * avail/8192, 2) as "freespace ratio" from pg_freespace('test1');

结果类似:

blkno

avail

0

1024

1

4096

2

8160

其中 blkno 是 Heap Page 编号,avail 是 FSM 认为该页面大约有多少字节可用。

查看指定 Heap Page

SELECT pg_freespace('public.test', 0);

到此这篇关于PostrgeSQL空闲空间地图的文章就介绍到这了,更多相关PostrgeSQL空闲空间地图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • PostgreSQL基础知识之SQL操作符实践指南

    PostgreSQL基础知识之SQL操作符实践指南

    这篇文章主要给大家介绍了关于PostgreSQL基础知识之SQL操作符实践的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用PostgreSQL具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2020-05-05
  • PostgreSQL向量检索之pgvector入门实战指南

    PostgreSQL向量检索之pgvector入门实战指南

    pgvector是PostgreSQL的开源扩展,用于在数据库中存储和处理向量数据,特别是高维嵌入向量(embedding),本文介绍PostgreSQL向量检索:pgvector入门指南,感兴趣的朋友一起看看吧
    2026-01-01
  • PostgreSQL数据库事务出现未知状态的处理方法

    PostgreSQL数据库事务出现未知状态的处理方法

    这篇文章主要给大家介绍了PostgreSQL数据库事务出现未知状态的处理方法,需要的朋友可以参考下
    2017-07-07
  • PostgreSQL中常用的时间日期脚本使用教程

    PostgreSQL中常用的时间日期脚本使用教程

    PostgreSQL是一款简介而又性能强大的数据库应用程序,其在日期时间数据方面所支持的功能也都非常给力,下面就来看一下PostgreSQL中常用的日期时间脚本使用教程.
    2016-05-05
  • 解决sqoop从postgresql拉数据,报错TCP/IP连接的问题

    解决sqoop从postgresql拉数据,报错TCP/IP连接的问题

    这篇文章主要介绍了解决sqoop从postgresql拉数据,报错TCP/IP连接的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • postgresql IvorySQL新增命令及相关配置参数详解

    postgresql IvorySQL新增命令及相关配置参数详解

    这篇文章主要为大家介绍了postgresql IvorySQL新增命令及相关配置参数详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • postgresql 中的 like 查询优化方案

    postgresql 中的 like 查询优化方案

    这篇文章主要介绍了postgresql 中的 like 查询优化方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • Postgresql 解决pg掉电后无法重启的问题

    Postgresql 解决pg掉电后无法重启的问题

    这篇文章主要介绍了Postgresql 解决pg掉电后无法重启的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • PostgreSQL高可用集群部署与配置指南

    PostgreSQL高可用集群部署与配置指南

    本文主要介绍了PostgreSQL高可用集群部署与配置指南,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2026-02-02
  • 从PostgreSQL15升级到16全过程

    从PostgreSQL15升级到16全过程

    这篇文章主要介绍了从PostgreSQL15升级到16全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2026-06-06

最新评论