LSN 和 Wal日志的相关性
LSN 和 Wal日志的相关性
LSN :Log Sequence Number
- 查看当前LSN
test=# select pg_current_wal_lsn();
pg_current_wal_lsn
--------------------
1/37000140
(1 row)
- LSN 组成
Datum pg_lsn_out(PG_FUNCTION_ARGS) //保留主要内容 { XLogRecPtr lsn = PG_GETARG_LSN(0); // typedef uint64 XLogRecPtr; uint32 id, off; /* Decode ID and offset */ id = (uint32) (lsn >> 32); off = (uint32) lsn; snprintf(buf, sizeof buf, "%X/%X", id, off); }
LSN 由64位(8字节)数据类型表示,ID 和 offset 各用 32bit。我们清晰的知道了
/
分割线的意义。 ID使用32bit(4字节)表示, offset使用32bit(4字节)表示。 -
Wal日志
Wal日志名示例:000000010000000100000037
名称组成:00000001(时间线)00000001(ID)00000037(序列号)
分析:
/* * Compute a segment number from an XLogRecPtr. */ #define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes) \ logSegNo = (xlrp) / (wal_segsz_bytes) // 根据lsn除以wal_size取整可以计算出,该位置相对于wal_size所对应的日志号 #define XLogSegmentsPerXLogId(wal_segsz_bytes) \ (UINT64CONST(0x100000000) / (wal_segsz_bytes)) // 4G(32位系统单文件最大存储上限)数据除以wal_size可以计算出,每个xlogID对应多少个日志文件 #define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes) \ snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, \ (uint32) ((logSegNo) / XLogSegmentsPerXLogId(wal_segsz_bytes)), \ (uint32) ((logSegNo) % XLogSegmentsPerXLogId(wal_segsz_bytes))) // 名字组成 时间线(4字节8字符打印)+ ID(4字节8字符打印) + 序列号(4字节8字符打印) // ID: 可以理解成有多少个4G的数据 // 序列号: wal_size * 最大序列号 = 4G #define XLogSegmentOffset(xlogptr, wal_segsz_bytes) \ ((xlogptr) & ((wal_segsz_bytes) - 1)) // 计算lsn数据在wal日志文件中的偏移
- LSN 与 Wal日志的相关性(时间线占不考虑)
LSN:00000001(ID:4字节代表有多少个4G数据)/00000037000140(offset:4字节代表4G数据)
1/37000140数字前边补零其方便阅读理解
WAL:00000001(ID:代表多少个4G数据)00000037(日志序列号)
ID域都代表有多少个4G数据,LSN的offset根据wal_size的大小,前几位用来标识日志的序列号
-
LSN 与 Wal日志的换算
test=# select pg_walfile_name_offset('1/37000140'); pg_walfile_name_offset (000000010000000100000037,320) (1 row)
可以获取lsn对应的Wal日志信息
[CitusDB中国]站主,PostgreSQL粉丝,现从事Citus研发工作
愿Citus在中国发展的越来越好