06-PG存储——HOT

1.HOT简介

PG从8.3版本开始,实现了HOT的特性,HOT为Heap-Only Tuple updates的缩写,即堆内元组更新,HOT使行更新时,将新记录和旧记录放在同一个页面内,这样就避免了索引元组的修改(索引元组修改很消耗资源),避免了不必要的清理过程。

2.为什么引入HOT

我们知道,PG删除行或更新行不会真正的清除旧的记录,而是将其标记为删除,在事务中不可见,但是数据的变更会影响索引的引用,因为索引的叶块保存的是索引键值(列)和键值所在的块号和偏移量。如下所示

test=#  SELECT * FROM index_page('idx_id',1);
 itemoffset | htid  | dead 
------------+-------+------
          1 | (0,1) | f
          2 | (0,2) | f
          3 | (0,3) | f
          4 | (0,4) | f
          5 | (1,1) | f
(5 rows)

第一列itemoffset是索引记录在本页的偏移量。第二列htid就是索引所指向的数据页的页号和偏移量。(0,1)表示该条索引记录指向的数据页为表0号页面第1条记录,同理(1,1)表示1号页面第1条记录。

在没有HOT之前,一旦行发生更新,新行很有可能在本页面,也可能插入到新的页面上去,无论更新的行是在本页面还是新页面,那么此时原索引的(0,1)记录就无效了,需要为更新的行新增一条新的指针记录。当然,索引页记录也不会删除,会标记为“死亡”,这样频繁的更新不仅仅会造成表数据的膨胀,更严重的是索引数据的膨胀,因此,postgreSQL引入了HOT。

3.HOT的工作原理

引入HOT后,在更新一行时,如果更新的行和旧的行在同一个页面上(可以配置较小的fillfactor参数,给更新留足空间),那么就不会再修改改行的索引记录,而是在旧元组标记为Heap Hot Updated,而同页面内的新行标记为Heap Only Tuple,两个标志位分别保存在自己元组的t_infomask2字段中。

#创建表
test=# drop table hot;
DROP TABLE
test=# create table hot (id int,name varchar(20));
CREATE TABLE
#创建基于ID列的索引
test=# create index ind_id on hot(id);
CREATE INDEX
#插入三行记录
test=# insert into hot values(1,'aaa');
INSERT 0 1
test=# insert into hot values(2,'bbb');
INSERT 0 1
test=# insert into hot values(3,'ccc'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南風_入弦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值