专栏首页数据库架构之美PostgreSQL堆内元组、动态剪枝技术介绍

PostgreSQL堆内元组、动态剪枝技术介绍

上一篇文章《PostgreSQL的元组、页面结构及索引查找原理》中介绍了postgresql数据库数据结构和索引查找过程,本文接着继续介绍下堆内元组和动态剪枝技术,这两个技术其实是相辅相成的。我们知道在数据库元组插入更新时,索引也需要进行相应维护,因为pg的老元组不会实时清理,那么在更新后索引中就会多出一条索引记录指向新元组,这样造成索引膨胀,维护代价变大。pg为了避免这个问题,从8.3版本开始采用HOT(heap only tuple)解决这个问题,下面简单介绍一下技术原理。

普通更新

如下图所示,当tuple发生更新后,需要新增一条tuple记录到页面中,此时索引中也对应新增了一条记录,该记录指向tuple2的line pointer。这样的话每次更新都需要在索引页面插入新记录,维护开销太大,而且会造成索引膨胀。Pg采用hot技术解决这个问题。

HOT更新

在使用hot更新时,元组更新后不会在索引页面新建相应记录,而通过在新老元组上设置标志位使得老元组指向新元组,形成新旧元组“链”解决这个问题。

前一篇文章介绍过,在元组结构的t_informask2字段中有两个标记位,heap_hot_update和heap_only_tuple,在更新tuple1时,postgresql会将tuple1(老元组)的标记位置为heap_hot_update,代表该元组是经过hot更新的行,同时将tuple2(新元组)的标记位置为heap_only_tuple。具体过程如下:

1.首先找到目标数据的索引元组

2.然后通过索引元组中的位置,访问行指针数组,找到行指针1

3.读取tuple1

4.发现tuple1的标记位是heap_hot_update,表明该元组是经过hot更新的元组,并不是真实要读取的数据,于是通过tuple1的t_ctid字段读取tuple2(上一篇文章也介绍过,当元组被更新过后,元组的t_ctid字段指向新的元组)

动态修剪

上面访问数据的过程其实访问了tuple1和tuple2两个数据块,这时我们可能会考虑到一个问题,因为tuple1是旧元组,它会在合适时机被vacuum掉,这时就无法通过tuple1的ctid字段定位到tuple2了,为了解决这个问题,postgresql会在合适的时候进行line pointer的重定向(redirect),将tuple1的line pointer重定向到line pointer2,这个过程称为动态修剪。

此时访问新元组的流程如下:

1.首先找到目标数据的索引元组

2.然后通过索引元组中的位置,访问行指针数组,找到行指针1

3.通过行指针的重定向,找到行指针2

4.通过行指针2直接定位tuple2

HOT技术的适用场景

当然HOT技术也不是万能的,它也有不适用的场景,比如下面两个场景:

1.当更新的元组和老元组不在同一个page中时,新旧元组链是不能跨越页面的,指向该元组的索引元组也会被添加到索引页面中。

2.当索引的key值更新时,原有索引记录中的key无法再定位到正确元组,此时会在索引页面中插入一条新的索引元组。

本文分享自微信公众号 - 数据库架构之美(databasekernel),作者:数据库架构之美

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-12-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Postgresql HOT技术内幕解读

    我们知道在数据库行数据更新时,索引也需要进行维护,如果是高并发的情况下,索引维护的代价很大,可能造成索引分裂。Pg为了避免这个问题,采用了HOT(堆内元组技术)...

    数据库架构之美
  • PostgreSQL的元组、页面结构及索引查找原理

    我们知道postgresql数据库通过数据多版本实现mvcc,pg又没有undo段,老版本的数据元组直接存放在数据页面中,这样带来的问题就是旧元组需要不断地进行...

    数据库架构之美
  • 硬核-深度剖析PostgreSQL数据库“冻结炸弹”原理机制

    冻结(FREEZE),相信熟悉pg的人都对这个词不陌生,因为冻结过程对数据库的资源消耗极大,影响业务的正常运行,所以也被称为“冻结炸弹”。网上关于冻结的文章也比...

    数据库架构之美
  • Python | 5分钟搞定 Python3 元组

    元组(tuple)是一种静态的(immutable)或者说是不可变(unchangeable)的数据结构,里面的元素按照一定的顺序排列。它是静态的,所以元组里的...

    用户1634449
  • 4.91Python数据类型之(6)元组

    用户2398817
  • 技术 | Python从零开始系列连载(九)

    导读 Python特色数据类型(元组)(上) 元组(tuple) 元组是Python的另一种特色的数据类型 元组和列表是相似的 可以存储不同类型的数据 但是!划...

    灯塔大数据
  • 爬虫 (十三) 学习 python 基础知识点的正确姿势 (六)

    我会以比较学习的方式,主要拿Python和我之前学习的javascript进行比较,拿学习javascript的学习经历来迁移到学习Python,如果你在此之前...

    公众号---志学Python
  • Python 元组知识点

    程序员同行者
  • 技术 | Python从零开始系列连载(十)

    导读 Python特色数据类型(元组)(下) 元组和列表相互转化 ? ? 没错,只要在原来的列表外套一层tuple()就可以转为元组 在原来的元组外面套一层li...

    灯塔大数据
  • python中的元组

    和列表一样 也可以使用数字索引提取元素中的值 然而最常用的方法是将元组解包为一组变量:

    用户2398817

扫码关注云+社区

领取腾讯云代金券