广告
返回顶部
首页 > 资讯 > 数据库 >PostgreSQL中的Multi Version Heap Tuple分析
  • 427
分享到

PostgreSQL中的Multi Version Heap Tuple分析

2024-04-02 19:04:59 427人浏览 安东尼
摘要

这篇文章主要介绍“postgresql中的Multi Version Heap Tuple分析”,在日常操作中,相信很多人在Postgresql中的Multi Version Heap Tuple分析问题上

这篇文章主要介绍“postgresql中的Multi Version Heap Tuple分析”,在日常操作中,相信很多人在Postgresql中的Multi Version Heap Tuple分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”PostgreSQL中的Multi Version Heap Tuple分析”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

Concurrency Control并发控制是一种机制,在并发进行多个事务时维护一致性(Consistency)和隔离性(Isolation),一致性和隔离性是数据库事务ACID(Atomicity, Consistency, Isolation, Durability) 属性中的C和I。
多版本并发控制(mvcC)是广泛使用的并发控制技术,其主要优势是读不会阻塞写,而写也不会阻塞读。MVCC有很多种变体,PostgreSQL使用一种称为快照隔离Snapshot Isolation (SI)的MVCC变体实现并发控制。
在MVCC中,每个DML操作创建一个数据(包括Index)的新版本,同时保留之前的旧版本。当事务读取数据时,选择其中一个“正确”的版本,以确保各个事务之间的隔离。

零、隐藏列和infomask标记

为了更好的说明Heap Tuple的存储结构,有必要先简要说明Tuple的隐藏列以及相关的标记.
隐藏列

testdb=# select attname, attnum, atttypid::regtype, attisdropped::text from pg_attribute where attrelid=34374;
 attname  | attnum |     atttypid      | attisdropped 
----------+--------+-------------------+--------------
 tableoid |     -7 | oid               | false
 cmax     |     -6 | cid               | false
 xmax     |     -5 | xid               | false
 cmin     |     -4 | cid               | false
 xmin     |     -3 | xid               | false
 ctid     |     -1 | tid               | false
 c1       |      1 | integer           | false
 c2       |      2 | character varying | false
 c3       |      3 | character varying | false
(9 rows)

tableoid-数据表OID
cmax-删除该tuple的事务内部命令ID
xmax-删除该tuple的事务ID
cmin-插入该tuple的事务内部命令ID
xmin-插入该tuple的事务ID
ctid-heap tuple的ID

infomask标记
主要的标记包括t_infomask2和t_infomask.
t_infomask2
取值和说明如下


#define HEAP_NATTS_MASK 0x07FF 
//低11位为属性个数

#define HEAP_KEYS_UPDATED 0x2000 
#define HEAP_HOT_UPDATED 0x4000 
#define HEAP_ONLY_TUPLE 0x8000 
#define HEAP2_XACT_MASK 0xE000 
//把十六进制值转换为二进制显示
     11111111111 #define HEAP_NATTS_MASK         0x07FF 
  10000000000000 #define HEAP_KEYS_UPDATED       0x2000  
 100000000000000 #define HEAP_HOT_UPDATED        0x4000  
1000000000000000 #define HEAP_ONLY_TUPLE         0x8000  
1110000000000000 #define HEAP2_XACT_MASK         0xE000 
1111111111111110 #define SpecTokenOffsetNumber       0xfffe

t_infomask
取值和说明如下

//t_infomask说明
               1 #define HEAP_HASNULL            0x0001  
              10 #define HEAP_HASVARWIDTH        0x0002  
             100 #define HEAP_HASEXTERNAL        0x0004  
            1000 #define HEAP_HASOID             0x0008  
           10000 #define HEAP_XMAX_KEYSHR_LOCK   0x0010  
          100000 #define HEAP_COMBOCID           0x0020  
         1000000 #define HEAP_XMAX_EXCL_LOCK     0x0040  
        10000000 #define HEAP_XMAX_LOCK_ONLY     0x0080  
                    
                 #define HEAP_XMAX_SHR_LOCK  (HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_KEYSHR_LOCK)
                 #define HEAP_LOCK_MASK  (HEAP_XMAX_SHR_LOCK | HEAP_XMAX_EXCL_LOCK | \
                          HEAP_XMAX_KEYSHR_LOCK)
       100000000 #define HEAP_XMIN_COMMITTED     0x0100  
      1000000000 #define HEAP_XMIN_INVALID       0x0200  
                 #define HEAP_XMIN_FROZEN        (HEAP_XMIN_COMMITTED|HEAP_XMIN_INVALID)
     10000000000 #define HEAP_XMAX_COMMITTED     0x0400  
    100000000000 #define HEAP_XMAX_INVALID       0x0800  
   1000000000000 #define HEAP_XMAX_IS_MULTI      0x1000  
  10000000000000 #define HEAP_UPDATED            0x2000  
 100000000000000 #define HEAP_MOVED_OFF          0x4000  
1000000000000000 #define HEAP_MOVED_IN           0x8000  
                 #define HEAP_MOVED (HEAP_MOVED_OFF | HEAP_MOVED_IN)
1111111111110000 #define HEAP_XACT_MASK          0xFFF0  

一、INSERT

创建数据表,插入数据

testdb=# drop table if exists t_mvcc1;
DROP TABLE
testdb=# create table t_mvcc1 (c1 int,c2 varchar(40));
CREATE TABLE
testdb=# 
testdb=# insert into t_mvcc1 values(1,'C2-1');
INSERT 0 1
testdb=# insert into t_mvcc1 values(2,'C2-2');
INSERT 0 1
testdb=#

通过pageinspect插件查看page中的内容

testdb=# select lp,lp_off,lp_flags,t_xmin,t_xmax,t_field3 as t_cid,t_ctid,t_infomask2,t_infomask from heap_page_items(get_raw_page('t_mvcc1',0));
 lp | lp_off | lp_flags | t_xmin | t_xmax | t_cid | t_ctid | t_infomask2 | t_infomask 
----+--------+----------+--------+--------+-------+--------+-------------+------------
  1 |   8152 |        1 |   2300 |      0 |     0 | (0,1)  |           2 |       2050
  2 |   8112 |        1 |   2301 |      0 |     0 | (0,2)  |           2 |       2050
(2 rows)

其中lp为Line Pointer(ItemID,行指针),t_xmin(分别是2300&2301)为插入数据的事务ID,t_xmax为0(Invalid事务号),t_cid是命令编号,t_ctid是heap tuple ID,详细解释请参见参考资料.
t_infomask2为0x0002,说明有2个字段(低11位为属性的个数);
t_infomask为2050,即0x0802,标记存在可变长属性(HEAP_HASVARWIDTH)/XMAX无效(HEAP_XMAX_INVALID)

二、UPDATE

更新数据(提交事务)

testdb=# 
testdb=# begin;
BEGIN
testdb=# 
testdb=# update t_mvcc1 set c2='C2#1' where c1 = 1;
UPDATE 1
testdb=# update t_mvcc1 set c2='C2#2' where c1 = 2;
UPDATE 1
testdb=# 
testdb=# commit;
COMMIT

通过pageinspect插件查看page中的内容

testdb=# select lp,lp_off,lp_flags,t_xmin,t_xmax,t_field3 as t_cid,t_ctid,t_infomask2,t_infomask from heap_page_items(get_raw_page('t_mvcc1',0));
 lp | lp_off | lp_flags | t_xmin | t_xmax | t_cid | t_ctid | t_infomask2 | t_infomask 
----+--------+----------+--------+--------+-------+--------+-------------+------------
  1 |   8152 |        1 |   2300 |   2302 |     0 | (0,3)  |       16386 |        258
  2 |   8112 |        1 |   2301 |   2302 |     1 | (0,4)  |       16386 |        258
  3 |   8072 |        1 |   2302 |      0 |     0 | (0,3)  |       32770 |      10242
  4 |   8032 |        1 |   2302 |      0 |     1 | (0,4)  |       32770 |      10242
(4 rows)

可以看到原数据仍存在,但t_xmax值为2302,表示这两行已被更新,同时t_ctid指向新的heap tuple.
1/2号tuple的t_infomask2是16386即0x4002 -> HEAP_HOT_UPDATED
t_infomask是258,即0x0102 -> HEAP_XMIN_COMMITTED | HEAP_HASVARWIDTH

3/4号tuple的t_infomask2是32770,即0x8002 -> HEAP_ONLY_TUPLE
t_infomask是10242,即0x2802 -> HEAP_UPDATED | HEAP_XMAX_INVALID | HEAP_HASVARWIDTH

更新数据(回滚事务)

testdb=# begin;
BEGIN
testdb=# 
testdb=# update t_mvcc1 set c2='C2_1' where c1 = 1;
UPDATE 1
testdb=# update t_mvcc1 set c2='C2_2' where c1 = 2;
UPDATE 1
testdb=# 
testdb=# rollback;
ROLLBACK
testdb=# select cmin,cmax,xmin,xmax,ctid,c1,c2 from t_mvcc1;
 cmin | cmax | xmin | xmax | ctid  | c1 |  c2  
------+------+------+------+-------+----+------
    0 |    0 | 2302 | 2303 | (0,3) |  1 | C2#1
    1 |    1 | 2302 | 2303 | (0,4) |  2 | C2#2
(2 rows)

通过pageinspect插件查看page中的内容

testdb=# select lp,lp_off,lp_flags,t_xmin,t_xmax,t_field3 as t_cid,t_ctid,t_infomask2,t_infomask from heap_page_items(get_raw_page('t_mvcc1',0));
 lp | lp_off | lp_flags | t_xmin | t_xmax | t_cid | t_ctid | t_infomask2 | t_infomask 
----+--------+----------+--------+--------+-------+--------+-------------+------------
  1 |   8152 |        1 |   2300 |   2302 |     0 | (0,3)  |       16386 |       1282
  2 |   8112 |        1 |   2301 |   2302 |     1 | (0,4)  |       16386 |       1282
  3 |   8072 |        1 |   2302 |   2303 |     0 | (0,5)  |       49154 |       8450
  4 |   8032 |        1 |   2302 |   2303 |     1 | (0,6)  |       49154 |       8450
  5 |   7992 |        1 |   2303 |      0 |     0 | (0,5)  |       32770 |      10242
  6 |   7952 |        1 |   2303 |      0 |     1 | (0,6)  |       32770 |      10242
(6 rows)

3/4号(lp=3/4)tuple被更新,t_xmax设置为更新事务的ID,但事务rollback(PG通过clog记录事务状态,clog后续再行讨论).
t_infomask2=49154,即0xC002
t_infomask=8450,即0x2102 -> HEAP_UPDATED | HEAP_XMIN_COMMITTED | HEAP_HASVARWIDTH

5/6号tuple是新生成的更新记录,但事务rollback.
t_infomask2=32770,即0x8002 -> HEAP_ONLY_TUPLE
t_infomask=10242,即0x2802 -> HEAP_UPDATED | HEAP_XMAX_INVALID | HEAP_HASVARWIDTH

三、DELETE

删除数据(提交事务)

testdb=# begin;
BEGIN
testdb=# 
testdb=# delete from t_mvcc1 where c1 = 1;
DELETE 1
testdb=# 
testdb=# commit;
COMMIT
testdb=# 
testdb=#  select cmin,cmax,xmin,xmax,ctid,c1,c2 from t_mvcc1;
 cmin | cmax | xmin | xmax | ctid  | c1 |  c2  
------+------+------+------+-------+----+------
    1 |    1 | 2302 | 2303 | (0,4) |  2 | C2#2
(1 row)

通过pageinspect插件查看page中的内容

testdb=# select lp,lp_off,lp_flags,t_xmin,t_xmax,t_field3 as t_cid,t_ctid,t_infomask2,t_infomask from heap_page_items(get_raw_page('t_mvcc1',0));
 lp | lp_off | lp_flags | t_xmin | t_xmax | t_cid | t_ctid | t_infomask2 | t_infomask 
----+--------+----------+--------+--------+-------+--------+-------------+------------
  1 |   8152 |        1 |   2300 |   2302 |     0 | (0,3)  |       16386 |       1282
  2 |   8112 |        1 |   2301 |   2302 |     1 | (0,4)  |       16386 |       1282
  3 |   8072 |        1 |   2302 |   2304 |     0 | (0,3)  |       40962 |       9474
  4 |   8032 |        1 |   2302 |   2303 |     1 | (0,6)  |       49154 |      10498
  5 |   7992 |        1 |   2303 |      0 |     0 | (0,5)  |       32770 |      10754
  6 |   7952 |        1 |   2303 |      0 |     1 | (0,6)  |       32770 |      10754
(6 rows)

3号(lp=3) tuple被删除,t_xmax修改为2304,t_ctid修改为(0,3).
t_infomask2=40962,即0xA002
t_infomask=9474,即0x2502 -> HEAP_UPDATED | HEAP_XMAX_COMMITTED | HEAP_XMIN_COMMITTED | HEAP_HASVARWIDTH

删除数据(回滚事务)

testdb=# begin;
BEGIN
testdb=# 
testdb=# delete from t_mvcc1 where c1 = 2;
DELETE 1
testdb=# 
testdb=# rollback;
ROLLBACK
testdb=# 
testdb=# select cmin,cmax,xmin,xmax,ctid,c1,c2 from t_mvcc1;
 cmin | cmax | xmin | xmax | ctid  | c1 |  c2  
------+------+------+------+-------+----+------
    0 |    0 | 2302 | 2305 | (0,4) |  2 | C2#2
(1 row)

xmax修改为事务号2305(原为2303).
通过pageinspect插件查看page中的内容

testdb=# select lp,lp_off,lp_flags,t_xmin,t_xmax,t_field3 as t_cid,t_ctid,t_infomask2,t_infomask from heap_page_items(get_raw_page('t_mvcc1',0));
 lp | lp_off | lp_flags | t_xmin | t_xmax | t_cid | t_ctid | t_infomask2 | t_infomask 
----+--------+----------+--------+--------+-------+--------+-------------+------------
  1 |   8152 |        1 |   2300 |   2302 |     0 | (0,3)  |       16386 |       1282
  2 |   8112 |        1 |   2301 |   2302 |     1 | (0,4)  |       16386 |       1282
  3 |   8072 |        1 |   2302 |   2304 |     0 | (0,3)  |       40962 |       9474
  4 |   8032 |        1 |   2302 |   2305 |     0 | (0,4)  |       40962 |      10498
  5 |   7992 |        1 |   2303 |      0 |     0 | (0,5)  |       32770 |      10754
  6 |   7952 |        1 |   2303 |      0 |     1 | (0,6)  |       32770 |      10754
(6 rows)

删除4号(lp=4) tuple,但事务回滚,t_max修改为2305.
t_infomask2=40962,即0xA002
t_infomask=10498,即0x2902 -> HEAP_UPDATED | HEAP_XMAX_INVALID | HEAP_XMIN_COMMITTED | HEAP_HASVARWIDTH

到此,关于“PostgreSQL中的Multi Version Heap Tuple分析”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

您可能感兴趣的文档:

--结束END--

本文标题: PostgreSQL中的Multi Version Heap Tuple分析

本文链接: https://www.lsjlt.com/news/64368.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • PostgreSQL中的Multi Version Heap Tuple分析
    这篇文章主要介绍“PostgreSQL中的Multi Version Heap Tuple分析”,在日常操作中,相信很多人在PostgreSQL中的Multi Version Heap Tuple分析问题上...
    99+
    2022-10-18
  • 分析PostgreSQL中的tuple locks
    这篇文章主要介绍“分析PostgreSQL中的tuple locks”,在日常操作中,相信很多人在分析PostgreSQL中的tuple locks问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方...
    99+
    2022-10-18
  • PostgreSQL中哪个函数为heap tuple找到合适的分区
    本篇内容介绍了“PostgreSQL中哪个函数为heap tuple找到合适的分区”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔...
    99+
    2022-10-18
  • PostgreSQL中Tuple可见性判断分析
    本篇内容主要讲解“PostgreSQL中Tuple可见性判断分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“PostgreSQL中Tuple可见性判断分析”吧...
    99+
    2022-10-18
  • Python语言中Tuple的由来分析
    目录Tuple概述Tuple与英语Tuple与数学Tuple与编程Tuple概述 在Python中使用元组(Tuple)存储一组信息,其特征如下: 1、使用()定义元组2、元组中使用...
    99+
    2022-11-11
  • Python中的Tuple操作实例分析
    这篇“Python中的Tuple操作实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Python中的Tuple操作实例...
    99+
    2023-06-29
  • PostgreSQL中获取Tuple的分区键值函数是什么
    这篇文章主要介绍“PostgreSQL中获取Tuple的分区键值函数是什么”,在日常操作中,相信很多人在PostgreSQL中获取Tuple的分区键值函数是什么问题上存在疑惑,小编查阅了各式资料,整理出简单...
    99+
    2022-10-18
  • 分析PostgreSQL中的synchronous_commit参数
    本篇内容主要讲解“分析PostgreSQL中的synchronous_commit参数”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“分析PostgreSQL中的...
    99+
    2022-10-18
  • PostgreSQL中PlannedStmt的跟踪分析
    这篇文章主要为大家展示了“PostgreSQL中PlannedStmt的跟踪分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“PostgreSQL中Planne...
    99+
    2022-10-19
  • PostgreSQL中的ProcessRepliesIfAny函数分析
    本篇内容主要讲解“PostgreSQL中的ProcessRepliesIfAny函数分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“PostgreSQL中的P...
    99+
    2022-10-18
  • 分析PostgreSQL中的distinct和group by
    本篇内容介绍了“分析PostgreSQL中的distinct和group by”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅...
    99+
    2022-10-18
  • 分析PostgreSQL CreateFunction中的interpret_function_parameter_list函数
    这篇文章主要介绍“分析PostgreSQL CreateFunction中的interpret_function_parameter_list函数”,在日常操作中,相信很多人在分析PostgreSQL Cr...
    99+
    2022-10-18
  • 分析PostgreSQL CreateFunction中的ProcedureCreate函数
    本篇内容介绍了“分析PostgreSQL CreateFunction中的ProcedureCreate函数”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何...
    99+
    2022-10-18
  • 分析PostgreSQL中的Prepare Transaction特性
    本篇内容介绍了“分析PostgreSQL中的Prepare Transaction特性”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大...
    99+
    2022-10-18
  • 分析PostgreSQL中的大表连接
    这篇文章主要介绍“分析PostgreSQL中的大表连接”,在日常操作中,相信很多人在分析PostgreSQL中的大表连接问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”分析Po...
    99+
    2022-10-18
  • 分析PostgreSQL中的数据结构HTAB
    这篇文章主要讲解了“分析PostgreSQL中的数据结构HTAB”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“分析PostgreSQL中的数据结构HTAB”...
    99+
    2022-10-18
  • PostgreSQL中PlannedStmt结构的日志分析
    这篇文章主要介绍了PostgreSQL中PlannedStmt结构的日志分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。APPEND-&g...
    99+
    2022-10-19
  • 分析PostgreSQL DBA中新增的WAL选项
    这篇文章主要讲解了“分析PostgreSQL DBA中新增的WAL选项”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“分析PostgreSQL DBA中新增的...
    99+
    2022-10-18
  • PostgreSQL中关系代数的示例分析
    这篇文章给大家分享的是有关PostgreSQL中关系代数的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、基本概念关系代数是一种过程化查询语言.它包括一个运算的集合,这...
    99+
    2022-10-18
  • PostgreSQL中查询重写的示例分析
    小编给大家分享一下PostgreSQL中查询重写的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!重写后的Query结构三...
    99+
    2022-10-18
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作