Docker PostgreSQL无效的主检查点记录。

7

我一直在尝试在 Docker 中(在 Windows 上)运行 postgres 并保持数据的持久性存储,我认为我终于成功了,但现在当我尝试启动容器时,我会遇到以下错误:

LOG:  invalid primary checkpoint record
LOG:  invalid secondary checkpoint record
PANIC:  could not locate a valid checkpoint record

以下是我启动容器的步骤:

docker volume create ct_data
docker run --name postgres_ct -v ct_data:/var/lib/postgresql/data -p 5432:5432 postgres

我随后使用pgAdmin连接它,创建了一个新表,并使用恢复选项导入了一个postgres转储文件。数据加载没有问题。我启动了第二个容器,使用与上述相同的卷,但名称和端口号不同以进行测试,我能够连接,所以我将其关闭。
现在,一小时后,我发现我的原始容器自动停止,因此我尝试重新启动它并获得了上述错误。这是我第一次尝试使用Docker,因此很可能我错过了一些简单的东西。

你是否同时在一个卷上运行两个容器? - Matt
@Matt 我最初只是为了测试音量而这样做,但一旦我设置好了,就不打算再这样做了。 - pheeper
2
那样做的话可能不太可行,除非有一个特别编写的进程来处理像那样多个进程写入相同文件的情况,通常会导致数据损坏,这似乎是你遇到的问题。移除该卷并重新开始,在每次只使用一个postgres容器的卷。 - Matt
@Matt,那正是发生的事情。当我重新创建卷并仅使用不同容器进行测试,但每次只使用一个容器时,它就可以正常工作。 - pheeper
2个回答

10
这个相关帖子的被接受的答案建议删除Docker卷,这意味着PostgreSQL实例中的所有数据都将丢失!我最近遇到了同样的问题,在我们存储了几个月的数据的环境中,因此删除/删除卷是(非常非常)的最后手段。
我发现这个答案要求重置事务写前日志(WAL)。这在DB安装为应用程序而不是作为容器运行时的情况下有效。然而,在Docker的情况下,容器本身无法部署,因为出现以下错误

PANIC: could not locate a valid checkpoint record

解决方案

在这种情况下,解决方案是使用postgres映像的docker run命令,并在正确的PGDATA路径(您之前配置的路径)上挂载相同的物理卷,并直接登录到bash shell。
docker run -it -v /data/postgres_data:<PGDATA_path> postgres:14 /bin/bash

<PGDATA_path> 默认为/var/lib/postgresql/data,如果您没有更改它的话。 如果您使用的是docker卷,请从卷列表中找出您的docker卷名称:docker volume ls。获取卷名称,然后像下面这样使用docker run

docker run -it -v <docker_volume_name>:<PGDATA_path> postgres:14 /bin/bash

一旦您获得了容器的 shell,现在可以使用以下命令重置 WAL:

# Postgres >= 10
pg_resetwal <PGDATA_path>

# Postgres < 10
pg_resetxlog <PGDATA_path>

如有需要,请使用-f选项。有关详细信息,请参阅PostgreSQL文档中的pg_resetwal

现在退出容器的shell,然后使用docker-compose/docker stack(取决于您使用哪个),重新部署容器,您将成功恢复数据库并保留所有数据。

注意事项

  1. 某些数据可能仍会丢失,尤其是在没有WAL一致性的地方。
  2. 某些依赖于数据库的应用程序可能会抛出进一步的错误,例如“重置数据库日志,找不到插入的数据”。在这种情况下,您必须重置这些应用程序的写头。
  3. 请访问我的答案这里,了解何时/为什么会出现这种情况。

3
感谢@Matt的帮助,我弄清楚了发生了什么。当我同时连接两个容器时,卷(即postgres数据库)就会损坏。
不过,允许多个容器连接到单个数据库容器是可能的,但不能共享卷。您需要创建一个新容器来运行postgres守护程序,然后其他容器可以通过tcp套接字连接到它。有关如何执行此操作的更多信息,请阅读文档(点此链接)

1
不错。感谢解释。我在这里添加了一个答案,用于删除损坏的卷的Docker命令。 - Connor Leech

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