You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL主库未归档WAL文件恢复及主备集群崩溃数据恢复问询

嘿,作为常年和PostgreSQL主备集群打交道的老玩家,我来一步步帮你搞定这两个问题,都是生产环境里很常见的崩溃恢复场景~

1. 如何恢复主库正在写入但尚未归档的当前WAL文件?

主库崩溃时,正在写入的WAL文件(也就是pg_wal目录里current链接指向的那个)通常还没触发归档——因为PostgreSQL只有在WAL segment写满切换时才会执行archive_command。要恢复这个文件,按以下步骤来:

  • 第一步:停稳主库,别乱碰
    先确保主库已经彻底停止运行,绝对不要贸然重启,否则可能会覆盖损坏的WAL文件,把最后一丝恢复机会搞没。

  • 第二步:定位目标WAL文件
    进入主库的数据目录下的pg_wal子目录,执行:

    ls -l current
    

    你会看到类似这样的输出:

    current -> 000000010000000000000005
    

    箭头后面的000000010000000000000005就是正在写入的未归档WAL文件。

  • 第三步:手动归档这个文件
    按照你主库的archive_command逻辑,把这个文件复制到归档目录(你的归档目录是/data):

    test ! -f /data/000000010000000000000005 && cp /path/to/main/pg_wal/000000010000000000000005 /data/
    

    要是主库的数据目录还能正常访问,直接这么操作就行;如果数据目录损坏但磁盘还能读,就从磁盘的原始路径里找到这个文件复制过去。

  • 最坏情况:磁盘彻底损坏
    如果主库磁盘完全挂了,这个未归档的WAL就没法恢复了,你只能恢复到最后一个已归档WAL的位置,这部分未归档的数据会丢失。

2. 备库离线后主库崩溃:从归档恢复数据 + 获取最后一个WAL文件

结合你的场景(主库开了归档,备库用了复制槽),分两部分解答:

2.1 如何从归档WAL恢复数据?

这里分两种常见情况:

情况A:备库还存活,只是离线

你可以把备库恢复到主库崩溃前的状态,然后提升为主库:

  1. 检查备库的恢复配置
    确保备库的restore_command(PG12+是在postgresql.conf里配置,旧版本是recovery.conf)指向你的归档目录:

    restore_command = 'cp /data/%f %p'
    

    同时确认recovery_target = 'latest'(默认就是这个值,会恢复到最新的可用WAL位置)。

  2. 补上未归档的WAL
    把刚才第一步找到的主库未归档WAL文件复制到/data归档目录里。

  3. 启动备库并提升
    启动备库:

    pg_ctl start -D /path/to/standby/data
    

    备库会自动从归档里拉取WAL进行恢复,直到没有更多WAL可用。恢复完成后,执行提升命令让它成为可读写的主库:

    pg_ctl promote -D /path/to/standby/data
    

情况B:备库也挂了,需要从归档新建主库

这种情况需要你有主库的基础备份(如果没有的话,只能从初始化状态恢复,数据损失会很大):

  1. 解压基础备份到新目录
    把你之前做的基础备份(比如用pg_basebackup生成的)解压到一个新的数据目录。

  2. 配置恢复参数

    • PG12及以上:修改新目录下的postgresql.conf,添加:
      restore_command = 'cp /data/%f %p'
      recovery_target = 'latest'
      recovery_target_action = 'promote'  # 恢复完成后自动提升为主库
      
    • PG11及以下:在新目录创建recovery.conf,写入:
      restore_command = 'cp /data/%f %p'
      recovery_target = 'latest'
      trigger_file = '/tmp/promote_me'
      
  3. 补上未归档WAL
    同样把主库崩溃前的未归档WAL复制到/data归档目录。

  4. 启动新实例
    启动PostgreSQL,它会先恢复基础备份,然后自动从归档拉取所有WAL进行恢复,最后提升为可读写的主库。

2.2 如何获取主库崩溃前正在写入的最后一个WAL文件?

有几种可靠的方法:

  • 方法1:查看pg_wal的current链接
    这是最直接的方式,进入主库pg_wal目录,执行:

    ls -l $PGDATA/pg_wal/current
    

    输出里箭头指向的文件名就是最后一个正在写入的WAL。

  • 方法2:如果主库能启动到只读模式
    要是主库没彻底坏,能启动到只读状态,连接进去执行SQL:

    SELECT pg_walfile_name(pg_current_wal_lsn());
    

    结果就是当前的WAL文件名。

  • 方法3:从归档目录推断
    查看归档目录/data里的WAL文件,按文件名排序(PG的WAL文件名是按LSN递增的),最大的那个是最后一个已归档的WAL,主库的最后一个WAL就是它的下一个编号(比如归档里最大的是000000010000000000000009,那主库的就是00000001000000000000000A)。

  • 方法4:扫描磁盘上的pg_wal文件
    如果主库数据目录损坏但磁盘可读,直接查看pg_wal目录下的所有文件,按修改时间排序,最新的那个(排除临时文件)就是目标WAL。


内容的提问来源于stack exchange,提问作者Mohamed Adel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:18:32