PG事物提交之后,会把事务的状态信息写入到clog(pg_xact)文件中,当第一次访问事物涉及到的行时,会读取clog记录的事物状态信息来判断事物是否提交或者abort,并且更新t_infomask的状态,这样下次再访问该行数据时通过判断t_infomask就知道不再需要访问clog了。具体t_infomask的具体值和意义,可以参考https://blog.csdn.net/m15217321304/article/details/110870837

--//源码位置  src/backend/access/transam/clog.c

--//xid事物的状态信息可以在头文件查看
--//头文件位置src/include/access/clog.h

/** Possible transaction statuses --- note that all-zeroes is the initial* state.** A "subcommitted" transaction is a committed subtransaction whose parent* hasn't committed or aborted yet.*/
typedef int XidStatus;#define TRANSACTION_STATUS_IN_PROGRESS          0x00
#define TRANSACTION_STATUS_COMMITTED            0x01
#define TRANSACTION_STATUS_ABORTED              0x02
#define TRANSACTION_STATUS_SUB_COMMITTED        0x03

--//源码位置  src/backend/access/transam/clog.c

/** Defines for CLOG page sizes.  A page is the same BLCKSZ as is used* everywhere else in Postgres.** Note: because TransactionIds are 32 bits and wrap around at 0xFFFFFFFF,* CLOG page numbering also wraps around at 0xFFFFFFFF/CLOG_XACTS_PER_PAGE,* and CLOG segment numbering at* 0xFFFFFFFF/CLOG_XACTS_PER_PAGE/SLRU_PAGES_PER_SEGMENT.  We need take no* explicit notice of that fact in this module, except when comparing segment* and page numbers in TruncateCLOG (see CLOGPagePrecedes).*//* We need two bits per xact, so four xacts fit in a byte */
#define CLOG_BITS_PER_XACT      2
#define CLOG_XACTS_PER_BYTE 4
#define CLOG_XACTS_PER_PAGE (BLCKSZ * CLOG_XACTS_PER_BYTE)
#define CLOG_XACT_BITMASK       ((1 << CLOG_BITS_PER_XACT) - 1)##CLOG_BITS_PER_XACT  代表一个事务2个字节 , 一个事务需要两个字节表示,所以一个1字节(8个bit位)可以存放8/2=4个事物
##CLOG_XACTS_PER_BYTE 代表一个字节可以存放4个事物
##CLOG_XACTS_PER_PAGE 代表一个page可以存放多少事物 ,比如一个块8K, 一个字节可以存放4个事物, 所以一个page=8192*4
##CLOG_XACT_BITMASK   代表CLOG_BITS_PER_XACT左移一位,CLOG_BITS_PER_XACT原值为2,二进制为0010,左移一位0100,然后0100转换10进制为3,3 - 1 =2,转换2进制为0011#define SLRU_PAGES_PER_SEGMENT  32
代入公式中:
N = 0xFFFFFFFF/CLOG_XACTS_PER_PAGE/SLRU_PAGES_PER_SEGMENT
= 0xFFFFFFFF/(8192*4)/32
= 4096
--//每个segment有32个Pages(SLRU_PAGES_PER_SEGMENT = 32),则每个segment file大小为8K*32=256K.

给定一个事务号,如何获取该事务对应的状态?
PG首先通过该事务号获得该事务状态存储在clog中哪个page,然后再根据下面的公式,计算存储事物状态的偏移量

 #define TransactionIdToPage(xid)    ((xid) / (TransactionId) CLOG_XACTS_PER_PAGE)#define TransactionIdToPgIndex(xid) ((xid) % (TransactionId) CLOG_XACTS_PER_PAGE)#define TransactionIdToByte(xid)    (TransactionIdToPgIndex(xid) / CLOG_XACTS_PER_BYTE)#define TransactionIdToBIndex(xid)  ((xid) % (TransactionId) CLOG_XACTS_PER_BYTE)
如给定事务号100,根据上述公式可得到:
Page = 100 / (8192*4) = 0 —> 第0号page
PageIndex = 100 % (8192*4) = 100 —> Page内偏移
ByteInPage = 100 / 4 = 25 —> 该Page内的第25个Byte
ByteIndex = 100 % 4 = 0 —> 该字节中的首2bits

--//上面提到一个segment大小为8K*32=256K
--//我这里就遇到这么一个问题,我的xid事物号很大,如果直接套用上面的公式,那么在xact文件中找不到对应的文件

下面通过实际案例验证

--//session 1

postgres=# select txid_current();txid_current
--------------1048700
(1 row)postgres=#
--//先不要提交

--//按照公式

--//1048700/(8192*4)
postgres=# select 1048700/(8192*4);?column?
----------32
(1 row)postgres=# 

--//但是xact文件里面没有超过32k大小的文件

[postgres@postgres pg_xact]$ ls -ltr
total 16
-rw------- 1 postgres postgres 8192 Jan 19 07:47 0000
-rw------- 1 postgres postgres 8192 Jun  9 00:07 0001
[postgres@postgres pg_xact]$ 

--//一个段 32个page ,一个page可以存放page*4个事物, 所以一个段最多可以存放  32*8192*4= 1048576
--//所以,如果一个xid大于了1048700,那么需要使用xid%(8192*4*32)(无论xid大小是多少,使用这个公式都没有问题)

postgres=# select 1048700/(8192*4*32);?column?
----------1
(1 row)postgres=# 

—-//所以,xid事物落到了0001文件

--//偏移量为1048694%(8192*4*32)

postgres=# select 1048700%(8192*4*32);?column?
----------124
(1 row)

--//换算偏移量对应的位置

postgres=# select 124/4;?column?
----------31
(1 row)postgres=# 

--//换算在31字节处的具体位置(1个字节8个bit,2个bit代表一个事务)

postgres=# select 124%4;?column?
----------0
(1 row)postgres=#
--//说明在31字节的前2bit位

--//使用hexdump查看内容,当前还没有提交

[postgres@postgres pg_xact]$ hexdump -C 0001 -s 31 -n 1
0000001f  00                                                |.|
00000020
[postgres@postgres pg_xact]$ --//对应的进制码为 00 00 00 00

--//session 1提交会话并checkpoint

postgres=# commit;
COMMIT
postgres=# checkpoint;
CHECKPOINT
postgres=# \q
[postgres@postgres pg_xact]$ 

--//再次hexdump查看

[postgres@postgres pg_xact]$ hexdump -C 0001 -s 31 -n 1
0000001f  01                                                |.|
00000020
[postgres@postgres pg_xact]$ --//对应二进制码为 00 00 00 01

--//session 1 再次开启一个新事务,最后回滚

postgres=# select txid_current();txid_current
--------------1048701
(1 row)postgres=# abort;
ROLLBACK
postgres=# checkpoint;
CHECKPOINT
postgres=# 

--//查询clog的数据
--//#define TRANSACTION_STATUS_ABORTED              0x02
--//理论上0x2转换2进制为 10,那么31字节的bit 码应如下:
--//00 00 10 01 转换16进制为9
--//使用hexdump查看

[postgres@postgres pg_xact]$ hexdump -C 0001 -s 31 -n 1
0000001f  09                                                |.|
00000020
[postgres@postgres pg_xact]$ 

--//session 1 再次开启一个新事务,然后回滚

postgres=# begin;
BEGIN
postgres=# select txid_current();txid_current
--------------1048702
(1 row)postgres=# abort;
ROLLBACK
postgres=# checkpoint;
CHECKPOINT
postgres=# 

--//理论上2进制码为 00 10 10 01 ,转换16进制 29
--//使用hexdump验证

[postgres@postgres pg_xact]$ hexdump -C 0001 -s 31 -n 1
0000001f  29                                                |)|
00000020
[postgres@postgres pg_xact]$ 

--//session 1 再次开启一个新事务,最后提交

postgres=# begin;
BEGIN
postgres=# select txid_current();txid_current
--------------1048703
(1 row)postgres=# commit;
COMMIT
postgres=# checkpoint;
CHECKPOINT
postgres=# 

--//这个时候2进制码应该为 01 10 10 01,转换16进制为 69 
--//使用hexdump验证

[postgres@postgres pg_xact]$ hexdump -C 0001 -s 31 -n 1
0000001f  69                                                |i|
00000020
[postgres@postgres pg_xact]$ 

--//如果session 1再开启一个会话,无论事务提交还是回滚,都不会再影响31字节处的数据
--//session 1开启一个会话,提交

postgres=# begin;
BEGIN
postgres=# select txid_current();txid_current
--------------1048704
(1 row)postgres=# commit;
COMMIT
postgres=# checkpoint;
CHECKPOINT
postgres=# 

--//使用hexdump验证

[postgres@postgres pg_xact]$ hexdump -C 0001 -s 31 -n 1
0000001f  69                                                |i|
00000020
[postgres@postgres pg_xact]$ 

--//如果验证32字节处的数据,2进制码应该是 00 00 00 01,转换16进制为01

[postgres@postgres pg_xact]$ hexdump -C 0001 -s 32 -n 1
00000020  01                                                |.|
00000021
[postgres@postgres pg_xact]$ 

[2021-06-17]PostgreSQL事物提交日志信息clog解析相关推荐

  1. Mculover666的博客文章导航(嵌入式宝藏站)(2021.06.17更新)

    一.MCU系列 1. 开发环境 [Keil MDK](一)Keil MDK 5.28 的下载.安装.破解 [Keil MDK](二)Keil MDK中芯片器件包的安装 [Keil MDK](三)Kei ...

  2. svn修改提交日志信息

    参考:唐小码个人博客 一.svn修改提交的msg信息和作者信息 鼠标右键找到show log> 选择要修改的日志行,第一个是修改作者信息,第二个是修改日志信息 二.svn修改提交的日期信息 修改 ...

  3. python爬虫笔记 -- 更新至2021/06/17

    教学视频1(简略):https://www.bilibili.com/video/BV1164y1m7Xb 教学视频2:https://www.bilibili.com/video/BV1Yh411o ...

  4. Java 字符串(一条日志信息)解析实例

    Java 基础--日期(Date)的解析 如下为 Apache common 生成的日志信息格式: 27.19.74.143 - - [30/May/2013:17:38:20 +0800] \&qu ...

  5. postgresql源码学习(51)—— 提交日志CLOG 原理 用途 管理函数

    一. CLOG是什么 CLOG(commit log)记录事务的最终状态. 物理上,是$PGDATA/pg_xact目录下的一些文件 逻辑上,是一个数组,下标为事务id,值为事务最终状态 1. 事务最 ...

  6. Git 基础 —— 配置与日志信息

    0. 查看 git 的配置情况 git config命令使用 git config --list# 会以属性,属性值的形式,逐行的给出 1. .gitconfig 文件 安装完成后,还需要最后一步设置 ...

  7. 2021.06.06家庭财经系统制作(2)

    show tables; 查看数据库里有什么表命令. 碰到mysql软件问题.比想象的难缠. 用之前的方式打不开黑框(鼠标单击 mysql5.7 ccommand line Client),黑框一闪而 ...

  8. Elastic Stack容器化部署拓展(Https、AD域集成)并收集Cisco设备的日志信息

    前言: 还记得在去年的笔记中提到过EFK(Elasticsearch-Filebeat-Kibana)的部署,但是其中的内容相对简单,也没有提到一些额外的Elastic Stack的特性.链接如下:h ...

  9. 1git命令的使用,查看git仓库状态,添加文件到git跟踪,git提交,查看git分支,查看git仓库日志信息,切换git分支,解决git分支合并后出现冲突的问题

    1新建一个存储git的文件夹,命令是: toto@toto-K45VD:~$ mkdir gitfolder 2初始化一个git仓库,命令是: toto@toto-K45VD:~$cd gitfold ...

最新文章

  1. 使用BCH 操作码的三个新型应用程序
  2. 模拟和存根有什么区别?
  3. bireme数据源同步工具--debezium+kafka+bireme
  4. 安装Ruby和Rails运行环境
  5. 【树莓派】树莓派CSI摄像头安装及测试方法
  6. SSM框架中分页插件pageHelper的使用实例
  7. canvas用2d渲染出3d的感觉
  8. java暂停的方法_Java使用join方法暂停当前线程
  9. php布尔类型代码,php中的boolean(布尔)类型详解
  10. Codeforces 235C
  11. python 伪多线程_Python实现简单多线程任务队列
  12. C++表白代码---一颗心
  13. 高中电子技术——电子元器件的识别
  14. 人民日报申论范文:如何写“担当”“责任”
  15. 网易互娱2017实习生招聘游戏研发工程师在线笔试第二场(图像处理)
  16. RH2288v3常用的知识
  17. C++知识讲解(一)
  18. nginx——反向代理,https加密证书,重定向
  19. java代码校验手机号码_校验手机号码的正则表达式写法 (java实现)
  20. JMockit mock 静态块 static block

热门文章

  1. Eclipse(中文语言包下载地址)Indigo,Helios,Galileo,Ganymede,Europa
  2. 如何保护Excel的工作簿结构不被改动?
  3. 企业对java的需求_企业最需要的需求状态是哪一种?
  4. 手掌是人体健康的晴雨表
  5. Vm挂载虚拟硬盘(傻瓜式教程)
  6. uniapp中vue强制刷新部分视图数据
  7. 走马观花看西门子公司自动控制软件
  8. 小试墨刀-----打地鼠
  9. JS省市联动 需要引用JQUERY包
  10. 股票配资中的穿仓是什么意思