暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

Halo数据库--CLOG

原创 Halo Tech 2024-03-11
388

一、CLOG是什么

    CLOG(COMMIT log)——事务提交日志,它是保存PG数据库中事务的状态,从而判断事务的可见性。事务提交日志分配于共享内存中,并作用于事务处理的全过程。

二、CLOG中事务状态

    CLOG中只记录四种事务状态,分别是IN_PROGRESS(进行中),CMMITTED(已提交),ABORTED(回滚,中断)以及SUB_COMMITTED(子事务已提交)。

在源码/src/include/access/clog.h 中定义的数据结构


三、CLOG是怎么工作的


如上图:

T1:txid 200 提交;txid 200的状态从IN_PROGRESS状态改变为CMMITTED状态。

T2:txid 201 回滚或中止;txid 201的状态就从IN_PROGRESS状态变为了ABORTED状态。

注:引用了《PostgreSQL指南:内幕探索》5.4.2节内容

四、CLOG文件能记录多少记录

在源码/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                                /*一个事务状态占用2个bit位*/
#define CLOG_XACTS_PER_BYTE 4                               /*一个字节可以存放4个事务状态(默认4,8 bit/2)*/
#define CLOG_XACTS_PER_PAGE (BLCKSZ * CLOG_XACTS_PER_BYTE)    /*一个页块可以存放多少个事务状态(默认8KB*8b/2b=32K=2^15个)*/
#define CLOG_XACT_BITMASK    ((1 << CLOG_BITS_PER_XACT) - 1)

从源码中的定义可以知道记录一个事务状态信息需要2比特,一个字节存储了4个事务状态的记录。一个页面(默认是8KB),可记录CLOG记录条数为8K*8b/2b=32K,所以一个CLOG日志文件为256KB,在一个段中由32个页面组成,可记录的CLOG日志条数为32*2^15=2^20条记录。

    事务ID为32bit,可表示的事务数有2^32个,CLOG日志文件是以段文件为单位的,CLOG段的数量为2^32/2^20=2^12。CLOG日志文件以段号命名,所以只需要12位即可,postgresql以4位的十六进制数来表示段号,并作为日志段文件的名称。

五、CLOG存储在哪里

CLOG存储在PG数据目录下的pg_xact子目录中(pg9.4之前是存储在clog子目录,pg10之后才改成pg_xact子目录),文件中主要记录的是事务号(xid)和事务最终状态。

看下pg_xact目录下clog文件:

[halo@halo168 pg_xact]$ pwd
/data/halo/pg_xact
[halo@halo168 pg_xact]$ ls -l
total 16
-rw-------. 1 halo halo 8192 Mar  1 04:53 0000

CLOG日志文件命名是0000,0001,0002,......。

六、怎么定位CLOG日志中记录

我们先来看下源码/src/backend/access/transam/clog.c中

#define TransactionIdToPage(xid)    ((xid) / (TransactionId) CLOG_XACTS_PER_PAGE)         
/*使用事务ID计算该事务在第几个页面*/
#define TransactionIdToPgIndex(xid) ((xid) % (TransactionId) CLOG_XACTS_PER_PAGE)        
/*使用事务ID计算该事务在页面上的偏移量是多少*/
#define TransactionIdToByte(xid)    (TransactionIdToPgIndex(xid) / CLOG_XACTS_PER_BYTE)   
/*使用事务ID计算该事务在面页上的字节偏移,就是第几个的字节*/
#define TransactionIdToBIndex(xid)    ((xid) % (TransactionId) CLOG_XACTS_PER_BYTE)       
/*使用事务ID计算该事务在记录其CLOG记录的字节内的偏移量,即字节内的哪个bit*/

根据这四元组定义我们可以用来定位某条CLOG日志记录。

七、定位CLOG日志记录实操

以回滚操作作为实操,如下图


执行checkpoint刷新CLOG,把数据落盘。

然后使用hexdemp工具dump出该bytes。命令格式如下:


hexdump -C -n length -s skip file_name
常用参数:
-C 定义了导出的格式,
-s skip 指定了从文件头跳过多少字节,或者说是偏移量,默认是十进制。如果是0x开头,则是十六进制。
-n 指定了导出多少长度

实际操作如下图


其他状态验证类似,不再验证。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论