Docker环境下Postgres 9.6.5升级至11.7的数据迁移问题
Postgres 9.6.5容器升级至11.7并保留数据的解决方案
一、直接复用旧数据卷的物理升级方案(推荐)
要让Postgres 11.7直接读取旧卷数据,可在容器环境内模拟物理机的pg_upgrade流程,步骤如下:
1. 前置准备
- 停止运行中的旧Postgres 9.6.5容器:
docker stop old-postgres - 备份旧数据卷(务必执行,防止升级失败数据丢失):
docker run --rm -v pg96-data:/data -v $(pwd)/pg-backup:/backup busybox tar cvzf /backup/pg96-full-backup.tar.gz /data - 创建新的数据卷用于存放升级后的11.7数据:
docker volume create pg11-data
2. 启动临时升级容器并执行升级
运行11.7版本的Postgres容器,同时挂载新旧数据卷,进入交互式终端:
docker run -it --rm \ -v pg96-data:/pg96 \ -v pg11-data:/pg11 \ postgres:11.7 \ bash
在容器内部执行以下操作:
- 添加Debian Stretch源(用于安装9.6版本的Postgres二进制包):
echo "deb http://deb.debian.org/debian stretch main" >> /etc/apt/sources.list - 更新源并安装Postgres 9.6:
apt update && apt install -y postgresql-9.6 --no-install-recommends - 初始化11.7版本的空数据库:
initdb -D /pg11 - 执行物理升级:
pg_upgrade \ -b /usr/lib/postgresql/9.6/bin \ -B /usr/lib/postgresql/11/bin \ -d /pg96 \ -D /pg11 \ -U postgres - 升级完成后,生成新集群的统计信息(按提示执行):
./analyze_new_cluster.sh
3. 启动新的11.7容器
退出临时容器后,用新数据卷启动Postgres 11.7:
docker run -d \ --name new-postgres \ -v pg11-data:/var/lib/postgresql/data \ -e POSTGRES_PASSWORD=your-original-password \ -p 5432:5432 \ postgres:11.7
二、高效数据迁移方案(解决dump/restore的效率与认证问题)
如果暂时不想用物理升级,可优化dump/restore流程,解决认证错误并提升效率:
1. 解决Peer认证失败问题
原命令报错是因为psql默认使用peer认证(匹配操作系统用户),通过指定-h localhost强制使用TCP连接,触发密码认证:
docker exec old-postgres pg_dump -U postgres -d db_name | \ docker exec -i new-postgres psql -U postgres -d db_name -h localhost
确保新容器启动时已设置POSTGRES_PASSWORD环境变量。
2. 提升dump/restore效率
- 并行导出/恢复:适合大数据库,利用多核加速:
# 旧容器导出为并行目录格式(-j指定并行数,根据CPU核心数调整) docker exec old-postgres pg_dump -U postgres -d db_name -F d -j 4 -f /tmp/dumpdir # 复制导出目录到新容器 docker cp old-postgres:/tmp/dumpdir new-postgres:/tmp/dumpdir # 新容器并行恢复 docker exec new-postgres pg_restore -U postgres -d db_name -j 4 /tmp/dumpdir - 全实例导出:如果需要迁移所有数据库、用户和配置,用
pg_dumpall:docker exec old-postgres pg_dumpall -U postgres | \ docker exec -i new-postgres psql -U postgres -h localhost
内容的提问来源于stack exchange,提问作者Luigi
相关产品推荐
相关产品推荐

