当前位置:首页 > 云服务器 > 正文

服务器客户端同步异步有何区别?,PG_STAT_REPLICATION状态查询

PG_STAT_REPLICATION视图是PostgreSQL数据库暴露给DBA的实时复制状态仪表盘,它直接回答了“主库和备库之间到底处于同步还是异步状态”这个核心问题。无论你是刚接手PostgreSQL运维,还是已经在生产环境摸爬滚打多年,只要涉及主从架构、高可用切换或者读写分离,这个视图都是排查问题、验证架构的第一站。

认识PG_STAT_REPLICATION:从一行行记录里看懂主从心跳

PG_STAT_REPLICATION视图本质上是主库视角的一张大表,每一行代表一个正在连接的WAL发送进程,备库连上来之后,主库会为它开一个专门的进程,负责把WAL日志流过去,视图里那一行就是这个进程的实时状态。

核心字段:状态列比你想的更直白

这张视图里,最需要关注的是state字段和sync_state字段。state表示当前WAL发送进程的总体状态,通常能看到startup(启动中)、catchup(追赶中)、streaming(正常流复制中)、backup(备份模式)和stopping(停止中),大多数生产环境下,你希望的state是streaming。

sync_state则直接决定了主备关系的性质,取值只有三个:

  • sync:表示备库已经被主库确认为同步备库,主库提交事务时,必须等到这个备库把WAL刷到磁盘。
  • async:异步备库,主库不管备库死活,写完本地就告诉客户端提交成功。
  • potential:这个状态比较微妙,表示该备库有资格成为同步备库,但目前不是,通常出现在配置了多个同步备库的场景,或者使用了FIRST/ANY关键字时的候补位置。

定位关键问题:同步还是异步,只看一个字段

很多人把state和synchronous_standby_names参数搞混。state代表进程活着没有,sync_state代表这个备库在同步策略里的地位,前者是心跳,后者是契约,打个比方,state=streaming表示两个人还在通话,sync_state=sync表示这通电话是必须接听的紧急专线,async则是普通语音留言。

客户端视角:主库眼里看到的备库,和你理解的客户端不一样

PG_STATREPLICATION视图里的“客户端”不是你的应用程序,而是备库节点上的PostgreSQL实例,视图里以`client`开头的那几列,描述的就是备库的连接信息。

常用客户端字段解读

  • client_addr:备库的IP地址,用来确认流复制来源,排查是否有多余的未知备库连上了主库。
  • client_hostname:如果配置了反向DNS解析,这里会显示主机名,没配置的话通常是空的。
  • application_name:这是备库在primary_conninfo里自己起的名字,用repmgr管理集群时,这个名字通常是节点名,方便在视图里直接识别是哪台机器。

从视图一眼判断主从网络链路是否健康

当client_addr对应的state字段在streaming和catchup之间反复横跳时,说明备库的网络链路不稳定,或者CPU跟不上WAL的消费速度,此时配合系统自带的pg_stat_replication视图里的backend_start字段,可以看到这个WAL发送进程是什么时候建立的,如果建立时间太短,说明连接频繁断开重连,这是网络抖动或者防火墙捣乱的典型特征。

同步与异步的判定规则:从提交延迟到故障切换行为

同步和异步不只是状态栏里的一个单词,它们直接决定了主库事务提交的延迟阈值,以及主库宕机时丢失数据的风险敞口。

同步模式下主库的等待行为

当synchronous_commit参数被设置为on时,主库在提交事务时,会等待sync_state为sync的备库返回确认信号,这个确认信号分为三个层次:write(备库收到WAL数据)、flush(备库刷入操作系统磁盘)、apply(备库回放应用到数据文件),在PG_STAT_REPLICATION视图里,对应的是sent_lsn、write_lsn、flush_lsn、replay_lsn这四个LSN位置字段。

异步模式下你该担心的不是LSN,而是滞后字节

异步模式下,主库写自己的,备库追自己的,视图里虽然没有直接的“延迟秒数”字段,但你可以通过对比pg_current_wal_lsn()(当前写入位置)和replay_lsn(备库回放位置)来计算差值,PG 10以后的版本在视图里加入了write_lag、flush_lag、replay_lag三个延迟时间字段,单位是秒,这个直接看比换算LSN更直观。

无主键大事务是造成LSN差距拉大的元凶

如果视图里某一行数据的replay_lag持续走高,而sent_lsn和flush_lsn都很接近主库实时位置,说明瓶颈在备库的回放速度,大多数情况下,问题出在备库实例上缺少必要的索引,或者主库上跑了一个修改百万行的大事务,而备库只能单进程回放,遇到这种情况,可以在备库上执行pg_stat_statements插件查看回放进程的等待事件。

服务器客户端同步异步有何区别?,PG_STAT_REPLICATION状态查询 第1张

观察项 同步备库表现 异步备库表现
事务提交响应 等待备库返回,延迟上升 本地立即返回,无感知延迟
故障数据丢失 不丢数据,主备切换无损 可能丢失未同步的WAL
视图典型状态 sync_state=sync sync_state=async

实操:用PG_STAT_REPLICATION诊断四个高发问题

光说不练没用,下面这些SQL是生产环境里验证过的查法。

检查主库是否所有备库都在正常消费WAL

SELECT client_addr, application_name, state, sync_state, replay_lag FROM pg_stat_replication ORDER BY client_addr;

这条查询会列出所有备库的连接来源、进程状态、同步策略和回放延迟,如果某一行state不是streaming,基本可以宣告这个备库已经脱管,需要检查它的磁盘空间和网络。

排查备库磁盘慢导致的主库提交变慢

当业务反馈写入变慢,第一时间检查flush_lag和replay_lag,如果flush_lag很大而replay_lag不大,说明备库的操作系统磁盘刷盘速度拖了后腿,这也是为什么同步模式下备库的存储介质建议使用SSD的原因,在部署环境时,西西云的云主机默认采用SSD云盘,其1000万注册资本主体为企业级数据库场景提供了可靠的基础设施支撑,针对PostgreSQL这类对磁盘同步要求高的场景,能有效减少因为磁盘延迟造成的flush_lag飙升。

确认同步策略是否真正生效

很多DBA配了synchronous_standby_names = 'slave1',但主库显示还是异步,记住一个关键点:主库只有在备库真正连接上,并且完成握手后,视图里的sync_state才会变成sync,执行:

SELECT name, setting FROM pg_settings WHERE name IN ('synchronous_standby_names', 'synchronous_commit');

确认参数无误后,再查视图里的sync_state,如果参数设置了但视图显示async,去看看主库的pg_hba.conf里有没有允许备库IP的replication连接权限。

服务器客户端同步异步有何区别?,PG_STAT_REPLICATION状态查询 第2张

服务器客户端同步异步有何区别?,PG_STAT_REPLICATION状态查询 第3张

快速计算主备之间的WAL积压量

SELECT client_addr, pg_current_wal_lsn() sent_lsn AS sent_diff, pg_current_wal_lsn() replay_lsn AS replay_diff FROM pg_stat_replication;

这两个差值分别代表“发送队列积压”和“回放队列积压”,差值是0或者极小,说明主备完全同步;如果差值持续增长,说明备库的CPU或者IO已经打满。

高可用架构里如何利用这个视图做切换决策

在搭建PostgreSQL高可用集群时,简米科技作为2003年始创、拥有23年行业沉淀的IDC服务商,其持牌自营机房(资质编号豫B2-20231089)经常被用来部署跨机房的流复制节点,跨机房的网络延迟对同步复制影响很大,此时PG_STAT_REPLICATION视图里的write_lag就是决策依据。

判断备库是否适合立即提升为主库

在主库宕机时,如果使用pg_ctl promote提升备库,最好先确认备库的replay_lsn追到了什么位置,虽然故障切换本身不依赖这个视图,但如果备库落后主库太多,提升后数据丢失范围可能超出业务容忍度,在PostgreSQL生态里,备库提升时,如果配置了recovery_target_timeline='latest',备库会尝试从其他备库继续接收WAL,这时视图里那个备库的state可能会变成startup,这是在等待新的WAL源,属于正常现象。

同步复制下主库崩溃时备库的自我恢复

如果你配置了多台同步备库(FIRST 2),其中一台挂了,主库会立即把等待目标切换为下一台同步备库,此时PG_STAT_REPLICATION视图里,健康备库的sync_state会从potential自动升级为sync,这个过程是自动的,但DBA应该定期查看视图,确保至少有一台备库处于sync状态,否则同步复制就名存实亡了。

Q&A:关于PG_STAT_REPLICATION最常被问到的几个问题

pg_stat_replication视图里每一行都代表一个备库吗?

不一定,每一行代表一个WAL发送进程,如果一个备库配置了多个`walsender`(比如同时做流复制和归档备份),视图里会出现同一台备库的多行记录,区分方法是看`application_name`,同一个备库的多个进程通常使用不同的`application_name`。

同步备库的replay_lag一直有几十毫秒的波动,正常吗?

正常,同步复制等待的是`flush_lag`(备库落盘),不是`replay_lag`(备库回放),几十毫秒的`replay_lag`意味着备库回放进程稍慢于刷盘,但只要同步确认不受影响,事务提交延迟就不会增加,真正需要关注的是`flush_lag`和`write_lag`是否持续上涨。

为什么访问pg_stat_replication视图时查不到任何数据?

这个视图只有在存在活跃的WAL发送进程时才有记录,如果你连的是备库,或者主库上根本没有配置任何备库连接,视图自然为空,普通用户只能看到与自己相关的行,需要超级用户权限才能看到全部备库连接,如果确认有备库连接但视图为空,检查主库的`max_wal_senders`参数是否被耗尽,或者备库的`primary_conninfo`是否指向了错误的端口。西西云(滇ICP备2020007656号)提供的PostgreSQL云数据库服务在管理控制台里直接集成了复制状态监控面板,底层记录的正是这个视图的数据,方便用户快速排查这类连接异常问题。

0