searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

WAL事务日志

2023-09-26 01:19:26
20
0

WAL 事务日志

什么是WAL

  • WAL是Write Ahead Logging的缩写,指的是将变更与行为写入事务日志的协议

  • 在PostgreSQL中,事务日志/将行为写入事务日志的实现机制

  • 在7.1版本中首次实现,是时间点恢复( Point-in-Time Recovery,PITR ) 与流复制(Streaming Replication,SR)实现的基础

WAL段文件

PG使用无符号64bit整型(uint64)作为事务日志文件的寻址空间.

为了便于管理,PG把事务日志文件划分为N个segment,每个segment称为WAL segment file,每个WAL segment file大小默认为16MB

 

可以在initdb时通过--wal-segsize选项来配置WAL段文件的大小。

WAL segment file文件名称为24个字符,由3部分组成,每个部分是8个字符,每个字符是一个16进制值(即0~F)

第1部分是TimeLineID,取值范围是0x00000000 -> 0xFFFFFFFF

第2部分是逻辑文件ID,取值范围是0x00000000 -> 0xFFFFFFFF

第3部分是物理文件ID,取值范围是0x00000000 -> 0x000000FF

LSN 标识符

为了标记每个数据页最后修改它的日志记录号,可以理解为XLOG Record在事务日志文件中的偏移

在每个数据页的PageHeaderData结构中引入了一个LSN标识符,指向最后修改页面的日志记录

typedef struct PageHeaderData
{
	/* XXX LSN is member of *any* block, not only page-organized ones */
	PageXLogRecPtr pd_lsn;		/* LSN: next byte after last byte of xlog
								 * record for last change to this page */
	uint16		pd_checksum;	/* checksum */
	uint16		pd_flags;		/* flag bits, see below */
	LocationIndex pd_lower;		/* offset to start of free space */
	LocationIndex pd_upper;		/* offset to end of free space */
	LocationIndex pd_special;	/* offset to start of special space */
	uint16		pd_pagesize_version;
	TransactionId pd_prune_xid; /* oldest prunable XID, or zero if none */
	ItemIdData	pd_linp[FLEXIBLE_ARRAY_MEMBER]; /* line pointer array */
} PageHeaderData;

LSN由3部分组成,分别是逻辑文件ID,物理文件ID和文件内偏移,三者共同组成unit64(32+8+24),达到最大64bit的+文件寻址空间.

根据LSN号推算得到其对应的日志文件

WAL segment file内部结构

WAL segment file内部划分为N个page(Block),每个page大小为8192 Bytes即8K,每个WAL segment file第1个page的header在PG源码中相应的数据结构是XLogLongPageHeaderData,后续其他page的header对应的数据结构是XLogPageHeaderData,结构定义在src/include/access/xlog_internal.h中

在一个page中,page header之后是N个XLOG Record。

XLogLongPageHeaderData 与 XLogPageHeaderData 结构的定义在src/include/access/xlog_internal.h

XLOG记录的数据部分可以分为两类:备份区块(完整的页面)或非备份区块(不同的操作对应的数据不同)

WAL段切换

  • WAL段已经被填满。

  • pg_switch_wal()被调用。

  • 启用了archive_mode,且已经超过archive_timeout配置的时间。

WAL段管理

切换后的段文件通常会被回收(重命名或重用)以供将来使用,如果不需要,也可能会被删除

配置参数wal_keep_segments及复制槽功能都会影响WAL段文件的数量。

使用pg_waldump查看WAL

postgres=# create table t_wal(n_id int);
CREATE TABLE
ztq=# select pg_current_wal_lsn();
 pg_current_wal_lsn 
--------------------
 0/5C013238
(1 row)

postgres=# insert into t_wal values(1);
INSERT 0 1
postgres=# insert into t_wal values(2);
INSERT 0 1
postgres=# checkpoint;
CHECKPOINT
postgres=# select pg_current_wal_lsn();
 pg_current_wal_lsn 
--------------------
 0/5C013548
(1 row)
[postgres@evm-cgn20cgcho6hmrpkhv60 ~]$ pg_waldump -s 0/5C013238 -e 0/5C013548
rmgr: Heap        len (rec/tot):     59/    59, tx:      16195, lsn: 0/5C013238, prev 0/5C013200, desc: INSERT+INIT off 1 flags 0x00, blkref #0: rel 1663/16384/16852 blk 0
rmgr: Transaction len (rec/tot):     34/    34, tx:      16195, lsn: 0/5C013278, prev 0/5C013238, desc: COMMIT 2023-05-15 16:01:27.400630 CST
rmgr: Standby     len (rec/tot):     54/    54, tx:          0, lsn: 0/5C0132A0, prev 0/5C013278, desc: RUNNING_XACTS nextXid 16196 latestCompletedXid 16194 oldestRunningXid 16195; 1 xacts: 16195
rmgr: Heap        len (rec/tot):     59/    59, tx:      16196, lsn: 0/5C0132D8, prev 0/5C0132A0, desc: INSERT off 2 flags 0x00, blkref #0: rel 1663/16384/16852 blk 0
rmgr: Transaction len (rec/tot):     34/    34, tx:      16196, lsn: 0/5C013318, prev 0/5C0132D8, desc: COMMIT 2023-05-15 16:01:36.487546 CST
rmgr: Standby     len (rec/tot):     50/    50, tx:          0, lsn: 0/5C013340, prev 0/5C013318, desc: RUNNING_XACTS nextXid 16197 latestCompletedXid 16196 oldestRunningXid 16197
rmgr: Standby     len (rec/tot):     50/    50, tx:          0, lsn: 0/5C013378, prev 0/5C013340, desc: RUNNING_XACTS nextXid 16197 latestCompletedXid 16196 oldestRunningXid 16197
rmgr: XLOG        len (rec/tot):    114/   114, tx:          0, lsn: 0/5C0133B0, prev 0/5C013378, desc: CHECKPOINT_ONLINE redo 0/5C013378; tli 1; prev tli 1; fpw true; xid 0:16197; oid 25044; multi 1; offset 0; oldest xid 480 in DB 1; oldest multi 1 in DB 1; oldest/newest commit timestamp xid: 0/0; oldest running xid 16197; online
rmgr: Standby     len (rec/tot):     50/    50, tx:          0, lsn: 0/5C013428, prev 0/5C0133B0, desc: RUNNING_XACTS nextXid 16197 latestCompletedXid 16196 oldestRunningXid 16197
rmgr: Standby     len (rec/tot):     50/    50, tx:          0, lsn: 0/5C013460, prev 0/5C013428, desc: RUNNING_XACTS nextXid 16197 latestCompletedXid 16196 oldestRunningXid 16197
rmgr: XLOG        len (rec/tot):    114/   114, tx:          0, lsn: 0/5C013498, prev 0/5C013460, desc: CHECKPOINT_ONLINE redo 0/5C013460; tli 1; prev tli 1; fpw true; xid 0:16197; oid 25044; multi 1; offset 0; oldest xid 480 in DB 1; oldest multi 1 in DB 1; oldest/newest commit timestamp xid: 0/0; oldest running xid 16197; online
rmgr: Standby     len (rec/tot):     50/    50, tx:          0, lsn: 0/5C013510, prev 0/5C013498, desc: RUNNING_XACTS nextXid 16197 latestCompletedXid 16196 oldestRunningXid 16197

pg_waldump的组成部分

  • rmgr : 资源名称,也即日志的归类。

  • lsn: 日志编号

  • desc :对日志详细信息的描述

 

 

0条评论
0 / 1000
z****n
4文章数
1粉丝数
z****n
4 文章 | 1 粉丝
z****n
4文章数
1粉丝数
z****n
4 文章 | 1 粉丝
原创

WAL事务日志

2023-09-26 01:19:26
20
0

WAL 事务日志

什么是WAL

  • WAL是Write Ahead Logging的缩写,指的是将变更与行为写入事务日志的协议

  • 在PostgreSQL中,事务日志/将行为写入事务日志的实现机制

  • 在7.1版本中首次实现,是时间点恢复( Point-in-Time Recovery,PITR ) 与流复制(Streaming Replication,SR)实现的基础

WAL段文件

PG使用无符号64bit整型(uint64)作为事务日志文件的寻址空间.

为了便于管理,PG把事务日志文件划分为N个segment,每个segment称为WAL segment file,每个WAL segment file大小默认为16MB

 

可以在initdb时通过--wal-segsize选项来配置WAL段文件的大小。

WAL segment file文件名称为24个字符,由3部分组成,每个部分是8个字符,每个字符是一个16进制值(即0~F)

第1部分是TimeLineID,取值范围是0x00000000 -> 0xFFFFFFFF

第2部分是逻辑文件ID,取值范围是0x00000000 -> 0xFFFFFFFF

第3部分是物理文件ID,取值范围是0x00000000 -> 0x000000FF

LSN 标识符

为了标记每个数据页最后修改它的日志记录号,可以理解为XLOG Record在事务日志文件中的偏移

在每个数据页的PageHeaderData结构中引入了一个LSN标识符,指向最后修改页面的日志记录

typedef struct PageHeaderData
{
	/* XXX LSN is member of *any* block, not only page-organized ones */
	PageXLogRecPtr pd_lsn;		/* LSN: next byte after last byte of xlog
								 * record for last change to this page */
	uint16		pd_checksum;	/* checksum */
	uint16		pd_flags;		/* flag bits, see below */
	LocationIndex pd_lower;		/* offset to start of free space */
	LocationIndex pd_upper;		/* offset to end of free space */
	LocationIndex pd_special;	/* offset to start of special space */
	uint16		pd_pagesize_version;
	TransactionId pd_prune_xid; /* oldest prunable XID, or zero if none */
	ItemIdData	pd_linp[FLEXIBLE_ARRAY_MEMBER]; /* line pointer array */
} PageHeaderData;

LSN由3部分组成,分别是逻辑文件ID,物理文件ID和文件内偏移,三者共同组成unit64(32+8+24),达到最大64bit的+文件寻址空间.

根据LSN号推算得到其对应的日志文件

WAL segment file内部结构

WAL segment file内部划分为N个page(Block),每个page大小为8192 Bytes即8K,每个WAL segment file第1个page的header在PG源码中相应的数据结构是XLogLongPageHeaderData,后续其他page的header对应的数据结构是XLogPageHeaderData,结构定义在src/include/access/xlog_internal.h中

在一个page中,page header之后是N个XLOG Record。

XLogLongPageHeaderData 与 XLogPageHeaderData 结构的定义在src/include/access/xlog_internal.h

XLOG记录的数据部分可以分为两类:备份区块(完整的页面)或非备份区块(不同的操作对应的数据不同)

WAL段切换

  • WAL段已经被填满。

  • pg_switch_wal()被调用。

  • 启用了archive_mode,且已经超过archive_timeout配置的时间。

WAL段管理

切换后的段文件通常会被回收(重命名或重用)以供将来使用,如果不需要,也可能会被删除

配置参数wal_keep_segments及复制槽功能都会影响WAL段文件的数量。

使用pg_waldump查看WAL

postgres=# create table t_wal(n_id int);
CREATE TABLE
ztq=# select pg_current_wal_lsn();
 pg_current_wal_lsn 
--------------------
 0/5C013238
(1 row)

postgres=# insert into t_wal values(1);
INSERT 0 1
postgres=# insert into t_wal values(2);
INSERT 0 1
postgres=# checkpoint;
CHECKPOINT
postgres=# select pg_current_wal_lsn();
 pg_current_wal_lsn 
--------------------
 0/5C013548
(1 row)
[postgres@evm-cgn20cgcho6hmrpkhv60 ~]$ pg_waldump -s 0/5C013238 -e 0/5C013548
rmgr: Heap        len (rec/tot):     59/    59, tx:      16195, lsn: 0/5C013238, prev 0/5C013200, desc: INSERT+INIT off 1 flags 0x00, blkref #0: rel 1663/16384/16852 blk 0
rmgr: Transaction len (rec/tot):     34/    34, tx:      16195, lsn: 0/5C013278, prev 0/5C013238, desc: COMMIT 2023-05-15 16:01:27.400630 CST
rmgr: Standby     len (rec/tot):     54/    54, tx:          0, lsn: 0/5C0132A0, prev 0/5C013278, desc: RUNNING_XACTS nextXid 16196 latestCompletedXid 16194 oldestRunningXid 16195; 1 xacts: 16195
rmgr: Heap        len (rec/tot):     59/    59, tx:      16196, lsn: 0/5C0132D8, prev 0/5C0132A0, desc: INSERT off 2 flags 0x00, blkref #0: rel 1663/16384/16852 blk 0
rmgr: Transaction len (rec/tot):     34/    34, tx:      16196, lsn: 0/5C013318, prev 0/5C0132D8, desc: COMMIT 2023-05-15 16:01:36.487546 CST
rmgr: Standby     len (rec/tot):     50/    50, tx:          0, lsn: 0/5C013340, prev 0/5C013318, desc: RUNNING_XACTS nextXid 16197 latestCompletedXid 16196 oldestRunningXid 16197
rmgr: Standby     len (rec/tot):     50/    50, tx:          0, lsn: 0/5C013378, prev 0/5C013340, desc: RUNNING_XACTS nextXid 16197 latestCompletedXid 16196 oldestRunningXid 16197
rmgr: XLOG        len (rec/tot):    114/   114, tx:          0, lsn: 0/5C0133B0, prev 0/5C013378, desc: CHECKPOINT_ONLINE redo 0/5C013378; tli 1; prev tli 1; fpw true; xid 0:16197; oid 25044; multi 1; offset 0; oldest xid 480 in DB 1; oldest multi 1 in DB 1; oldest/newest commit timestamp xid: 0/0; oldest running xid 16197; online
rmgr: Standby     len (rec/tot):     50/    50, tx:          0, lsn: 0/5C013428, prev 0/5C0133B0, desc: RUNNING_XACTS nextXid 16197 latestCompletedXid 16196 oldestRunningXid 16197
rmgr: Standby     len (rec/tot):     50/    50, tx:          0, lsn: 0/5C013460, prev 0/5C013428, desc: RUNNING_XACTS nextXid 16197 latestCompletedXid 16196 oldestRunningXid 16197
rmgr: XLOG        len (rec/tot):    114/   114, tx:          0, lsn: 0/5C013498, prev 0/5C013460, desc: CHECKPOINT_ONLINE redo 0/5C013460; tli 1; prev tli 1; fpw true; xid 0:16197; oid 25044; multi 1; offset 0; oldest xid 480 in DB 1; oldest multi 1 in DB 1; oldest/newest commit timestamp xid: 0/0; oldest running xid 16197; online
rmgr: Standby     len (rec/tot):     50/    50, tx:          0, lsn: 0/5C013510, prev 0/5C013498, desc: RUNNING_XACTS nextXid 16197 latestCompletedXid 16196 oldestRunningXid 16197

pg_waldump的组成部分

  • rmgr : 资源名称,也即日志的归类。

  • lsn: 日志编号

  • desc :对日志详细信息的描述

 

 

文章来自个人专栏
postgresql 日志分析
3 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
1
0