我有一个与一个容器PostgreSQL和另一个与我的应用程序组成的 docker .我需要将两个数据库恢复到PostgreSQL中,然后启动应用程序.

目前,我已经try 了这个对接器组合:

version: "3.7"
services:
  dataspace_postgres:
    container_name: custompostgres
    platform: linux/amd64
    build:
      context: ./
      dockerfile: Dockerfile.CustomPostgres
    networks:
      - dataspace
    environment:
      PGUSER: postgres
      POSTGRES_DB: postgres
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
    ports:
      - 5434:5432
    volumes:
      - disk-postgres:/var/lib/postgresql/data
      - ./dumps/psql/managementreporting.sql:/managementreporting.sql
      - ./dumps/psql/idams_new.sql:/idams_new.sql
      - ./dumps/init.sh:/docker-entrypoint-initdb.d/init.sh
    healthcheck:
      test: ["CMD-SHELL", "sh -c 'pg_isready -U postgres -d managementreporing'"]
      interval: 10s
      timeout: 120s
      retries: 10

  dataspace_consolidatedreportingunit:
    container_name: consolidatedreportingunit
    platform: linux/amd64
    build:
      context: ./
      dockerfile: Dockerfile.ReportingTool
    networks:
      - dataspace
    ports:
      - 8080:80
      - 8081:443
    depends_on:
      dataspace_postgres:
        condition: service_healthy

networks:
  dataspace:
    driver: bridge

volumes:
  disk-postgres:
    driver: local

和我的init.sh文件:

pg_restore -v -c -d managementreporting managementreporting.sql
pg_restore -v -c -d idams_new idams_new.sql

目前在启动时,无论我try 什么,它都会失败,并出现以下错误:

pg_restore: connecting to database for restore custompostgres
| 2023-09-29 14:27:03.007 UTC [64] FATAL: database "managementreporting" does not exist custompostgres | pg_restore: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: database "managementreporting" does not exist custompostgres exited with code 1

对我来说,恢复数据库的唯一方法是将它们直接挂载到/docker-入口点-initdb.d/中(对于转储),但是我无法让另一个容器等待postgesql来完成恢复.

有什么主意吗?

推荐答案

我设法用简单的方法解决了恢复数据库和等待恢复完成这两个问题.

首先,在Docker-Compose中,在卷下,如果您已经使用普通模式备份了数据库,只需将它们注入docker-Entrypoint-initdb.d文件夹,就可以恢复数据库,但使用这种方法,您无法判断恢复实际完成的时间,如下所示:

volumes:
  - disk-postgres:/var/lib/postgresql/data
  - ../PostgreSQL/dumps/plain/managementreporting.sql:/docker-entrypoint-initdb.d/managementreporting.sql
  - ../PostgreSQL/dumps/plain/idams_new.sql:/docker-entrypoint-initdb.d/idams_new.sql

相反,我们使用自定义格式的备份并将其注入根文件夹,因此我们需要一个脚本来恢复它们,并在恢复完成时创建一个标记,如下所示:

volumes:
  - disk-postgres:/var/lib/postgresql/data
  - ../PostgreSQL/dumps/psql/managementreporting.sql:/managementreporting.sql
  - ../PostgreSQL/dumps/psql/idams_new.sql:/idams_new.sql
  - ../PostgreSQL/dumps/init.sh:/docker-entrypoint-initdb.d/init.sh
healthcheck:
  test: ["CMD-SHELL", "test -f /tmp/healthcheck.txt"]
  interval: 10s
  timeout: 120s
  retries: 10
  start_period: 60s

以及用于恢复和标记的cmd-shellinit.sh脚本,如下所示

#Restore Consolidated Reporting Unit Database
createdb managementreporting #use it to avoid locale error on restore instead of pg_restore -C
pg_restore -v -U postgres -d managementreporting --no-owner /managementreporting.sql # -d should be postgres
#Restore Production BluePrint Idams New Database
createdb idams_new #use it to avoid locale error on restore instead of pg_restore -C
pg_restore -v -U postgres -d idams_new --no-owner /idams_new.sql # -d should be postgres
#Create a file to use healtcheck and ensure that PostgreSQL init has finished as during this action can accept connections
touch /tmp/healthcheck.txt #same file name at docker-compose healtcheck

在init.sh脚本中,我们使用createdb而不是-C切换到pg_Restore来创建数据库,因为当要恢复的数据库具有与默认postgres数据库不同的排序规则时,这会产生问题.(还发现-Cswitch 期望找到已经存在的数据库,而不是创建数据库,这很奇怪,很可能是因为期望首先删除它).

此外,我们使用--no-owner切换到PG_RESTORE,以便忽略我们进行备份的服务器上的前一个所有者,因为该所有者可能不存在于我们用于恢复的服务器中.

最后,我们创建一个文件(空文件),以便在docker中对其进行健康判断--编写容器并将其标记为健康,然后使用应用程序启动第二个容器.最后,不要太关注START_PERIOD:60S,我把它放在那里是因为我确信数据库在60S之前不会被恢复,因此没有必要在60S之前进行TCP判断调用.

Postgresql相关问答推荐

在输入稍有错误的PostgreSQL表中进行快速字符串搜索

为什么在PostgreSQL中CPU_INDEX_TUPLE_COST与CPU_TUPLE_COST不同

DBT-DBT依赖于未找到的源

Jsonb[]字段中的PostgreSQL否定&q;-0.0

为什么Postgres优化器切换到嵌套循环进行连接?

GORM Golang SQL查询执行不区分大小写的搜索不起作用

EF Core和npgsql连接池已被耗尽

postgresql中多个左连接的空结果

Upper() 不会大写重音字符

如何在 sequelize 使用 db postgres 中通过外键更新记录和更新包含许多记录关系

如何使用 PostgreSQL 数据库中的函数和存储过程从动态表中获取所有数据?参数传入的表名

postgres 的密码

psql中set、\set和\pset的区别

SQLAlchemy 中使用什么类型存储字节字符串?

使用 Hibernate 查询:colon gets treated as parameter / escaping colon

PostgreSQL 获取过go 12 小时的元素

从长时间的postgres转换日期

Postgres 数据库文件保存在 ubuntu 中的什么位置?

在 postgres 中存在不同的 string_agg 问题

使用 Hibernate 注释映射 PostgreSQL 串行类型