PG_Heap Only Tuple(HOT)剖析
Postgresql在8.3版中引入了HOT特性,以便在Update操作中,当更新的新行和旧行存储在相同的表数据页中时,能有效地使用索引和表的页;同时也减少了Vacuum处理的必要性。
无HOT之前PG-update存在的问题
假设表‘tbl’存在两个列 ‘id’ 和‘data’; ‘id’ 是 ‘tbl’的主键
testdb=# \d tbl Table "public.tbl" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- id | integer | | not null | data | text | | | Indexes: "tbl_pkey" PRIMARY KEY, btree (id)
表' tbl '有1000个元组;id为' 1000 '的最后一个元组存储在表的第5页。最后一个元组是从对应的索引元组中指向的,其索引键是' 1000 ',tid是'(5,1)',如图1.1(a)
Fig. 1.1. Update a row without HOT
我们考虑用以下SQL进行更新:
testdb=# UPDATE tbl SET data = 'B' WHERE id = 1000;
在这种情况下,PostgreSQL不仅会在表中插入新的元组,还会在索引页中插入新的索引元组。见图1.1(b)
索引元组的插入会消耗索引页空间,而且索引元组的插入和删除成本都很高。HOT降低了这些问题的影响。
HOT内部运行原理剖析
当一行数据用HOT特性更新时,如果更新的行和旧行存储在相同的表页面中,PostgreSQL将不插入相应的新索引元组,而是分别在在旧元组的t_informask2标志位中设置HEAP_HOT_UPDATED,新元组的t_informask2标志位中设置HEAP_ONLY_TUPLE ;见图1.2和1.3
此外,在执行剪枝和碎片整理操作中,HEAP_HOT_UPDATED和HEAP_ONLY_TUPLE位都将被使用。
Fig. 1.2. Update a row with HOT
Fig. 1.3. HEAP_HOT_UPDATED and HEAP_ONLY_TUPLE bits
以下,将剖析PostgreSQL如何在用HOT更新元组之后使用索引扫描访问更新后的元组。见图1.4(a)。
但是,如果删除表页中的死亡元组,就会出现一个问题。例如,在图1.4(a)中,如果' Tuple_1 '被删除,因为它是一个死元组,' Tuple_2 '将不能从索引中访问。
Fig. 1.4. Pruning of the line pointers
操作步骤如下:
(1)查找指向目标元组的索引元组 (2)访问从索引元组中指向的行指针"[1]" (3)读"Tuple_1" (4)通过Tuple_1的t_ctid读取Tuple_2
但是,如果删除表页中的dead tuple,就会出现一个问题。例如,在图1.4(a)中,如果' Tuple_1 '被删除,因为它是一个dead tuple,' Tuple_2 '将不能从索引中访问。
为了解决这个问题,在适当的时候,PostgreSQL将指向旧元组的行指针重定向到指向新元组的行指针。在PostgreSQL中,这种处理称为剪枝。图1.4(b)描述了PostgreSQL如何访问修剪后更新的元组。
操作步骤如下:
(1)查找索引元组。 (2)访问从索引元组中指向的行指针"[1]"。 (3)通过重定向的行指针访问指向Tuple_2的行指针"[2]"。 (4)读取由行指针"[2]"指向的Tuple_2
如果可能的话,在执行SELECT、UPDATE、INSERT和DELETE等SQL命令时,将执行修剪处理。由于执行时间非常复杂,本章不详细描述。详情可以查看README.HOT
如果可能的话,PostgreSQL会在适当的时候删除dead tuple,就像在修剪过程中一样。在PostgreSQL的文档中,这种处理称为碎片整理。图1.5描绘了热的碎片整理。
Fig. 1.5. Defragmentation of the dead tuples
请注意,碎片整理的成本低于正常的Vacuum处理的成本,因为碎片整理不涉及删除索引元组。
使用HOT可以减少索引和页面表的消耗;这也减少了Vacuum处理必须处理的元组数量。因此,HOT对性能有很好的影响,因为它在update和Vacuum的处理过程中,减少了索引元组的插入次数。
不适用场景:
1、新旧元组不在同一个数据块中。
2、更新的列包含索引键。
参考文献:
《The Internals of PostgreSQL for database administrators and system developers》
《Postgresql官方文档》