PostgreSQL 中 pg_wal 目录里的 .ready .done .history 文件的生命周期

说明: 本文基于GPT回答生成


文章目录

PostgreSQL 中 pg_wal 目录里的 .ready / .done / .history 分别是干什么的?

你这个问题非常偏运维,而且和归档(archive_mode)强相关,正好也很容易被误删。

下面我按你关心的几个点,一次讲清楚:

  • 是干啥的
  • 一般多大
  • 里面内容长什么样
  • 什么时候产生
  • 什么时候自动删除
  • 什么时候会残留
  • 什么时候可以手工删

先给你一张总览表(后面逐个展开):

文件类型 所在目录 作用
00000001000000000000005A.ready pg_wal/archive_status 表示:这个 WAL 等待归档
00000001000000000000005A.done pg_wal/archive_status 表示:这个 WAL 已归档
00000002.history pg_wal 时间线历史文件

注意:

👉 .ready / .done 不在 pg_wal 目录本身

👉 在:

复制代码
pg_wal/archive_status/

下面正式拆开讲。


一、xxx.ready 是干什么的?

位置

复制代码
$PGDATA/pg_wal/archive_status/

例如:

复制代码
00000001000000000000005A.ready

作用一句话说明

这个 WAL 段文件,已经写完了,正在等待 archive_command 去归档。


什么时候产生?

当:

  • 你开启了
conf 复制代码
archive_mode = on

并且:

  • 某一个 WAL 段文件切换完成时

PostgreSQL 会:

  1. 在 pg_wal 里生成 WAL 文件

  2. 同时在

    pg_wal/archive_status

里生成一个同名的:

复制代码
.ready

文件


举例

生成的 WAL 文件:

复制代码
pg_wal/00000001000000000000005A

对应就会有:

复制代码
pg_wal/archive_status/00000001000000000000005A.ready

这个文件里内容是啥?

👉 基本是空文件

一般是 0 字节。

你可以理解为:

只是一个标志文件


一般大小是多少?

通常:

复制代码
0 字节

什么时候会变成 done?

当你的:

conf 复制代码
archive_command

返回 0(成功)后:

PostgreSQL 会:

  • 删除 .ready

  • 创建:

    .done



二、xxx.done 是干什么的?

位置

同样在:

复制代码
pg_wal/archive_status/

例如:

复制代码
00000001000000000000005A.done

作用一句话说明

这个 WAL 文件已经被成功归档过了。


什么时候产生?

当:

复制代码
archive_command 执行成功

PostgreSQL 就会创建:

复制代码
.done

里面内容是啥?

👉 也是空文件

一般是 0 字节。


一般大小?

同样:

复制代码
0 字节

.done 什么时候删除?

注意这个点:

👉 PostgreSQL 并不会马上删 .done

.done 的清理由内部机制处理,通常是在:

  • WAL 文件被回收/删除之后
  • 或者 checkpoint 相关流程中

最终会被清掉。



三、.ready 和 .done 的完整生命周期

最典型流程是:

复制代码
WAL 切换完成
   ↓
生成 xxx.ready
   ↓
archive_command 成功
   ↓
删除 xxx.ready
生成 xxx.done
   ↓
后续回收时清理 xxx.done


四、xxx.history 是干什么的?

这个完全是另一类文件。


位置

直接在:

复制代码
pg_wal/

比如:

复制代码
00000002.history

作用一句话说明

记录时间线(timeline)切换历史,用于恢复和主备切换。


什么时候产生?

只有在发生:

👉 时间线切换

才会生成。

典型场景:

  • 从备库提升为主库(promote)
  • 做时间点恢复(PITR)
  • restore_command 恢复到新的 timeline

举例

比如你原来 timeline 是:

复制代码
00000001

提升备库后:

新 timeline 变成:

复制代码
00000002

那么就会生成:

复制代码
00000002.history

这个文件里面内容一般长什么样?

内容是文本。

类似这样:

复制代码
1    0/16B6C50    no recovery target specified

格式大概是:

复制代码
父时间线ID    切换LSN    说明

一般多大?

非常小。

一般:

  • 几十字节
  • 几百字节


五、什么时候会自动删除?

1️⃣ xxx.ready

👉 正常情况下:

  • archive_command 成功后
  • 立刻被删掉

2️⃣ xxx.done

👉 会在 WAL 回收时被清理

但这个不是强实时的。


3️⃣ xxx.history

👉 默认不会自动删除。

这是设计行为。



六、什么时候会残留?

这个问题在生产中非常常见。


(一)大量 .ready 残留

最常见原因只有一个:

👉 archive_command 一直失败

比如:

结果是:

复制代码
.ready 一直存在
.done 不生成

你会看到:

复制代码
pg_wal/archive_status/
  xxxx.ready
  yyyy.ready
  zzzz.ready

不断堆积。



(二).done 很多

这种一般不是故障。

只是:

  • WAL 还没被回收
  • 或 checkpoint 周期还没触发到清理点


(三).history 文件残留

这是正常现象。

只要发生过:

  • promote
  • PITR
  • 时间线切换

就会留下 history 文件。



七、什么时候可以手动删除?

这个非常重要,我给你直接分结论。


❌ 千万不要手工删除 .ready

原因很简单:

你删了:

复制代码
xxx.ready

PostgreSQL 就认为:

👉 这个 WAL 不需要归档了

而实际上:

👉 归档可能还没成功

会直接破坏归档链。



⚠️ 一般也不建议手工删除 .done

除非:

你非常明确:

  • 这个实例不再使用归档
  • 或你要重建环境


⚠️ history 文件能不能删?

结论:

👉 不建议删

特别是以下场景:

  • 你有:

    • 归档
    • 备库
    • PITR 需求

history 是恢复链的重要组成部分。



八、什么时候是"可以安全清理"的场景?

只有在以下场景中,才可以考虑手工清理这些文件:


场景 1:这个库已经不做归档、不做恢复

比如:

  • archive_mode 已关闭
  • 不存在备库
  • 不会再做 PITR
  • 是一个纯单机实例

那么:

.done.history 对你基本没有意义。


但即便如此:

👉 正确做法也不是手工删文件

而是:

  • 让 PostgreSQL 自己管理
  • 或重建集群


九、和你当前运维场景最相关的一个风险点

你前面一直在做:

  • 巡检
  • 清理
  • 自动化脚本

我非常明确地提醒你一句:

👉 不要把:

复制代码
pg_wal/archive_status

加入任何自动清理脚本。

尤其不要写:

bash 复制代码
find pg_wal -name "*.ready" -delete

这是非常危险的。



十、你可以用来巡检的一条非常实用的 SQL

你可以用这个来判断归档是否堆积:

sql 复制代码
select
  count(*) filter (where status = 'ready') as ready_cnt,
  count(*) filter (where status = 'done')  as done_cnt
from pg_stat_archiver;

不过更推荐的是:

sql 复制代码
select *
from pg_stat_archiver;

你重点看:

  • last_failed_wal
  • last_failed_time
  • failed_count


十一、结合你的环境,我给你一个非常实用的判断建议

你现在的场景是:

  • 单机 PostgreSQL
  • 以稳定运维为主
  • 很多自动巡检脚本

我建议你加一个规则:

如果:

复制代码
archive_mode = on

并且:

复制代码
pg_wal/archive_status/*.ready 数量 > 0
并持续增长

基本可以直接报警:

👉 归档通道已经异常。



十二、最后给你一版"DBA速记版总结"

ready

👉 等待归档

👉 0 字节

👉 archive_command 成功前存在

👉 失败会大量堆积

👉 不能删


done

👉 已完成归档

👉 0 字节

👉 后续会被清理

👉 不建议人工干预


history

👉 时间线切换历史

👉 文本文件

👉 非常小

👉 用于恢复链

👉 不建议删除

相关推荐
陌上丨12 小时前
Redis的Key和Value的设计原则有哪些?
数据库·redis·缓存
AI_567812 小时前
AWS EC2新手入门:6步带你从零启动实例
大数据·数据库·人工智能·机器学习·aws
ccecw12 小时前
Mysql ONLY_FULL_GROUP_BY模式详解、group by非查询字段报错
数据库·mysql
JH307312 小时前
达梦数据库与MySQL的核心差异解析:从特性到实践
数据库·mysql
数据知道13 小时前
PostgreSQL 核心原理:如何利用多核 CPU 加速大数据量扫描(并行查询)
数据库·postgresql
麦聪聊数据14 小时前
Web 原生架构如何重塑企业级数据库协作流?
数据库·sql·低代码·架构
未来之窗软件服务14 小时前
数据库优化提速(四)新加坡房产系统开发数据库表结构—仙盟创梦IDE
数据库·数据库优化·计算机软考
Goat恶霸詹姆斯15 小时前
mysql常用语句
数据库·mysql·oracle
大模型玩家七七16 小时前
梯度累积真的省显存吗?它换走的是什么成本
java·javascript·数据库·人工智能·深度学习