1. 程式人生 > 其它 >docker執行postgresql出現could not locate a valid checkpoint record的產生原因及如何解決

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

  退出並刪除剛才啟動的容器,然後重新啟動並掛載之前資料卷目錄就可以了。