用心打造
VPS知识分享网站

PostgreSQL WAL持续增长怎么办?复制槽与归档处理方法

PostgreSQL数据目录中的 pg_wal 越来越大,磁盘告警却迟迟不回落,通常不是普通日志轮转失效。WAL承担崩溃恢复、归档和复制,系统只有在确认旧段不再需要后才能回收或复用。

不要直接删除pg_wal中的文件。 正确做法是找出谁在保留WAL,恢复对应的归档或复制消费者,再决定是否调整上限或移除已经废弃的复制槽。

WAL持续增长

先确认磁盘与WAL增长速度

从系统和数据库两侧采集当前状态:

df -h /var/lib/postgresql
sudo du -sh /var/lib/postgresql/*/main/pg_wal

实际数据目录可通过SQL确认:

SHOW data_directory;
SELECT pg_size_pretty(sum(size)) AS wal_size
FROM pg_ls_waldir();

同时记录5至10分钟内的增长量和磁盘剩余时间。若空间只够支撑很短时间,应先暂停非关键批量写入、扩展磁盘或准备受控停机窗口。先保住数据库可写空间,再进行原因处理。

理解WAL为什么不能随意清理

WAL记录数据页变化,数据库恢复、物理备库、逻辑订阅和时间点恢复都可能依赖它。max_wal_size 是触发检查点和控制常规WAL体量的重要参数,但并不是绝对磁盘硬上限。

复制槽、wal_keep_size、未完成归档和长时间备份都可能要求保留更多WAL。看到超过max_wal_size并不等于参数失效,应继续查实际保留者。

直接删除文件会破坏恢复链,轻则导致备库无法继续,重则让主库重启后无法恢复一致状态。

检查复制槽是否滞后

读取所有槽的活动状态与保留量:

SELECT slot_name,
       slot_type,
       active,
       restart_lsn,
       confirmed_flush_lsn,
       wal_status,
       pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained
FROM pg_replication_slots
ORDER BY pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) DESC NULLS LAST;

active=false 且保留量持续增长,通常说明对应备库、CDC或逻辑订阅已停止消费。也要确认槽是否仍属于有效业务,不能看到非活动就删除。

restart_lsn越旧,主库为该槽保留的WAL通常越多。 新版PostgreSQL还可结合 wal_status 判断槽所需文件处于保留、扩展或即将丢失等状态。

核对物理备库与发送进程

在主库查看在线复制连接:

SELECT application_name,
       client_addr,
       state,
       sync_state,
       sent_lsn,
       write_lsn,
       flush_lsn,
       replay_lsn,
       pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn)) AS replay_lag_bytes
FROM pg_stat_replication;

若槽存在但没有对应连接,检查备库服务、网络、证书和连接串。若连接存在但 replay_lsn 长时间不动,应在备库检查磁盘、恢复冲突和PostgreSQL日志。

恢复备库消费比删除槽更安全。 一旦删除仍有用途的物理槽,主库可能回收备库尚未接收的WAL,最终只能重建备库。

检查归档命令是否失败

启用归档时,查询统计信息:

SELECT archived_count,
       failed_count,
       last_archived_wal,
       last_archived_time,
       last_failed_wal,
       last_failed_time
FROM pg_stat_archiver;

再检查参数:

SHOW archive_mode;
SHOW archive_command;

失败次数增加、最后成功时间停滞,说明归档目标不可写、空间不足、命令权限错误或网络存储异常。修复后应让归档程序继续处理积压,而不是手工把文件从 pg_wal 搬走。

归档是否成功必须以pg_stat_archiver和目标端文件共同确认。 只看到命令返回过0,不能证明后续文件持续可用。

判断是否为写入突增和检查点压力

没有异常槽或归档失败时,检查近期是否发生批量导入、大表更新、索引重建或全量维护。可以观察WAL生成差值:

SELECT pg_current_wal_lsn();
SELECT checkpoints_timed,
       checkpoints_req,
       checkpoint_write_time,
       buffers_checkpoint
FROM pg_stat_bgwriter;

隔一段时间再次读取LSN,使用 pg_wal_lsn_diff() 计算生成量。高写入本身会产生大量WAL,频繁检查点还可能增加I/O压力。

先治理异常写入和任务并发,再考虑扩大参数。 单纯增加磁盘或 max_wal_size 只能延后告警,不能消除失控的消费者。

安全处理已经废弃的复制槽

删除前必须确认槽对应的备库、订阅或CDC任务已经永久下线,并保存槽名、LSN和负责人记录。逻辑复制槽还要确认下游不再需要未消费变更。

确认废弃后执行:

SELECT pg_drop_replication_slot('old_slot_name');

活动槽不能直接删除,应先在消费者侧停止并确认连接释放。删除复制槽是不可逆的保留边界变更,不是临时释放空间按钮。 删除后等待检查点和回收过程,不要期待目录大小瞬间下降。

用上限控制复制槽风险

PostgreSQL提供 max_slot_wal_keep_size,用于限制复制槽在检查点时允许保留的WAL量。默认值 -1 表示槽可能无限保留;设置非负值后,过度滞后的槽可能失去继续复制所需的文件。

SHOW max_slot_wal_keep_size;

这个参数是保护主库磁盘的保险丝,代价是消费者落后过多时需要重建。数值应覆盖可接受的最大断连时间乘以峰值WAL生成速率,并留出缓冲。

萤光云LightNode 上搭建同版本短期环境,可以演练槽滞后与重建流程。不要把生产备份、证书或真实业务数据直接复制到测试实例。

空间紧急时的处置顺序

磁盘逼近100%时,先停止造成异常WAL的大批量任务,确认可扩容后在线增加空间,并修复归档或消费者。无法及时扩容时,应评估暂停写入,以避免数据库在不可控时刻失败。

可以清理数据目录之外已确认无关的系统日志或临时文件,但不要触碰 pg_wal、控制文件和数据文件。宁可受控限制写入,也不要用手工删WAL换取几分钟空间。

若主库已经停机,应保留现场并从可验证备份制定恢复方案,不要反复启动和删除文件。

修复后的完整验收

重复查询 pg_replication_slotspg_stat_replicationpg_stat_archiver,确认保留量开始下降、复制LSN持续前进、归档成功时间更新。系统侧确认磁盘空闲量稳定回升。

至少观察一个业务峰值周期,记录每小时WAL生成量、最大槽滞后和归档失败数。验收标准是保留者明确、消费者恢复、增长斜率回归预期,并且告警阈值早于磁盘耗尽时间。

常见问题

可以直接删除pg_wal里最旧的文件吗?

不可以。文件可能仍被崩溃恢复、复制或归档需要,手工删除可能使数据库和备库无法恢复。

max_wal_size为什么限制不住目录大小?

它不是绝对硬上限。复制槽、归档、wal_keep_size 和写入峰值都可能让实际目录更大。

非活动复制槽都能删除吗?

不能。非活动只表示当前没有消费者连接,还需确认该槽已经永久废弃且允许丢失未消费WAL。

温馨提示

任何删除槽或更改WAL保留参数的操作都应先验证备份,并通知备库或CDC负责人。把磁盘剩余时间、WAL增长速度和重建成本一起纳入决策,才能避免从容量故障变成数据恢复事故。

赞(0)
未经允许不得转载;国外VPS测评网 » PostgreSQL WAL持续增长怎么办?复制槽与归档处理方法
分享到