PostgreSQL中的可见性映射表什么时候使用?由谁来使用?

PostgreSQL 中可见性映射表(Visibility Map,简称 VM) 的使用时机和使用者。

可见性映射表(VM)是什么?

VM 是一个为每个堆表(主数据文件)分配的附属位图文件,它为数据文件中的每个页面(通常为 8KB) 跟踪两个关键的状态位:

  1. 全部可见位:如果某个页面的这个位被设置(=1),表示该页面中所有的元组对所有活动事务都是可见的。这意味着这个页面里没有需要被 VACUUM 清理的过期元组(死元组)。
  2. 全部冻结位:如果某个页面的这个位被设置(=1),表示该页面中所有的元组都已经被“冻结”。冻结的元组对于任何未来的事务都被视为已提交,这主要用于防止事务 ID 回卷(wraparound)这一严重问题。

什么时候使用?

VM 主要在以下三个关键场景中被使用:

  1. 加速 VACUUM 操作(最重要的作用)

    • VACUUM(常规或 autovacuum)运行时,它会扫描 VM。
    • 对于被标记为 “全部可见” 的页面,VACUUM直接跳过。因为它知道这些页面里没有死元组,无需进行耗时的扫描和清理。这极大地减少了 VACUUM 的 I/O 开销和处理时间,尤其是对于大部分数据都很静态的表。
    • 对于需要防止事务 ID 回卷的 VACUUM 操作,它会寻找那些尚未被标记为 “全部冻结” 的页面,并将其中的元组冻结,然后在 VM 中设置“全部冻结”位。
  2. 支持仅索引扫描

    • 当一个查询可以完全通过索引来满足时(即仅索引扫描),优化器会考虑使用 VM。
    • 如果索引指向的堆表页面在 VM 中被标记为 “全部可见”,那么数据库引擎就可以确信该索引元组对应的堆元组是有效的、可见的,而无需再访问堆表页面去检查元组的可见性(即检查 xmin/xmax)。
    • 这避免了额外的堆页面访问,可以显著提升纯索引查询的速度。
  3. 指导防止事务 ID 回卷的清理

    • PostgreSQL 使用事务 ID(XID)来实现多版本并发控制(MVCC)。XID 是一个 32 位的计数器,存在回卷风险。为了防止这个问题,必须定期将旧的元组“冻结”。
    • VACUUM 在执行防回卷任务时,会优先处理那些离回卷点最近、且没有被 VM 标记为“全部冻结” 的页面。VM 使得 VACUUM 能够高效地定位需要处理的目标,而不是盲目地扫描整个表。

由谁来使用(更新和读取)?

VM 的生命周期由 PostgreSQL 的核心进程和操作管理:

  • 设置者/更新者

    • VACUUM:这是最主要的设置和更新者。
      • 当一个页面被 VACUUM 扫描并确认其中没有死元组时,它会设置该页面的“全部可见”位。
      • 当一个页面中的所有元组都被冻结后,它会设置该页面的“全部冻结”位。
    • 数据修改操作:当页面发生变更时,VM 位会被清除。
      • 当执行 INSERTUPDATEDELETE 操作,修改了某个堆页面时,该页面在 VM 中的 “全部可见”位会被清除(设置为 0)。因为新的操作可能在这个页面上创建了不可见的元组(例如,一个新插入的元组可能对某些事务还不可见),或者产生了死元组,破坏了其“全部可见”的状态。
      • 注意UPDATEDELETE 操作通常不会直接设置 VM 位,它们只是通过清除位来“污染”页面状态,真正的设置工作留给后续的 VACUUM 来完成。
  • 读取者/使用者

    • VACUUM 进程:如上所述,它读取 VM 来决定哪些页面可以跳过,哪些需要清理或冻结。
    • 查询执行器:在执行查询计划时,特别是当优化器选择仅索引扫描路径时,查询执行器会读取 VM 来快速判断索引元组的可见性,从而决定是否避免访问堆页面。
    • SQL 命令 pg_visibility:这是一个管理工具,允许数据库管理员直接查询和分析特定表的 VM 状态,用于诊断和维护。

总结

方面描述
核心作用标记没有死元组元组已冻结的页面,作为元数据缓存。
主要使用时机1. VACUUM 运行时(跳过清理、指导冻结)。
2. 执行仅索引扫描查询时。
3. 进行防事务ID回卷清理时。
主要使用者1. 设置者VACUUM 操作。
2. 清除者INSERT/UPDATE/DELETE 等数据修改操作。
3. 读取者VACUUM 进程、查询执行器(仅索引扫描)。

简而言之,VM 是 VACUUM 和查询优化器的“助手”。它通过记录页面的清洁状态,让 VACUUM 工作得更智能、更快速,同时也让某些特定类型的查询跑得更快。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值