GBase 8c 复制槽 inactive 后 WAL 继续增长的处理方法
GBase 8c 复制槽 inactive 后 WAL 继续增长的处理方法
主库 WAL 目录连续告警、归档任务也在跑,但 pg_wal 占用仍下不来——这类现场并不少见。值班侧常先怀疑检查点过密、批处理过大或备份未转走日志;把运行日志、归档状态和 pg_replication_slots 对齐后,更常见的根因是:逻辑或物理复制槽已 inactive,槽未删除,WAL 被锚点挂住无法回收。
这与写入高峰抖动、备份恢复链路不通、数据同步延迟是不同问题线。GBase 8c 按 PostgreSQL 体系管理 WAL;复制槽会明确告诉主库下游仍需读到某个 LSN 之前的日志。槽在、消费断,磁盘占用往往单向上涨。复制槽应单独建立排查与下线流程,不宜并入通用 WAL 调参。
现象判断:先区分是不是「槽挂 WAL」
处理时建议先把现象与备份、归档、检查点拆开对照。
| 现场信号 | 建议先查 | 若命中,常见表现 |
|---|---|---|
| WAL 目录持续涨、业务写入并不猛 | pg_replication_slots |
active=f 且 restart_lsn 明显落后当前 LSN |
| 归档目录也在涨,主库 WAL 仍回收不了 | 槽类型 + 归档策略 | 逻辑槽未消费,归档无法越过槽保留点 |
| 刚停掉一条同步链路 | 槽是否仍保留 | inactive 槽未 drop,LSN 锚点不动 |
只调大 max_wal_size 暂时缓解 |
槽 lag 与 pg_wal 体积 |
参数推迟检查点,不能代替下游读日志 |
| 备库查询正常但主库 WAL 满 | 物理备库 vs 逻辑槽 | 流复制断链与逻辑解码槽排查路径不同 |
需要优先确认:当前不可回收 WAL 的下界,由哪条槽、哪个 LSN 决定。边界明确后,才谈删槽、拉消费或调参,避免误删日志或误伤在用链路。
机制说明:复制槽卡住了什么
主库每写一段 WAL 有当前 LSN;复制槽在 pg_replication_slots 记录 restart_lsn(逻辑槽还有 confirmed_flush_lsn)。槽存在期间,主库不能回收该槽仍需要的 WAL 段——消费端不前进,主库需代为保留日志。
| 槽类型 | 典型用途 | 常见断链原因 |
|---|---|---|
物理复制槽(physical) |
流复制备库、灾备拉流 | 备库长期停机、网络隔离、重建备库后旧槽未清 |
逻辑复制槽(logical) |
逻辑解码、CDC、自建消费 | 消费进程退出、订阅库删除、插件升级后未重建 |
| 无槽的临时同步 | 短时全量再追 | 一般不长期挂 WAL;与「槽挂死」分开判断 |
GBase 8c 分布式部署中,逻辑复制可能挂在 CN 或指定实例,DN 侧也有独立 WAL 目录。只盯单一节点目录,可能漏掉「槽在 A、涨在 B」。巡检建议按 实例角色 + 数据目录 + WAL 目录 记录,而不是只记集群名。
现场 SQL 示例
库名、槽名、路径按环境替换即可。
1. 查看槽状态与保留体积
SELECT
slot_name,
plugin,
slot_type,
database,
active,
pg_size_pretty(
pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)
) AS retained_on_restart_lsn,
pg_size_pretty(
pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn)
) AS retained_on_confirmed_flush,
restart_lsn,
confirmed_flush_lsn
FROM pg_replication_slots
ORDER BY slot_name;
重点关注 active = false 且 retained_on_restart_lsn 已达数十 GB 以上的行。inactive 仅表示无会话连接,不表示 WAL 可立即回收。
2. 当前 WAL 与归档
SELECT
pg_current_wal_lsn() AS current_lsn,
pg_walfile_name(pg_current_wal_lsn()) AS current_wal_file;
SELECT
archived_count,
last_archived_wal,
last_archived_time,
failed_count,
last_failed_wal,
last_failed_time
FROM pg_stat_archiver;
pg_stat_archiver 正常而 OS 层 pg_wal 仍涨时,应优先查复制槽,而不是先改检查点参数。
3. 逻辑订阅与流复制状态
SELECT subname, subenabled, subconninfo
FROM pg_subscription;
SELECT
pid, usename, application_name, client_addr, state,
sent_lsn, write_lsn, flush_lsn, replay_lsn
FROM pg_stat_replication;
订阅禁用或消费进程消失、发布端槽仍在,是较常见的「静默挂 WAL」组合。
4. 确认无依赖后删除槽
-- 须完成变更审批,确认下游不再从该 LSN 追读
SELECT pg_drop_replication_slot('cdc_order_slot_02');
短暂故障可先恢复消费,推动 confirmed_flush_lsn 前进;确认僵尸槽后再 drop。
相关参数(与检查点问题区分)
| 参数 / 对象 | 作用 | 适用场景 | 注意 |
|---|---|---|---|
max_slot_wal_keep_size |
限制单槽可保留 WAL 上限 | 防止单槽拖满磁盘 | 超限后槽可能失效,下游是否接受跳点需评估 |
wal_keep_size |
备库断连时主库额外保留 WAL | 物理备库短时离线 | 不替代逻辑槽消费 |
max_wal_size |
触发检查点的 WAL 阈值 | 写入与检查点频率 | 不能解决「槽阻止删文件」 |
archive_mode / archive_command |
WAL 归档 | PITR、跨机房 | 归档成功 ≠ pg_wal 可删 |
pg_replication_slots |
槽状态来源 | WAL 只涨不跌 | inactive 槽仍占保留位 |
多次因槽撑满磁盘时,可在变更窗口评估 max_slot_wal_keep_size,但不宜把它当作日常不清理 inactive 槽的替代。该参数更接近熔断,不是槽生命周期管理。
推荐处理顺序
1. 对齐告警时间线:是否伴随停同步、发版、删订阅库
2. 查 pg_replication_slots:inactive 槽、lag 体积、槽类型
3. 查 pg_stat_replication / pg_subscription:消费端是否存在
4. 可恢复则先拉起消费,观察 confirmed_flush_lsn 是否前进
5. 确认无业务依赖后 drop 僵尸槽,或重建订阅与新槽
6. 观察 pg_wal 是否回落;仍涨则排查是否还有其他槽
7. 固化:槽命名、负责人、下线 checklist、容量与 lag 监控
典型场景:测试库订阅生产发布端,测试下线后槽仍留在生产 CN;业务批量不大,WAL 仍按固定速率上涨。drop 测试槽后,目录常在数个检查点周期内明显下降。槽名建议带 业务前缀 + 环境标识;下线流程写死「停订阅 → 确认 lag → drop 槽」。
主机侧核对
du -sh /data/gbase8c/dn01/pg_wal
ls -lh /data/gbase8c/dn01/pg_wal | tail -20
du -sh /arch/gbase8c/wal/dn01
对每个仍承担写入或复制职责的实例分别检查,避免只查 CN 而漏掉 DN 上的逻辑槽。
常见误区
| 误区 | 后果 | 建议 |
|---|---|---|
| inactive 槽无影响 | WAL 持续保留 | inactive 槽纳入日巡检 |
归档正常即可手工删 pg_wal |
破坏恢复或解码 | 禁止手工删 WAL;先查槽 |
| 停订阅不 drop 槽 | LSN 锚点不动 | 下线:停消费 → 确认 lag → drop |
先调大 max_wal_size 腾空间 |
根因仍在 | 先处理槽再评估参数 |
| 重建备库不清理旧物理槽 | 双倍保留 | 重建前后核对槽名 |
| 只监控目录总大小 | 无法定位槽 | 定期采集 pg_replication_slots |
逻辑槽绑定 database 与 plugin;插件升级或发布端重建后,旧槽位点未迁移时,下游可能从很老 LSN 重读,主库再次囤积 WAL。发版说明应写明槽是 保留、迁移还是重建。
日常治理要点
- 建槽即登记:槽名、用途、负责人、下游系统、预计周期。
- 监控
active与各槽 lag 体积,与目录空间告警分开配置。 - 测试订阅生产时槽名带环境后缀;测试下线模板含 drop 槽步骤。
- CDC 消费端配置 lag/心跳告警。
- drop 槽前书面确认下游能否全量重拉;逻辑位点丢失成本需提前说明。
小结
GBase 8c 的 WAL 保证崩溃恢复与复制一致性;复制槽把「下游还需读到哪」写入目录元数据。槽在、消费不在,主库只能保留日志——排查路径与慢 SQL、锁等待、检查点抖动不同。
实操上先看 pg_replication_slots,对齐 inactive 槽与 lag 体积,再决定恢复消费、重建链路或审批后 drop 僵尸槽。参数可作辅助,不能替代槽的登记、巡检与下线。把槽按与表、索引同级对象管理,可在磁盘打满前定位到具体责任槽。
参考资料
[1] GBase 8c 日志参考
https://www.gbase.cn/docs/gbase-8c/02%20%E7%AE%A1%E7%90%86%E5%91%98%E6%8C%87%E5%8D%97/03%20%E8%BF%90%E7%BB%B4%E7%AE%A1%E7%90%86/%E6%97%A5%E5%BF%97%E5%8F%82%E8%80%83
[2] GBase 8c 管理员指南
https://www.gbase.cn/docs/gbase-8c/02%20%E7%AE%A1%E7%90%86%E5%91%98%E6%8C%87%E5%8D%97
[3] GBase 8c 产品文档
https://www.gbase.cn/docs/gbase-8c/%E6%AC%A2%E8%BF%8E/
[4] PostgreSQL 复制槽说明
https://www.postgresql.org/docs/current/warm-standby.html#STREAMING-REPLICATION-SLOTS
评论
热门帖子
- 12025-12-01浏览数:183265
- 22023-05-09浏览数:26036
- 42023-09-25浏览数:19689
- 52020-05-11浏览数:18321