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)一致,自定义格式备份对版本兼容性要求较高,跨版本可能导致恢复失败。
解决方案
给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"]添加pg_restore详细输出
在pg_restore命令中加入-v参数,便于查看恢复过程日志定位问题:pg_restore -v --clean --if-exists --no-owner --no-privileges -h db -d pg_db -U postgres /backup.bak清理旧数据卷重新部署
删除已存在的postgres_data卷,确保数据库从全新状态开始:docker-compose down -v docker-compose up -d确保数据库完全就绪后执行恢复
结合depends_on的健康检查依赖,修改db_init的配置:depends_on: db: condition: service_healthy
内容的提问来源于stack exchange,提问作者scicrow
相关产品推荐
相关产品推荐

