PostgreSQL之tuple结构

news/2024/7/9 23:13:19 标签: postgresql, 数据库

在上一篇文章PostgreSQL之堆表存储(Heap Table)中我们了解了PostgreSQL中堆表的存储结构,以及对于堆表的tuple是如何写入和读取的,不过我们只涉及到如何把想要的tuple从表对应的页面读取出来或者把tuple如何写到页面去,但是关于tuple内部的细节并没有说明。本文我们将着重学习一下tuple的内部结构以及对于增删改操作tuple是如何变化的。

Tuple结构

一个Tuple的结构主要包含三部分:由HeapTupleHeaderData结构定义的头信息,NULL bitmap以及用户数据,如下图所示。
在这里插入图片描述
NULL bitmap和用户数据很好理解,那么重点就是这个Tuple的头信息里面都代表了啥,从上图中我们可以看出,header里面重点的信息为t_xmin、t_xmax、t_cid、t_ctid。

  • t_xmin - 记录插入此行的事务号txid。
  • t_xmax - 记录此行被删除的事务号txid。如果此行未被删除或更新,值为0。
  • t_cid - 记录此行是在事务中的第几条SQL,如果是第一条值就是0,第二条值就是1,依次类推。比如对于’BEGIN;INSERT;INSERT;INSERT.COMMIT;'这样一个事务,这行是第三个INSERT中插入的,那么t_cid的值就是2。
  • t_ctid - 记录tuple identifier(TID),我们在前面的文章了介绍了TID是由block number+offset number组成的一个二元组,因此这个t_ctid就是一个用二元组表示的TID。如果对应行没有被更新,那么值就代表这个行自己,如果行被更新了,值指向新的行。可以理解这个t_ctid就是一个行的物理地址,对应到哪个页面中的哪条tuple位置。
    了解完Tuple的组成结构后,我们再看一下对于insert、update和delete操作对于Tuple的变更情况。

插入(Insert)

以下图为例,对于事务中只插入一条新记录,t_xmin会被填入对应事务号txid的值,t_xmax会被填入0因为这条数据没有被更新或删除,t_cid会被填入0因为这条insert语句是是事务中唯一的一条SQL,t_cid会被填入(0,1)代表这个表当前是空表这条数据是表的第一个页面中的第一条数据。
在这里插入图片描述
注:PG提供扩展pageinspect,可以查看数据库页面的内容。

testdb=# CREATE EXTENSION pageinspect;
CREATE EXTENSION
testdb=# CREATE TABLE tbl (data text);
CREATE TABLE
testdb=# INSERT INTO tbl VALUES('A');
INSERT 0 1
testdb=# SELECT lp as tuple, t_xmin, t_xmax, t_field3 as t_cid, t_ctid 
                FROM heap_page_items(get_raw_page('tbl', 0));
 tuple | t_xmin | t_xmax | t_cid | t_ctid 
-------+--------+--------+-------+--------
     1 |     99 |      0 |     0 | (0,1)

删除(Delete)

由于PG支持多版本MVCC,对于删除操作并不会立即把对应的tuple删除掉,而是通过标记让数据库知道这条数据属于被删除的数据,本质上其实是通过给t_xmax赋值来实现的。
以下图为例,一个事务中只包含一条delete语句,操作后对应这条记录的t_xmin不变,t_xmax被填入删除操作所在事务的事务号txid,t_cid为0因为这个事务中只包含这一条语句,t_cid保持不变因为这个tuple仍然在原来的位置。
在这里插入图片描述
注:如刚刚的说,delete之后这条tuple仍然保留,后续可以通过数据库的VACUUM清理机制自动删除。

修改(Update)

修改操作比insert和delete会复杂一些。PG中的修改操作内部是转换成了delete+insert的方式。因此整体上是把原记录标记为删除状态,然后插入一条新的记录。
以下图为例,一个事务中先后执行两条update,第一条update操作后,原记录的t_xmax被填入事务号100表示这条数据被删除,t_ctid被填入为(0,2)用来指向新插入的记录。Tuple_2代表新插入的记录,它的t_xmin被填入这个事务的txid 100,t_xmax为0因为这是一条新的记录,t_cid为因为这条记录是事务中的第一条SQL,t_ctid为(0,2)因为这条记录是表中的第二条记录。
在这里插入图片描述
再看第二条update结束后,把刚刚的Tuple_2删除了然后插入了一个新的Tuple_3,所以Tuple_2的t_xmax被填入100,t_ctid被修改为(0,3)指向新的记录位置。Tuple_3的t_xmin被填入同一个事务号100,t_xmax为0因为是一条新的记录,t_cid为1是因为这个update是事务中的第二条语句,t_ctid被修改为(0,3)代表这条记录是页面中的第二条tuple。

关于Free Space Map

以下我们学习了一个Tuple在增删改场景下的变化情况,这里我们附加说明一下FSM(Free Space Map)。
我们知道每个页面(Page)的顶端是header信息,尾端是Tuple记录,中间则是Free Space或者叫Hole。数据库在判断是否能往一个页面里面写的时候主要就是看这个Free Space够不够用。我们也可以通过扩展来查看每个页面的Free Space使用情况。

testdb=# CREATE EXTENSION pg_freespacemap;
CREATE EXTENSION

testdb=# SELECT *, round(100 * avail/8192 ,2) as "freespace ratio"
                FROM pg_freespace('accounts');
 blkno | avail | freespace ratio 
-------+-------+-----------------
     0 |  7904 |           96.00
     1 |  7520 |           91.00
     2 |  7136 |           87.00
     3 |  7136 |           87.00
     4 |  7136 |           87.00
     5 |  7136 |           87.00

http://www.niftyadmin.cn/n/181920.html

相关文章

pycharm 使用conda虚拟环境

一、配置conda虚拟环境1、使用如下命令创建conda虚拟环境conda create --prefixD:\pycharmProjects\conda\pycharm_env python3.10--prefix:执行创建conda虚拟环境的路径pycharm_env:虚拟环境的名称pythonx.x :指定虚拟环境配置的python版本2…

关于async/await、promise和setTimeout执行顺序

关于async/await、promise和setTimeout执行顺序 async function async1() {console.log(async1 start);await async2();console.log(asnyc1 end); } async function async2() {console.log(async2); } console.log(script start); setTimeout(() > {console.log(setTimeOut…

linux下QQ同一程序在不同位置的.desktop快捷方式文件的作用

以QQ为例,QQ程序在桌面显示为一个qq企鹅图标,名称为QQ,但是通过ls命令发现快捷方式全称为QQ.desktop 1./usr/share/applications/QQ.desktop 该文件存在的情况下,系统开始菜单里会有该应用的快捷方式, 可通过mv命令将…

深度学习 Day29——利用Pytorch实现咖啡豆识别

深度学习 Day29——利用Pytorch实现咖啡豆识别 文章目录深度学习 Day29——利用Pytorch实现咖啡豆识别一、前言二、我的环境三、前期工作1、导入依赖项设置GPU2、导入数据3、划分数据集四、手动搭建VGG16模型1、模型搭建2、查看模型参数3、调用官方的VGG16网络框架五、训练模型…

关于seo怎样才能优化网站(seo网站优化如何做)

seo网站优化技巧,怎么优化自己网站 1:网站优化的重要性 网站优化对于现在的企业来说是非常重要的,因为它能够帮助企业更好地推广自己的产品和服务。网站优化不仅仅可以帮助企业节省开支,还能使企业的网站更加具有吸引力&#xf…

区块链概论

目录 1.概述 2.密码学原理 2.1.hash函数 2.2.签名 3.数据结构 3.1.区块结构 3.2.hash pointer 3.3.merkle tree 3.3.1.概述 3.3.2.证明数据存在 3.3.3.证明数据不存在 4.比特币的共识协议 4.1.概述 4.2.验证有效性 4.2.1.验证交易有效性 4.2.2.验证节点有效性 …

一文快速回顾 Session 和 Cookie

前言 在 Web 应用程序中(通俗点,可以理解成一个网站),Session 和 Cookie 是两个非常重要的概念,主要用于实现用户身份认证、数据传递等功能。今天就来讲讲这两个东西。 对于当时刚开始接触到这两个概念的我来说&…

10_.I.MX6ULL_EPIT定时器

目录 EPIT定时器简介 EPIT的配置 源码实现 EPIT定时器简介 EPIT的全称是: Enhanced Periodic Interrupt Timer,直译过来就是增强的周期中断定时器,它主要是完成周期性中断定时的。学过 STM32 的话应该知道,STM32里面的定时器还有很多其它的功能,比如输入捕获、PWM 输出等等…