PostgreSQL错误 PANIC: 找不到有效的检查点记录。

120
当我加载postgres服务器(v9.0.1)时,出现了一种崩溃,导致它无法启动:

紧急情况:找不到有效的检查点记录

我该如何解决这个问题?


1
请不要在问题本身中发布解决方案。回答自己的问题并不被反对,但您应该将解决方案作为答案发布。这次我已经从问题中编辑了解决方案。请随时在答案中发布它。 - Adam Lear
3
我很好奇安娜编辑掉之前的答案是什么 :-) - filiprem
如果这是在从服务器/只读服务器上,并且您在复制基本备份后启动,请确保您在本地数据文件夹中拥有创建基本备份时创建的标签文件。 - Daniel Gee
11个回答

178

Postgres正在事务日志中寻找一个可能不存在或损坏的检查点记录。

在继续之前,你必须知道下面的操作如果运气不好可能会让情况变得更糟。根据《PostgreSQL关于pg_resetwal的文档》pg_resetwal可能会使你的数据库处于不确定状态:

如果pg_resetwal报错无法确定pg_control的有效数据,您可以通过指定-f(强制)选项来强制继续。在这种情况下,将使用合理的值替代缺失的数据。大多数字段可以预期匹配,但可能需要手动协助设置下一个OID、下一个事务ID和时代、下一个多事务ID和偏移量以及WAL起始位置字段。可以使用下面讨论的选项来设置这些字段。如果无法确定所有这些字段的正确值,仍然可以使用-f,但是恢复的数据库必须比通常更加怀疑:立即进行转储和重新加载是必要的。在转储之前,请不要在数据库中执行任何修改数据的操作,因为任何此类操作都可能使损坏变得更严重。
您可以通过运行以下命令来确定是否存在这种情况:
# Postgres >= 10
pg_resetwal DATADIR

# Postgres < 10
pg_resetxlog DATADIR

如果交易日志损坏,你会看到如下消息:
The database server was not shut down cleanly.  
Resetting the transaction log might cause data to be lost.  
If you want to proceed anyway, use `-f` to force reset.

你可以按照指示进行操作,并使用-f参数来强制更新。
# Postgres >= 10
pg_resetwal -f DATADIR

# Postgres < 10
pg_resetxlog -f DATADIR 

那应该会重置交易日志。然而,正如上面所述,这是一项风险较高的操作。你最好寻求专业建议。

4
通过使用 pg_resetwal /usr/local/var/postgres/ 进行重置,然后像这样运行 postgres:postgres -D /usr/local/var/postgres 对我有效。 - heisenBug
谢谢@heisenBug!对我也有用。 - Kaka Ruto
4
在Docker中使用pg_resetwal $PGDATA,在执行之前确保先运行su postgres。谢谢。 - Nurulazrad Murad
2
如果执行 pg_resetwal /var/lib/postgresql/data/ 时出现错误 pg_resetwal: error: cannot be executed by "root",那么你需要使用命令 su postgres 来切换到用户 postgres,通常该用户是该文件夹的所有者。如果你想查看文件夹的所有者是谁,可以使用命令 ls -l /var/lib/postgresql/data/ - Rorrim
这个 pg_resetwal 位于 /usr/lib/postgresql/11/bin - Barney Szabolcs

26

我正在使用9.1.7版本,并成功运行了以下内容:

/usr/lib/postgresql/9.1/bin/pg_resetxlog -f /var/lib/postgresql/9.1/main

你对pg_resetxlog命令的最后一个参数应该是Postgres存储数据库数据的磁盘位置。


同样适用于 Docker 容器中的 9.6 版本。 - Talgat

24

对于docker,

这个错误会导致容器不断被杀死和重新启动。第一步是让容器运行起来,以便我们可以进入容器并运行pg_resetwal或pg_resetxlog。

postgres的docker层信息中,我们可以看到:

ENTRYPOINT 是["docker-entrypoint.sh"],而 CMD是["postgres"]

docker-entrypoint.sh脚本将运行作为参数传递的任何linux命令。

如果您使用的是docker,则传递/bin/bash将覆盖默认的CMD并为您提供对容器shell的访问权限。

docker run -it -v /my_data:/var/lib/postgresql/data postgres:9.6.22 /bin/bash

这里的/var/lib/postgresql/data是容器内的postgres数据目录。

进入容器后,根据您的postgres版本运行以下命令。 这将重置事务日志(WAL)

在postgres >= 10上

pg_resetwal /var/lib/postgresql/data

在 PostgreSQL 10 之前

pg_resetxlog /var/lib/postgresql/data

在此线程上得到的最佳答案更详细地解释了pg_resetwal命令。

最后,您可以退出此容器并使用其原始CMD启动postgres DB容器。


一些额外信息

如果您看到以下错误,则可能是因为您上面指定的数据目录可能不正确。

pg_resetxlog:无法打开文件“PG_VERSION”以进行读取:没有那个文件或目录

您可以检查PGDATA环境变量是否具有正确的路径。

root@4650984c476b:/# printenv | grep PGDATA
PGDATA=/var/lib/postgresql/data

在旧版本的PostgreSQL中,可能会出现以下错误。

pg_resetxlog: 无法由 "root" 执行

可以通过运行以下命令来解决这个问题resolved by running below command

gosu postgres pg_resetxlog /var/lib/postgresql/data

对于像Kubernetes、Rancher V1这样的容器编排工具(因为我们无法直接运行Docker命令),我们需要使用类似于sleep的进程来启动容器。将以下内容作为cmd或args传递到您的编排清单中。

sleep infinity


sh -c 'while sleep 3600; do :; done'

然后使用类似 kubectl exec 的工具进入容器。一旦进入,可以运行 pg_resetwal/pg_resetxlog 命令。


1
只是作为一个旁注,如果有人没有立即设置好bin路径,我能够使用显式命令解决问题:/usr/lib/postgresql/<VERSION>/bin/pg_resetwal /var/lib/postgresql/data - Jay-Ar Polidario
并且将PGDATA=/var/lib/postgresql/data添加到ENV变量中。 - timmotej

15

此处所示,不应运行pg_resetxlog。提到此事的答案是错误的建议。假设错误发生在复制/复制实例的上下文中,则该链接提供了一种更简洁的使用pg_basebackup进行复制/复制的方法。


4

你是否进行连续归档?如果你在备份的同时进行,最好先移除备份标签。使用pg_resetxlog是一个严重的操作。


4

我遇到了一个 Docker Postgresql-13 无法启动的问题。

我通过找到数据卷(存放数据的卷)并以该目录的所有者身份运行以下命令来解决该问题:

先进入数据卷目录,例如:/var/lib/docker/volumes/c4c8d637d9eee086265d732b2974690b731abcb23f47ca61bf75fe28526e31ce/_data

然后以目录的所有者身份(在我的情况下是 systemd-coredump 用户)运行以下命令:

sudo -u systemd-coredump /usr/lib/postgresql/13/bin/pg_resetwal -f .

需要确保您已安装相同版本的 Postgresql(如果 pg_resetwal 不是卷的一部分)。

这样就修复了该问题。


1
这是直接可用的命令:docker run --rm -it -u=postgres -e POSTGRES_PASSWORD=password -v /pg_dbdata_dir:/some_dir postgres:13.4-buster /bin/bash -c "pg_resetwal -f /some_dir" - Kamil

3

如果在Windows Server上看到Postgresql显示错误“无法找到有效的检查点记录”,不要担心,只需在Power Shell上运行以下命令:

在Power Shell中打开文件夹C:\Program Files\PostgreSQL\12\bin(像这样),然后运行:

.\pg_resetwal.exe -f -D "C:\Program Files\PostgreSQL\12\data"

完整的命令将是:

C:\Program Files\PostgreSQL\12\bin.\pg_resetwal.exe -f -D "C:\Program Files\PostgreSQL\12\data";

在看到"Write-ahead log reset"消息后,您可以运行PostgreSQL服务,它将以100%的速度运行,同时确保在启动Potgresql服务之前结束所有正在运行的PostgreSQL任务。


1

就像日志所说的那样:无法找到有效的检查点记录。Postgres在$PGDATA/pg_xlog/目录下找不到正确的WAL。 尝试使用pg_resetxlog。


0

这个答案适用于Postgres 14。在执行以下步骤后,我在备用日志中遇到了相同的错误:

  1. 登录到备用服务器。
  2. 使用以下命令创建备份:

pg_basebackup -D $APP_BACKUP_PATH -F t -P -v -U replicator -w --no-password -h 10.29.51.98

  1. 将生成的$APP_BACKUP_PATH/base.tar解压到备用数据目录中。

  2. 重新启动备用服务器。启动失败并显示:PANIC: could not locate a valid checkpoint record

  3. 因此,备份没有正确生成。需要使用额外的选项-X stream来生成备份。

  4. 重新生成并将更新后的备份应用到备用数据目录后,备用服务器就可以正常启动了,不再出现此错误。


0
我在Docker中遇到了同样的问题。 Postgres的Docker服务没有正确关闭。 我解决这个问题的方法很简单: 注意:这个命令会删除存储在PostgreSQL容器中的数据库文件,请确保备份好你的数据库文件! sudo docker compose down 然后执行: sudo docker compose up 一切都正常运行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接