PostgreSQL LSN 详解及转换工具
LSN 是什么
LSN (Log sequence number) ,即日志序列号。每一条 WAL 日志都需要一个编号来标识它,而 LSN 就可以看作是 WAL 日志不断自增的编号。
LSN 格式
我们使用 pg_waldump 打印一段 WAL 日志,LSN 如下图所示。
PG 的 LSN 是 64 位无符号整数。以上图中的 3D7/40ABA220
为例,将其看作二进制后,/ 左边的为高 32 位,右边的为低 32 位:
- 高 32 位:3D7
- 低 32 位:40ABA220
将其拼在一起后(3D740ABA220),对应的十进制为 4223037841952 。
LSN 格式的逻辑含义
对于计算机来说,LSN 只是一个 64 位无符号整数,而对于人来说,我们可以将其分为三部分看,了解其逻辑含义。
其逻辑格式为 XXXXXXXX/YYZZZZZZ
,以上述的 3D7/40ABA220
为例 :
- XXXXXXX:logid,对应 3D7
- YY:logseg,段号,对应 40
- ZZZZZZ:offset,该条 WAL 在对应日志段中的偏移量
logseg 和 logid 其实是进位的关系,因为 YY 对应的段号只有两位,所以当其加到 FF 后又会回到 00,此时 logid 就会 +1。
WAL 文件名
一个 WAL 文件的名字如下图所示:
timeline 在 LSN 中没有表现,而 logid 和 logseg 都与上述的 LSN 能对应起来(logseg 的前 6 位固定为 0)。
常用转换函数
PG 原生有一些常用的函数用于 LSN 的计算、转换:
- 获取当前的 LSN 值
select pg_current_wal_lsn();
- 从 LSN 计算出 WAL 文件名(注意:timeline 是根据当前实例生成的,不同实例的 timeline 字段计算结果可能不同)
select pg_walfile_name('0/157A400');
- 进制转换,将 LSN 转换成十进制,和将十进制转换成 LSN 格式:
PG 原生没有现成的函数,可参考该 github。如果无法安装插件的话,直接将pg_lsn_conversion--1.0.sql
中的创建函数语句复制到实例中执行即可。