LSN in WAL

相关概念

  1. LSN 是一个 64 位逻辑字节偏移量,表示从 WAL 流起始位置的字节偏移
  2. TLI(TimeLineID)TLI 是 时间线标识符,用于区分 WAL 历史的不同”分支”。

表现形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
* Pointer to a location in the XLOG. These pointers are 64 bits wide,
* because we don't want them ever to overflow.
*/

typedef uint64 XLogRecPtr;

/*
* Store the LSN as a single 64-bit value, to allow atomic loads/stores.
*
* For historical reasons, the storage of 64-bit LSN values depends on CPU
* endianness; PageXLogRecPtr used to be a struct consisting of two 32-bit
* values. When reading (and writing) the pd_lsn field from page headers, the
* caller must convert from (and convert to) the platform's native endianness.
*/
typedef struct
{
uint64 lsn;
} PageXLogRecPtr;

相关转换

1
2
3
4
5
#define XLogSegNoOffsetToRecPtr(segno, offset, wal_segsz_bytes, dest) \
(dest) = (segno) * (wal_segsz_bytes) + (offset)

#define XLogSegmentOffset(xlogptr, wal_segsz_bytes) \
((xlogptr) & ((wal_segsz_bytes) - 1))

wal 日志文件

Format

1
00000001 00000000 00000003
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#define XLogSegmentsPerXLogId(wal_segsz_bytes) \
(UINT64CONST(0x100000000) / (wal_segsz_bytes))

/*
* Generate a WAL segment file name. Do not use this function in a helper
* function allocating the result generated.
*/
static inline void
XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
{
snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli,
(uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)),
(uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)));
}

An example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
gujinfei@jeff:~/codes/blink-tree-cpp/build$ pg_controldata $PGDATA | grep "Bytes per WAL segment"
Bytes per WAL segment: 16777216
gujinfei@jeff:~/codes/blink-tree-cpp/build$

gujinfei=# SELECT pg_current_wal_lsn();
pg_current_wal_lsn
--------------------
0/0384C598
(1 row)

gujinfei=# SELECT pg_walfile_name('0/0384C598');
pg_walfile_name
--------------------------
000000010000000000000003
(1 row)

  1. segno = 0x0384C598 / 0x1000000 = 3
  2. offset = 0x0384C598 % 0x1000000 = 0x384C598
  3. 文件名解析:
    • TLI(TimeLineID):00000001
    • 3/256 = 00000000
    • 3%256 = 00000003