暂无图片
pg中通过t_infomask2来判断表是否是hot更新,对应的原理是啥?
我来答
分享
暂无图片 匿名用户
pg中通过t_infomask2来判断表是否是hot更新,对应的原理是啥?

例如:


update t1 set info = 'abcd' where id = 2;

想判断是否是hot更新,一种方式是通过

t_infomask2 来判断的


请问,背后对应的原理是啥?

我来答
添加附件
收藏
分享
问题补充
1条回答
默认
最新
shunwahⓂ️

t_infomask标识位用于加快元组的可见性判断,其实现原理为:当查询一条数据时,需要判断所涉及元组的可见性,也就需要知道该元组的提交状态( 查看CLOG) ,如果同一条数据经常被查询或被访问,就需要多次去查看CLOG文件,会涉及较高代价的I/O操作。而将可见性标识位t_infomask直接写入把事务状态直接记录在元组头中(HeapTupleHeaderData),避免频繁访问CLOG影响从而加快可见性判断。

2.3 t_infomask的计算

postgres=# insert into test values(1);
postgres=# insert into test values(2);
postgres=# select *, t_xmin,t_xmax, t_infomask,t_infomask2 from heap_page_items(get_raw_page('test',0));
 lp | lp_off | lp_flags | lp_len | t_xmin | t_xmax | t_field3 | t_ctid | t_infomask2 | t_infomask | t_hoff | t_bits | t_oid |   t_data   | t_xmin | t_xmax | t_infomask | t_infomask2 
----+--------+----------+--------+--------+--------+----------+--------+-------------+------------+--------+--------+-------+------------+--------+--------+------------+-------------
  1 |  16352 |        1 |     28 |    824 |      0 |        0 | (0,1)  |           1 |       2048 |     24 |        |       | \x01000000 |    824 |      0 |       2048 |           1
  2 |  16320 |        1 |     28 |    825 |      0 |        0 | (0,2)  |           1 |       2048 |     24 |        |       | \x02000000 |    825 |      0 |       2048 |           1
(2 rows)
复制

可以看出插入 1 的事务id 为824, 插入 2 的事务id 为825。两者的标志位 t_infomask = 2048, 换算成16进制为0x0800;根据上述t_infomask的宏定义可知 t_xmax invalid/aborted,这是因为插入数据t_xmax不发生变化,为0;并不知道t_xmin是否提交,也就是说下次查询的时候并不能直接判断该元组的可见性,需要从CLOG读取事务的提交状态。

问题来了,那怎么才能避免后续重读读取CLOG文件,加快元组可见性判断和数据的读取呢?见下:

postgres=# select * from test;
 id 
----
  1
  2
(2 rows)
复制
postgres=# select *, t_xmin,t_xmax, t_infomask,t_infomask2 from heap_page_items(get_raw_page('test',0));
 lp | lp_off | lp_flags | lp_len | t_xmin | t_xmax | t_field3 | t_ctid | t_infomask2 | t_infomask | t_hoff | t_bits | t_oid |   t_data   | t_xmin | t_xmax | t_infomask | t_infomask2 
----+--------+----------+--------+--------+--------+----------+--------+-------------+------------+--------+--------+-------+------------+--------+--------+------------+-------------
  1 |  16352 |        1 |     28 |    824 |      0 |        0 | (0,1)  |           1 |       2304 |     24 |        |       | \x01000000 |    824 |      0 |       2304 |           1
  2 |  16320 |        1 |     28 |    825 |      0 |        0 | (0,2)  |           1 |       2304 |     24 |        |       | \x02000000 |    825 |      0 |       2304 |           1
(2 rows)
复制

从上述例子看出,执行select 语句后发现t_infomask从2048转变成2304,换算成16进制为0x0900;即
0x0800 | 0x0100 = 0x0900,表明设置了HEAP_XMIN_COMMITTED(0x0100)这个标志位,该元组插入成功并已提交,对后续事务均可见。

等到第一次访问(可能是VACUUM,DML或SELECT)该元组并进行可见性判断时:

如果Hint Bits已设置,直接读取Hint Bits的值。
如果Hint Bits未设置,则调用函数从CLOG中读取事务状态。如果事务状态为COMMITTED或ABORTED,则将Hint Bits设置到元组的t_informask字段。如果事务状态为INPROCESS,由于其状态还未到达终态,无需设置Hint Bits。

https://www.pudn.com/news/62444b37852c2d5b7e8042ef.html

暂无图片 评论
暂无图片 有用 0
打赏 0
回答交流
Markdown


请输入正文
提交
相关推荐
pg_stat_activity中的pid可以批量查杀吗?
回答 3
select'selectpgterminatebackend('||pid||');'askill,usename,datname,currentquery,now()querystartascti
PostgreSQL编译安装问题
回答 4
好的,我试试,谢谢各位大佬...
是不是只能postgres superuser 才可以restore?
回答 1
不是,普通用户可以对自己有权限的表进行恢复。同时pgdump备份导出时也可以不导出owner和权限信息,请查看pgdump的选项。
postgresql 有什么函数可以获取本机 ip 地址吗?
回答 1
已采纳
PostgreSQL本身并不带类似的转换函数,只能自己通过splitpart之类的方法进行分割转换。写函数:CREATEFUNCTIONip2int(text)RETURNSbigintAS$$SEL
pg中show 参数,怎么模糊查看或者show all|grep -i data这样怎么过滤需要的参数名
回答 3
这个问题可以用pg15的psql客户端\dconfig查看
postgresql没有执行sql操作,但是内存一直占用很高?
回答 1
利用top,pgtop查看消耗内存过多的进程,然后再检查配置参数,最后可能就是Postgres在本地内存中加载的缓存,由于模式和表太多,导致缓存太大,占用了太多内存https://juejin.cn/
postgreSQL 可以设置单独放wal日志的文件系统吗?
回答 6
可以
postgresql 死锁如何发现或者监控?
回答 1
已采纳
可以通过查看pgstatactivity表SELECTFROMpgstatactivityWHEREdatname'数据库名'andwaiting't';或者selectpidfrompglocksw
pg中除了基本统计信息,如何收集数据的分布信息--数据不均匀?
回答 2
通过analyze命令收集统计信息会自动更新列分布信息,应对数据分布不均匀的情况。
postgreSQL 分区表 默认放到DEFAULT,怎么查DEFAULT的数据?
回答 1
直接查询父表,where带上分区键,执行计划会直接打到子表上