• docker运行postgresql出现could not locate a valid checkpoint record的产生原因及如何解决


      这是我们测试环境遇到的一个问题,详见这篇文章:docker 部署数据库并通过数据卷恢复数据 - https://www.modb.pro/db/109870

      然后在网上找到一篇和我们的情况一样:https://www.jianshu.com/p/105855a8a6f7

    一、问题背景

      公司使用测试数据库使用的docker运行的postgresql, 在创建的时候两个docker启动的连接了统一个目录, 后来发现了这个问题停止了一个,紧接着另一个出现了

      而我们的情况是 docker stop 之后,2个容器都没了,然后重新创建容器并使用数据卷去恢复数据,容器一直启不成功。报错也是上面这个报错:

      然后也有一篇文章有介绍:https://daoyuan.li/docker-postgres-panic-could-not-locate-a-valid-checkpoint-record/

    重新启动时,我的 Postgres 数据库似乎没有正确关闭,当我尝试使用 docker-compose 再次启动它时,以下消息显示在docker logs

    // logs
    PANIC:  could not locate a valid checkpoint record
    LOG:  startup process (PID 23) was terminated by signal 6: Aborted
    LOG:  aborting startup due to startup process failure
    LOG:  database system is shut down
    LOG:  database system was interrupted; last known up at 2017-09-14 08:22:04 UTC
    LOG:  unexpected pageaddr B/68B26000 in log segment 000000010000000B0000006D, offset 11689984
    LOG:  invalid primary checkpoint record
    LOG:  unexpected pageaddr B/688F2000 in log segment 000000010000000B0000006D, offset 9379840
    LOG:  invalid secondary checkpoint record

    要解决这个问题,首先关闭这个容器(docker-compose down),然后以交互模式启动容器:

    daoyuan.li:~/Projects/magic/stock$ docker run -it -v /Users/daoyuan.li/Projects/magic/postgres_data:/var/lib/postgres/data postgres:9.6 /bin/bash
    root@c4d2fb7edcea:/# gosu postgres pg_resetxlog -f /var/lib/postgres/data
    Transaction log reset
    root@c4d2fb7edcea:/# exit

    重置事务日志后,一切都应该没问题。现在你可以再次启动你的容器(docker-compose up -d)

    二、解决方案

    1、具体原因:

      原因是两个容器共用一个/pg/data,导致/pg/data中事务日志有问题

    2、为什么会出现2个容器

      很有可能就是之前本来通过 docker run 启动了一个容器,挂载的数据卷目录;然后又通过 docker-compose.yml 又启动了一个相同的容器,也是挂载的相同的数据卷目录。

    3、如何解决

      具体原因结果发现是日志对不上了(2个容器导致数据库日志冲突了), 恢复一下就行了, 于是使用启动了一个容器,运行

    # 挂载该数据卷目录并进入到容器
    docker run -it  -v /root/postgres:/var/lib/postgresql/data postgres /bin/bash gosu postgres pg_resetxlog -f /var/lib/postgres/data

      但是结果发现没有这个命令, 然后去postgresql文档一查,pg_resetxlog在11版本中改成了pg_resetwal

    跟pg数据库的版本有关,11版本之前用pg_resetxlog,11版本及之后用pg_resetwal,我这里是用pg_resetwal

    gosu postgres pg_resetwal -f /var/lib/postgres/data

      当时紧接着又找不到目录, 然后才发现目录是postgresql

    gosu postgres pg_resetwal -f /var/lib/postgresql/data

      这样就搞定了。这里看一下如何查看 pg_resetwal 的位置及使用:

    # 查看pg_resetwal在哪个位置
    find / -name pg_resetwal
    /usr/lib/postgresql/13/bin/pg_resetwal
    # 恢复
    su - postgres
    gosu postgres /usr/lib/postgresql/13/bin/pg_resetwal -f /var/lib/postgresql/data

      退出并删除刚才启动的容器,然后重新启动并挂载之前数据卷目录就可以了。

  • 相关阅读:
    进程和线程的概念、区别和联系
    Python高级语法-GIL-理解(4.1.1)
    Web服务器-并发服务器-Epoll(3.4.5)
    Web服务器-并发服务器-长连接(3.4.4)
    Web服务器-并发服务器-单进程单线程非堵塞方式(3.4.3)
    Web服务器-并发服务器-协程 (3.4.2)
    Web服务器-并发服务器-多进程(3.4.1)
    Web服务器-服务器开发-返回浏览器需要的页面 (3.3.2)
    Web服务器-服务器开发-返回固定页面的HTTP服务器(3.3.1)
    Web服务器-HTTP相关-快速整一个服务器响应浏览器(3.2.1)
  • 原文地址:https://www.cnblogs.com/goloving/p/15305760.html
Copyright © 2020-2023  润新知