以下是我正在做的事情:
- 我有一个 Postgres 16 docker 容器,它正在连续归档 WAL 文件
00012
在归档之后00013
,我对数据库进行了基础备份,并使用pg_basebackup
该备份生成了一个00014..backup
文件(这些是示例文件,我知道实际的 WAL 更长)- 现在我将基础备份和存档的 WAL 复制到另一个从相同 docker 镜像(包括版本)新创建的 Postgres 16 docker 容器中
- 我让
postgres
用户成为所有这些文件的所有者 - 我从基础备份目录中删除了 WAL
pg_wal
,并更新了 restore_commandpostgresql.conf
(此外,我还撤消了主服务器上的存档配置) - 我删除
00012
了00013
WAL,因为它们已经在基础备份中了,所以现在存档的 WAL 只是00014
和创建的 .backup 文件 - 我创建了一个
recovery.signal
空文件,位于数据目录中 - 最后,我将当前目录的名称更改
pgdata
为pgdata_ini
,并将备份目录更改为pgdata
,以便它充当我的数据目录 - 然后我停止容器并重新启动,但由于
invalid checkpoint record
以下原因,数据库启动失败:could not find required checkpoint record
有人能指出我在这里做错了什么吗?
事实证明,无效的检查点记录是因为两个容器的数据库系统标识符不同而发生的,我们可以通过以下方式检查
select system_identifier from pg_control_system();
现在这听起来可能很明显,但有一个小小的警告。当我们执行 PITR 时,第一步是加载基础备份,在加载此备份并将其重命名为之后
pgdata
,但在重新启动之前,标识符实际上最终与上述查询相同。(即使它实际上不是针对系统的)因此我们必须采取以下措施来解决这个问题:
pg_wal
文件、restore_command
在 conf 中更新、添加recovery.signal
等)pgdata
并重新启动容器现在,它将正确拾取存档文件并恢复最新数据,因为系统标识符实际上是相同的。它只需要使用初始基础备份额外重新启动一次。