在 PostgreSQL 中释放项标识符后,space 将如何重用?
How will the space be reused after the item identifier is freed in PostgreSQL?
最近开始研究PostgreSQL的免费space管理和碎片整理。我知道堆上的每个页面都包含一个页眉、页面标识符、空闲 space 和项目。当插入一个新的元组时,一个新的项目标识符将被插入到 free space 的开头,新的项目数据将被插入到 free space.
的末尾
使用Vacuum
后,死元组的项标识符和项数据将被删除。如果删除的项目标识符位于其他标识符的中间,则标识符之间会有间隙。由于通常新的标识符会添加到 free space 的开头,因此中间释放的 space 会再次被重用吗?如果是这样,我们如何找到这个 space?
这是此场景的可视化示例:
删除一些元组后,(0,3) 和 (0,5) 之间有未使用的 space。这个 space 将如何再次被重用?
谢谢!
假设 table 包含 2 页。我们看一下第一页(第 0 页)让我们假设插入了一些数据并且页面有三个元组(行)。现在假设我们删除元组 2,那么 PG 会删除元组编号 2 并将剩余的元组重新排序为 de-fragmentation,然后更新此页面的 FSM 和 VM。 PostgreSQL 继续执行此过程直到最后一页(真空)。
当您执行 vacuum 操作时,不需要的 行指针不会被删除,它们将在未来重新使用。
因为,如果删除行指针,则必须更新关联索引的所有索引元组。
您所说的“项目标识符”的 PostgreSQL 技术术语是“行指针”。 “项目指针”或“元组标识符”是页码和行指针的组合(图像中的 (0,5)
)。
这种间接方式乍一看很别扭,但好处是实际的元组数据可以re-shuffled随时对空闲的space进行碎片整理而不用改变元组的地址
行指针在页眉后形成一个数组。当应将新元组添加到缓冲区时,可以使用任何空闲行指针。如果没有空闲的行指针,则在数组末尾添加一个新的行指针。有关参考,请参阅 src/backend/storage/page/bufpage.c
中的 PageAddItemExtended
。
行指针数组永远不会被压缩,除非页面被截断,然后 re-added。未使用的数组槽将在添加新元组时重复使用。如果页面曾经充满了大量的小元组,然后删除并用少量大元组重新填充,将会有额外未使用的 lp 占用少量 space,永远不会被重用。
您可以使用 pageinspect 中的 heap_page_items 和 where lp_off=0
来查找它们。
最近开始研究PostgreSQL的免费space管理和碎片整理。我知道堆上的每个页面都包含一个页眉、页面标识符、空闲 space 和项目。当插入一个新的元组时,一个新的项目标识符将被插入到 free space 的开头,新的项目数据将被插入到 free space.
的末尾使用Vacuum
后,死元组的项标识符和项数据将被删除。如果删除的项目标识符位于其他标识符的中间,则标识符之间会有间隙。由于通常新的标识符会添加到 free space 的开头,因此中间释放的 space 会再次被重用吗?如果是这样,我们如何找到这个 space?
这是此场景的可视化示例:
删除一些元组后,(0,3) 和 (0,5) 之间有未使用的 space。这个 space 将如何再次被重用? 谢谢!
假设 table 包含 2 页。我们看一下第一页(第 0 页)让我们假设插入了一些数据并且页面有三个元组(行)。现在假设我们删除元组 2,那么 PG 会删除元组编号 2 并将剩余的元组重新排序为 de-fragmentation,然后更新此页面的 FSM 和 VM。 PostgreSQL 继续执行此过程直到最后一页(真空)。
当您执行 vacuum 操作时,不需要的 行指针不会被删除,它们将在未来重新使用。
因为,如果删除行指针,则必须更新关联索引的所有索引元组。
您所说的“项目标识符”的 PostgreSQL 技术术语是“行指针”。 “项目指针”或“元组标识符”是页码和行指针的组合(图像中的 (0,5)
)。
这种间接方式乍一看很别扭,但好处是实际的元组数据可以re-shuffled随时对空闲的space进行碎片整理而不用改变元组的地址
行指针在页眉后形成一个数组。当应将新元组添加到缓冲区时,可以使用任何空闲行指针。如果没有空闲的行指针,则在数组末尾添加一个新的行指针。有关参考,请参阅 src/backend/storage/page/bufpage.c
中的 PageAddItemExtended
。
行指针数组永远不会被压缩,除非页面被截断,然后 re-added。未使用的数组槽将在添加新元组时重复使用。如果页面曾经充满了大量的小元组,然后删除并用少量大元组重新填充,将会有额外未使用的 lp 占用少量 space,永远不会被重用。
您可以使用 pageinspect 中的 heap_page_items 和 where lp_off=0
来查找它们。