You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Compose中PostgreSQL.bak备份恢复失败问题排查

Docker Compose部署PostgreSQL数据库恢复失败排查与解决

问题背景

正在部署运行Mezzanine的老旧Django网站本地版本用于故障排查,数据库通过以下命令导出:

sudo -u postgres pg_dump --role "postgres" --format custom --blobs 
     --encoding UTF8 --verbose --no-unlogged-table-data --file /tmp/backup.bak

本地可正常用pg_restore恢复备份,但通过Docker Compose部署时,db服务创建了数据库,db_init服务无报错输出,但数据库未恢复任何表,网站访问时出现relation "shipping_shippingcountry" does not exist的错误,已通过\dt命令确认数据库为空。

Docker Compose配置

version: '3'

services:
  db:
    image: postgres:13
    environment:
      POSTGRES_DB: pg_db
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "postgres"]
      interval: 10s
      retries: 5

  db_init:
    image: postgres:13
    container_name: pg_db_init
    command: ["sh", "-c", 
              "./wait-for-it.sh db:5432 -- pg_restore --clean --if-exists \
               --no-owner --no-privileges -h db -d pg_db -U postgres /backup.bak"] 
    environment:
      POSTGRES_DB: pg_db
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      PGPASSWORD: postgres
    volumes:
      - ./backup.bak:/backup.bak
      - ./wait-for-it.sh:/wait-for-it.sh
    depends_on:
      - db

  web:
    build: .
    command: python3 manage.py runserver 0.0.0.0:8000
    working_dir: /var/www/website.com.au    
    depends_on:
      - db
    environment:
      - DJANGO_SETTINGS=project.settings
    user: ${UID}:${GID}
    volumes:
      - .:/var/www/website.com.au
    ports:
      - "8000:8000"
    tty: true

volumes:
  postgres_data:

排查步骤

  • 检查wait-for-it.sh脚本权限:挂载到容器内的脚本默认可能无执行权限,导致db_init无法运行脚本跳过恢复,可执行docker exec pg_db_init ls -l /wait-for-it.sh查看权限状态。
  • 查看db_init容器完整日志:即使容器无报错提示,也可能存在执行细节问题,执行docker logs pg_db_init获取完整执行日志。
  • 确认postgres_data卷状态:若之前启动过Docker Compose,postgres_data卷可能已存在空数据库实例,导致pg_restore无法正确初始化。
  • 验证pg_restore命令兼容性:确认本地PostgreSQL版本与Docker镜像(postgres:13)一致,自定义格式备份对版本兼容性要求较高,跨版本可能导致恢复失败。

解决方案

  1. 给wait-for-it.sh添加执行权限
    本地先给脚本加权限:

    chmod +x wait-for-it.sh
    

    或修改db_init的command,先设置权限再执行:

    command: ["sh", "-c", 
              "chmod +x ./wait-for-it.sh && ./wait-for-it.sh db:5432 -- pg_restore -v --clean --if-exists \
               --no-owner --no-privileges -h db -d pg_db -U postgres /backup.bak"]
    
  2. 添加pg_restore详细输出
    在pg_restore命令中加入-v参数,便于查看恢复过程日志定位问题:

    pg_restore -v --clean --if-exists --no-owner --no-privileges -h db -d pg_db -U postgres /backup.bak
    
  3. 清理旧数据卷重新部署
    删除已存在的postgres_data卷,确保数据库从全新状态开始:

    docker-compose down -v
    docker-compose up -d
    
  4. 确保数据库完全就绪后执行恢复
    结合depends_on的健康检查依赖,修改db_init的配置:

    depends_on:
      db:
        condition: service_healthy
    

内容的提问来源于stack exchange,提问作者scicrow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 06:43:16