wal文件结构
PG使用无符号64bit整型(uint64)作为日志文件的寻址空间,理论上来说,如果只有一个日志文件,那么这个事务日志文件的大小最大为2^64Bytes(即16M*1TB=16EB)。为了高效管理事务日志文件,PG把日志文件划分为N个大小为16M(默认值)的WAL segment file.
总体结构如下图所示:
wal segment files
00000001 00000000 00000001
WAL segment file文件长度为24,由3部分组成,每个部分是8个16进制数字:
1.第1部分是TimeLineID,0x00000000 -> 0xFFFFFFFF
2.第2部分是逻辑文件ID,0x00000000 -> 0xFFFFFFFF
中间6个16进制没使用
3.第3部分是物理文件ID,0x00 -> 0xFF
逻辑文件ID占32bit,物理文件ID占8bit,16M的文件占24bit(16是2^4 + 1M是2^20),合计64bit.PG通过这三部分的组合,达到最大64bit的文件寻址空间.
dump数据内容
000000010000000000000001文件
逻辑id是0
物理id是01
pg_waldump -p ./ -s 0/01000000 -n 4
第一条xlog
len:106
lsn:0/01000028
头占了2*16+8=40字节,所以开始位置是028
prev 0/00000000
desc:CHECKPOINT_SHUTDOWN redo 0/1000028; tli 1; prev tli 1; fpw true; xid 0:3; oid 10000; multi 1; offset 0; oldest xid 3 in DB 1; oldest multi 1 in DB 1; oldest/newest commit timestamp xid: 0/0; oldest running xid 0; shutdown
第二条xlog
len:30
lsn:0/01000098
绝对位置相当于9*16+8=152
prev: 0/01000028
desc: NEXTOID 18192
数据内容
调试方法
postgres=# create table test(id int);
postgres=# select pg_current_wal_lsn();
pg_current_wal_lsn
--------------------
0/15DE5D8
(1 row)
postgres=# insert into test values(1);
INSERT 0 1
postgres=# insert into test values(21);
INSERT 0 1
postgres=# checkpoint;
CHECKPOINT
postgres=# select pg_current_wal_lsn();
pg_current_wal_lsn
--------------------
0/15DE788
(1 row)
pg_waldump -p ./ -s 0/15DE5D8 -e 0/15DE788
创建语句
rmgr: Heap
PostgreSQL内部将WAL日志归类到20多种不同的资源管理器。这条WAL记录所属资源管理器为Heap,即堆表。除了Heap还有Btree,Transaction等。
len (rec/tot): 3/ 59
WAL记录的总长度是59字节,其中main data部分是59字节
tx: 556
事务号
lsn: 0/015DE5D8
本WAL记录的LSN
prev 0/015DE5A0
上条WAL记录的LSN
desc: INSERT+INIT off 1
这是一条insert类型的记录(每个资源管理器最多包含16种不同的WAL记录类型),tuple在page中的位置为1。
blkref #0: rel 1663/16384/53523 blk 0
引用的第一个page所属的对表文件为1663/16384/53523,块号为0(即ctid的前半部分)。通过oid2name可以查到是哪个堆表。
更新和删除语句
LSN
10的函数
select pg_current_wal_lsn(), pg_walfile_name(pg_current_wal_lsn()), pg_walfile_name_offset(pg_current_wal_lsn());
1代表文件
5C7F00代表偏移,十进制就是6061824
9的函数
select pg_current_xlog_location(), pg_xlogfile_name(pg_current_xlog_location()), pg_xlogfile_name_offset(pg_current_xlog_location());
参考
https://www.cnblogs.com/kuang17/p/10613938.html