跳到主要内容

pg_lsn 类型

pg_lsn 表示 PostgreSQL 预写式日志(WAL)中的日志序列号位置。它用于复制延迟、恢复进度、备份和 WAL 诊断,不表示业务时间,也不能替代业务事件 ID。

位置格式​

SELECT '0/16B6C50'::pg_lsn;
SELECT pg_current_wal_lsn();

文本通常写成 X/Y,两个十六进制部分共同表示 WAL 字节位置。不同服务器实例产生的 LSN 没有可直接比较的业务意义;比较前必须确认属于同一 WAL 流或同一恢复链。

比较和差值​

SELECT '0/200'::pg_lsn > '0/100'::pg_lsn;
SELECT pg_wal_lsn_diff('0/300'::pg_lsn, '0/100'::pg_lsn);

LSN 支持排序、加减和差值函数。差值通常用于估算待发送或待回放的 WAL 字节数,但不是精确的时间延迟;吞吐量、网络和回放速度仍需结合时间测量。

复制监控示例​

SELECT application_name,
client_addr,
sent_lsn,
write_lsn,
flush_lsn,
replay_lsn,
pg_wal_lsn_diff(sent_lsn, replay_lsn) AS bytes_behind
FROM pg_stat_replication;

监控视图中不同列代表发送、写入、刷盘和回放阶段。不要只看 sent_lsn,也不要把逻辑复制槽、物理复制和归档恢复的指标混为一谈。

LSN 与事务、时间​

一个事务可能产生多个 WAL 记录,LSN 反映日志位置而不是提交时间。LSN 在 WAL 回收、备份保留和复制槽管理中有生命周期约束;保留过旧 LSN 可能阻止 WAL 清理并占满磁盘。

如果需要从业务表追踪“某条数据何时同步”,应在应用或逻辑复制流程中保存业务时间、事务标识和同步状态,而不是把 pg_lsn 暴露给终端用户。

存储与接口​

可以在诊断表中保存 pg_lsn 快照:

CREATE TABLE replication_samples (
sampled_at timestamptz NOT NULL DEFAULT now(),
replay_lsn pg_lsn NOT NULL
);

跨版本、跨集群导出监控数据时,最好同时记录集群标识、时间和采样来源。不要把 LSN 当作全局递增主键或跨集群排序键。

常见误区​

  • 把 LSN 当成业务事件顺序或时间戳。
  • 比较不同数据库集群的 LSN 数字大小。
  • 只监控发送位置,不监控写入、刷盘和回放位置。
  • 长期保存复制槽或过旧 LSN,造成 WAL 无法回收。
  • 把 pg_lsn 作为公共 API 字段,泄露内部复制结构。