在 Docker 中运行的 PostgreSQL 数据库突然无法启动, 错误日志类似这样:
PANIC,XX000,"could not locate a valid checkpoint record",,,,,,,,,""
LOG,00000,"startup process (PID 24) was terminated by signal 6: Aborted",,,,,,,,,""
LOG,00000,"aborting startup due to startup process failure",,,,,,,,,""
这种情况多数情况下是在执行事务时, 数据库被强行关闭导致的, 修复的方法是:
pg_resetwal DATADIR
来解决;pg_resetxlog DATADIR
来解决;由于数据库是在 Docker 中运行的, 因此需要按照 Docker 的方式来修复:
停止正在运行的容器实例
使用命令 docker-compose down
来停止正在运行的数据库容器实例, 也可以使用 docker stop
和 docker rm
命令。
覆盖 entrypoint 来的形式启动一个临时的容器
这一步很重要, 需要使用原来的镜像, 覆盖默认的 entrypoint 启动, 进入可交互的命令行窗口:
docker run -it --rm --entrypoint /bin/bash \
-v ${pwd}/data:/var/lib/postgresql/data \
postgres:9.3
注意镜像的版本必须和原来的一致
根据数据库的版本选择 pg_resetwal
或者 pg_resetxlog
进行修复
以 PostgreSQL 9.3 为例, 在上面的步骤中打开的命令行窗口中输入 pg_resetxlog
命令
pg_resetxlog /var/lib/postgresql/data
通常会返回这样的提示
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
强制重置事务日志
pg_resetxlog -f /var/lib/postgresql/data
重新启动数据库实例
docker-compose up -d
使用 pg_resetxlog
或者 pgresetwal
有可能会丢失数据, 启动之后, 需要仔细检查数据库的健康情况。 如果有数据库备份的话, 请尽快进行数还原。
更多请参考 PostgreSQL 的文档 https://www.postgresql.org/docs/current/app-pgresetwal.html