最近,我开始对PostgreSQL免费空间管理和碎片整理进行一些研究。据我所知,堆中的每个页面都包含一个页眉、页标识符、空闲空间和项。当插入一个新的元组时,一个新的项标识符将插入到空闲空间的开头,而新的项数据将插入到空闲空间的末尾。
使用Vacuum后,将删除死元组的项标识符和项数据。如果已删除的项标识符位于其他标识符的中间,则标识符之间将存在空白。由于新的标识符通常会在空闲空间的开头添加,这段空间之间的空闲空间还会再被重用吗?如果是这样,我们如何才能找到这个空间?
下面是这个场景的一个可视化示例:

去掉一些元组后,(0,3)和(0,5)之间有未使用的空间。如何再利用这个空间?谢谢!
发布于 2020-10-08 02:22:38
您所称的“项标识符”的PostgreSQL技术术语是“行指针”。“项指针”或“元组标识符”是页面号和行指针(图像中的(0,5) )的组合。
乍一看,这种间接操作很尴尬,但优点是可以随时重新调整实际的元组数据,以便在不更改元组地址的情况下对空闲空间进行碎片整理。
行指针在页头之后形成数组。当需要向缓冲区中添加新的元组时,可以使用任何空闲行指针。如果没有空闲行指针,则在数组末尾添加一个新的行指针。有关参考,请参见PageAddItemExtended in src/backend/storage/page/bufpage.c。
发布于 2020-10-08 01:57:39
假设表包含2页。我们来看看第一页(第0页),让我们假设插入了一些数据,并且页面有三个元组(行)。现在,如果我们删除元组2,则PG删除元组编号2,并将剩余的元组重新排序到去碎片,然后更新此页面的FSM和VM。PostgreSQL继续进行此过程,直到最后一页(真空)。
当您进行真空操作时,不必要的行指针不会被移除,它们将在将来被重用。
因为,如果删除行指针,则必须更新关联索引的所有索引元组。
https://stackoverflow.com/questions/64254419
复制相似问题