pageinspect分析btree索引结构

简介:

pg的btree索引有4中类型的索引页面:1、meta page,每个索引都会有该页面,这个页面直接指向root page。2、root page页面,如果heap item很多,会指向新的branch page或者是leaf page。3、branch page页面指向branch page或者leaf page。4、leaf page。
我在9.4.7的版本上8kblock的int类型字段上的索引,大概一个页面可以存407条记录,也就是说,如果你是int索引且只有一个字段记录数在0-407范围内是只有root page的这是1级结构,2级结构的记录数就是407*407,3级结构就是407^3,以此类推。
现在具体开始使用pageinspect分析pg索引结构。先安装pageinspect
image
创建好测试表,插入测试数据。
image
下面开始分析1级结构。找到表a的索引名称
image
使用bt_metap看索引页面信息。
image
这个信息意思就是a_pkey这个索引level=0就说明只有meta page和root page,root page的id是1。
使用bt_page_stats看下索引页面的状态信息。
image
btpo_flags=2表示root节点,btpo_flags=1表示 leaf节点,btpo_flags=0表示 branch节点,btpo_flags=3表示即使root节点又是leaf节点。btpo=0是最底层,btpo_prev和btpo_next表示左右节点页面号。
使用bt_page_items看下索引页面内容。
image
这里面有个注意点,如果该节点是最右节点就是第一条记录就是指向页面的第一条记录,如果不是最右节点就是第二条为第一条记录,第一条记录为右节点的起始item。从bt_page_stats可以看出它的左右节点都是0号页面也就是meta page所以1号页面是最右节点,所以取第一条记录,ctid(0,1)
image

二级结构。
image
level=1代表2级结构,就是meta page,root page,leaf page。root页面id=3。
bt_page_stats信息
image
btpo_flags=2表示这是root节点,btpo=1表示不是最底层,左右节点都是0号页面。
bt_page_items信息
image
因为这个是最右节点所以是第一条记录指向下一个节点页面号。所以是(1,1)
看下1号页面的bt_page_stats信息
image
btpo_flags=1是leaf page,btpo=0是最底层。左节点页面号是0,右节点页面号是2。该节点不是最右节点。
看下1号页面bt_page_items信息
image
因为不是最右节点,所以取第二条记录(0,1)。
看下(0,1)的具体内容。
image

三级结构。
image
level=2说明有meta page,root page,一个branch page,一个leaf page,root page页面号是412。
bt_page_stats信息
image
btpo_flags=2是root节点,btpo=2不是最底层。
bt_page_items信息
image
branch节点页面号是3。

branch节点bt_page_stats。
image
btpo_flags=0,是branch节点,btpo=1不是底层节点。
branch节点bt_page_items。
image
下一叶子节点页面号是(1,1)。

leaf节点bt_page_stats。
image
btpo=0,是底层节点。btpo_flags=1是leaf page。
leaf节点bt_page_items。
image
第一条数据是(0,1)。
image

下面模拟一种异常状况进行分析。
先创建表create unlogged table test03 (id int primary key, info text);
vi test.sql
setrandom id 1 100
insert into test03 values(:id, repeat(md5(random()::text), 1000)) on conflict on constraint test03_pkey do update set info=excluded.info;

第一个会话开启长事务。
第二个会话运行:pgbench -M prepared -n -r -P 1 -f test.sql -c 48 -j 48 -T 2000

正常状态时:
image
长时间运行第二个会话,关闭索引扫描出现的情况:
image
发现大部分都是heap块。看到这里知道了,这个其实是pg的hot update搞得鬼。
hot update 就是更新非索引字段时,会产生一个tuple2,索引指向ctid1,ctid1还是先指向原来的tuple1,再由tuple1指向ctid2,再由ctid2指向tuple2。如果你进行vacuum之后,就是索引指向ctid1,tuple1被回收,ctid1指向ctid2,ctid2指向tuple2。
现在用pageinspect看下这个表的索引情况:
image
这是有meta page,root page,branch page,leaf page这种结构的,root号是412。
image
image

从这两张图可以得出(1,1)到(99,1)除了(99,1)的第一条数据都是id=1的数据。下面看下一共有多少个。
image
是394个。
image
又重新查了下发现(99,1)这个里面就没有id=1的数据。一共扫描的块数就是394+root page+leaf page=396,刚好和上面的计划中扫描块的总数相同。(这里有点小疑问,我觉得应该是计划的是对的,一共是有394条数据但是只需要扫描393个块,索引是扫描了3个,扫描了root leaf1 和leaf99,好像证明不了,按照计划来推断应该是这样算的)。

目录
相关文章
windbg分析 IRQL_NOT_LESS_OR_EQUAL 蓝屏问题
本文通过windbg分析了电脑出现的IRQL_NOT_LESS_OR_EQUAL蓝屏问题,并尝试了多种解决方法,最终通过硬件清理暂时解决了问题。
1790 0
windbg分析 IRQL_NOT_LESS_OR_EQUAL 蓝屏问题
|
算法 Java 调度
软考中级软件设计师自我总结知识分享--JAVA类真题总结(一)
该系列文章全篇文字在10w+,全文都是自己备考中的干货,软考涉及很多计算机基础,数据结构,算法分析,编程思想,开发流程等等,不仅适合参加软考的人学习,也适合扩宽自己知识视野的人去学习,每一篇都将会把重点加粗处理,特别是易错点,考试常考平时也容易记错,请一定仔细看!
1088 0
|
SQL 消息中间件 人工智能
《Apache Flink 案例集(2022版)》——5.数字化转型——翼支付Apache Flink 在翼支付的实践应用(上)
《Apache Flink 案例集(2022版)》——5.数字化转型——翼支付Apache Flink 在翼支付的实践应用(上)
456 0
|
存储 Docker 容器
Docker系列教程28-实战:使用Docker Compose运行ELK
原文:http://www.itmuch.com/docker/28-docker-compose-in-action-elk/,转载请说明出处。 ElasticSearch【存储】 Logtash【日志聚合器】 Kibana【界面】 答案: ...
1646 0
vue2的简单Popup (Confirm,Alert)组件
                 github:  https://github.com/longfei59418888/vui   (记得给一个 start,以后有一起讨论,各种好组件)     demo : http://60.205.209.185/#/popup
1287 0
|
Linux Apache
Centos 7 service 命令的更改,systemctl命令简单实用实例
centos 7 中的类似**"service httpd start"**服务启动,停止,重启指令,**“service”**已更改为**“systemctl”**。具体示例如下: systemctl start httpd.service 启动Apache httpd systemctl
3542 0
人工智能 缓存 前端开发
8582 32
人工智能 JavaScript 开发工具
3609 8
开发工具 Swift git
1363 2