database - 在 PostgreSQL 中释放项目标识符后,空间将如何被重用?
问题描述
最近我开始对 PostgreSQL 空闲空间管理和碎片整理做一些研究。我知道堆上的每个页面都包含一个页眉、页面标识符、可用空间和项目。当插入一个新的元组时,一个新的项目标识符将被插入到空闲空间的开头,新的项目数据将被插入到空闲空间的末尾。
使用后Vacuum
,dead tuples 的 item 标识和 item 数据将被移除。如果删除的项目标识符在其他标识符的中间,则标识符之间会有间隙。由于通常新的标识符将被添加到空闲空间的开头,这之间的空闲空间会再次被重用吗?如果是这样,我们怎样才能找到这个空间?
这是此场景的可视化示例:
删除一些元组后,(0,3) 和 (0,5) 之间有未使用的空间。这个空间将如何再次被重用?谢谢!
解决方案
假设该表包含 2 页。我们看一下第一页(第 0 页)让我们假设插入了一些数据并且该页有三个元组(行)。现在如果假设我们删除了元组 2,那么 PG 会删除元组 2 并将剩余的元组重新排序以进行碎片整理,然后更新此页面的 FSM 和 VM。PostgreSQL 继续执行此过程直到最后一页(真空)。
当您进行真空吸尘时,不会删除不必要的行指针,它们将在将来被重用。
因为,如果删除行指针,则必须更新关联索引的所有索引元组。
推荐阅读
- ios - 在重用之前,UITableViewHeaderFooterView 的 VoiceOver 无法正常工作
- java - 是否可以在 Android Studio 中使用 Firebase 数据库添加子项同时保留旧项?
- time-complexity - 伪代码的时间复杂度
- javascript - 如何防止 setInterval 同时被多次调用?
- bluetooth - 在与 BlueZ 的蓝牙连接期间微调超时?
- r - 如何将逗号分隔的字符串剥离为唯一的子字符串
- python - CodeCoverage 未显示在 Python 项目的 SonarCloud 中
- firebase - Flutter main.dart中的LateInitialization错误
- java - 无法将嵌入式 Derby 驱动程序注册到 WildFly 25
- python - 有没有办法在 Node.js 或 ReactJS 中导入和运行 Python 包?