运行在容器中Postgres数据库数据损坏后如何恢复?

运行,容器,postgres,数据库,数据,损坏,如何,恢复 · 浏览次数 : 0

小编点评

## postgres 数据库 WAL 损坏后恢复步骤 **问题:** postgres 数据库 WAL 损坏,导致 CrashBackoffLoop,无法正常启动。 **解决方案:** 1. **尝试启动 Pod** - 通过 `kubectl exec -it` 命令进入 `database-postgres-56cff865bb-92pcx` 容器中。 - 使用 `pg_reset_wal` 命令恢复 WAL。 2. **恢复 WAL** **步骤:** **a. 检查 WAL 恢复结果** - 使用 `pg_resetwal --dry-run` 命令检查 WAL 恢复结果。 - 如果结果符合预期,则使用 `pg_resetwal` 命令恢复 WAL。 **b. 恢复 WAL** - 使用 `pg_resetwal` 命令恢复 WAL。 - 注意: - `pg_resetwal` 命令仅适用于 WAL 文件已损坏的情况。 - 恢复 WAL 后,需要 restart postgres 服务。 **注意:** - 恢复 WAL 后,需要确保 `postgres` 服务能够正常启动。 - 使用 `pg_resetwal` 命令之前,请确保确保 WAL 文件的完整性。 **其他提示:** - 在执行 `pg_resetwal` 命令之前,请确保确保已备份重要数据。 - 恢复 WAL 后,请仔细检查数据库的性能,并根据需要进行优化。

正文

前言

使用 K8S 部署 RSS 全套自托管解决方案- RssHub + Tiny Tiny Rss, 我介绍了将 RssHub + Tiny Tiny RSS 部署到 K8s 集群中的方案. 其中 TTRSS 会用到 Postgres 存储数据, 也一并部署到 K8s 容器中.

但是最近, 由于一次错误操作, 导致 Postgres 数据库的 WAL 损坏, Postgres 的 Pod 频繁 CrashBackoffLoop. 具体报错如下:

Postgres shutdown exit code 1:

2023-09-27 02:32:17.127 UTC [1] LOG:  received fast shutdown request
2023-09-27 02:32:17.181 UTC [1] LOG:  aborting any active transactions
2023-09-27 02:32:17.434 UTC [1] LOG:  background worker "logical replication launcher" (PID 26) exited with exit code 1
2023-09-27 02:32:17.481 UTC [21] LOG:  shutting down
2023-09-27 02:32:17.880 UTC [1] LOG:  database system is shut down

Postgres "invalid resource manager ID in primary checkpoint record" and "could not locate a valid checkpoint record"

2023-09-27 02:33:23.189 UTC [1] LOG:  starting PostgreSQL 13.5 on x86_64-pc-linux-musl, compiled by gcc (Alpine 10.3.1_git20211027) 10.3.1 20211027, 64-bit
2023-09-27 02:33:23.190 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2023-09-27 02:33:23.190 UTC [1] LOG:  listening on IPv6 address "::", port 5432
2023-09-27 02:33:23.199 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2023-09-27 02:33:23.210 UTC [21] LOG:  database system was shut down at 2023-09-27 02:32:22 UTC
2023-09-27 02:33:23.210 UTC [21] LOG:  invalid resource manager ID in primary checkpoint record
2023-09-27 02:33:23.210 UTC [21] PANIC:  could not locate a valid checkpoint record
2023-09-27 02:33:24.657 UTC [1] LOG:  startup process (PID 21) was terminated by signal 6: Aborted
2023-09-27 02:33:24.657 UTC [1] LOG:  aborting startup due to startup process failure
2023-09-27 02:33:24.659 UTC [1] LOG:  database system is shut down

如上, WAL文件已损坏, 应该如何恢复?

恢复步骤

🐾Warning:

目的是启动 Postgres 恢复应用的正常运行. 数据可能存在丢失.

这是一个 TTRSS feed 应用, 只供我自己使用, 只要能启动起来, 丢失一点数据无所谓.

首先, Postgres Pod 在 CrashBackoffLoop, 无法进行任何操作, 首要任务是使 Pod 启动起来, 不要关闭. 这里通过在 Deployment 添加一些命令来实现. 如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  ...
spec:
  ...
  template:
    spec:
      containers:
      - image: postgres:13-alpine
        imagePullPolicy: IfNotPresent
        name: postgres
        command: ["sh"]
        args: ["-c", "tail -f /dev/null"]
...

如上, 通过 sh -c tail -f /dev/null 实现 Pod 运行. 也可以通过类似 while true; do sleep 30; done; 等类似命令来实现.

Pod 稳定运行后, 通过 kubectl exec -it 进入该Pod:

k3s kubectl exec -it database-postgres-56cff865bb-92pcx -n rsshub -- /bin/sh

并切换到 postgres 用户:

su - postgres

🐾Warning:

切换到 postgres 用户方可执行下面命令.

接下来就顺利了, 使用 pg_reset_wal 恢复 WAL:

先用 --dry-run 看看运行结果:

pg_resetwal --dry-run /var/lib/postgresql/data/

如果结果符合预期, 再运行:

pg_resetwal /var/lib/postgresql/data/
Write-ahead log reset

成功后, 退出 Pod. 并移除 Deploy 的 commandargs 后, postgres 即可正常启动. 如下:

2023-09-27 04:03:25.172 UTC [1] LOG:  starting PostgreSQL 13.5 on x86_64-pc-linux-musl, compiled by gcc (Alpine 10.3.1_git20211027) 10.3.1 20211027, 64-bit
2023-09-27 04:03:25.173 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2023-09-27 04:03:25.173 UTC [1] LOG:  listening on IPv6 address "::", port 5432
2023-09-27 04:03:25.179 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2023-09-27 04:03:25.187 UTC [20] LOG:  database system was shut down at 2023-09-27 04:02:42 UTC
2023-09-27 04:03:25.210 UTC [1] LOG:  database system is ready to accept connections

完成🎉🎉🎉

三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.

与运行在容器中Postgres数据库数据损坏后如何恢复?相似的内容:

运行在容器中Postgres数据库数据损坏后如何恢复?

前言 在使用 K8S 部署 RSS 全套自托管解决方案- RssHub + Tiny Tiny Rss, 我介绍了将 RssHub + Tiny Tiny RSS 部署到 K8s 集群中的方案. 其中 TTRSS 会用到 Postgres 存储数据, 也一并部署到 K8s 容器中. 但是最近, 由于

虚拟化技术浅析第二弹之初识Kubernetes

作者:京东物流 杨建民 一、微服务架构起源 单体架构:可以理解为主要业务逻辑模块(我们编写的代码模块,不包括独立的中间件)运行在一个进程中的应用,最典型的是运行在一个Tomcat容器中,位于一个进程里。单体架构好处是技术门槛低、编程工作量少、开发简单快捷、调试方便、环境容易搭建、容易发布部署及升级,

[转帖]针对容器的nginx优化

针对容器的nginx优化 本篇文章介绍了 Nginx 在容器内使用遇到的CPU核数获取问题以及对应的解决方法。 回顾上篇文章:TCP 半连接队列和全连接队列 背景 容器技术越来越普遍,很多公司已经将容器技术作为基础架构的一部分,容器中可以运行任何软件,包括 Web Server、Applicatio

[转帖]nsenter 工具的使用

一、背景 对于运行在后台的docker容器,我们经常需要做的事情是进入到容器中,docker为我们提供了docker exec 、docker attach 命令,并且还提供了nsenter工具,外部工具供我们使用。 docker attach存在的问题是:当多个窗口同时attach到同一个容器时,

[转帖]docker编译speccpu2017

实验步骤: 1.下载docker和speccpu2017 2.docker下载镜像,创建容器 3.将下载的宿主机speccpu2017拷贝到docker创建的容器中(docker cp) 4.在docker容器(docker exec)中编译运行speccpu2017 下载docker yum in

[转帖]Docker限制容器的资源

docker在默认运行容器的情况下,是不会对运行的容器进行资源限制的,在自己的实验环境的话是随便你怎么弄的,不过在生产中是一定会对docker运行的容器进行资源限制的,如果不限制的话在生产中会带来很多弊端的。例如当资源没有做限制时,资源用完了后会导致其他的容器无法运行,在生产中的话是会部署几十个或者

[转帖]如何在一个Docker中同时运行多个程序进程?

https://cloud.tencent.com/developer/article/1683445 我们都知道Docker容器的哲学是一个Docker容器只运行一个进程,但是有时候我们就是需要在一个Docker容器中运行多个进程 那么基本思路是在Dockerfile 的CMD 或者 ENTRYP

.NET微服务系统迁移至.NET6.0的故事

本次迁移涉及的是公司内部一个业务子系统,该系统是一个多样化的应用,支撑着公司的多个业务方向。目前,该系统由40多个基于.NET的微服务应用构成,使用数千个CPU核心和数TB内存,在数百个Linux容器中运行。每天,该系统需要处理数十亿次请求。 该系统其中大部分服务是在2018-2019年左右由老旧.

2.1 C++ STL 数组向量容器

Vector容器是C++ STL中的一个动态数组容器,可以在运行时动态地增加或减少其大小,存储相同数据类型的元素,提供了快速的随机访问和在末尾插入或删除元素的功能。该容器可以方便、灵活地代替数组,容器可以实现动态对数组扩容删除等各种复杂操作,其时间复杂度`O(l)常数阶`,其他元素的插入和删除为`O(n)线性阶`,其中n为容器的元素个数,vector具有自动的内存管理机制,对于元素的插入和删除可动

[转帖]讨论在 Linux Control Groups 中运行 Java 应用程序的暂停问题原创

https://heapdump.cn/article/1930426 说明 本篇原文来自 LinkedIn 的 Zhenyun Zhuang,原文:Application Pauses When Running JVM Inside Linux Control Groups[1],在容器化的进程中