PostgresSQL不同主要版本之间不兼容,需要手动升级
pg_dumpall或pg_upgrade都可以用来升级,前者是对整个数据库进行转储再在新的数据库上导入sql,Mt提到在特定版本有可能出现问题,后者是PostgreSQL的专用升级工具,大数据量速度快并且稳定,因此使用pg_upgrade。
pg_upgrade需要至少四个参数:
pg_upgrade -b oldbindir [-B newbindir] -d oldconfigdir -D newconfigdir [option...]
- -b: 旧版本的 PostgreSQL 程序文件目录;
- -B: 新版本的 PostgreSQL 程序文件目录;
- -d: 旧版本的数据目录;
- -D: 新版本的数据目录;
因此我们需要准备原数据库的数据目录与二进制文件目录、目标版本数据库的数据目录与二进制文件目录。
升级记录
- 停止数据库容器
- 备份原数据库
- 复制原数据库的二进制目录与数据目录到宿主机,以下为容器内路径
- /usr/lib/postgresql/13
- /usr/share/postgresql/13
- /var/lib/postgresql/data(数据目录为默认路径)
- 拉取并创建要更新到目标版本数据库的容器,对新数据目录进行初始化。这里从13.3升级到了16.9,系统均为Debian 12。
请注意以下环境变量的POSTGRES_USER一定要和原数据库保持一致,如果不一致升级会报错Only the install user can be defined in the new cluster,使用ALTER ROLE RENAME TO修改也是无效的,需要重新使用pg_ctl initdb初始化一个与原数据库install user一致的Cluster。
docker run --rm -it \ -e POSTGRES_USER=原数据库cluster-install-user-name \ -e POSTGRES_PASSWORD=233333 \ -v 要挂载到宿主机的新数据库数据目录:/var/lib/postgresql/data/ \ postgres:16.9
看到PostgreSQL init process complete; ready for start up.
后就可以退出容器了。
- 开始升级操作,挂载原数据库的二进制目录,数据目录与新数据库的数据目录到升级容器中。括号内容为原容器路径
docker run --rm -it \ -v 宿主机原数据库二进制目录(/usr/lib/postgresql/13):/usr/lib/postgresql/13/ \ -v 宿主机原数据库二进制目录(/usr/share/postgresql/13):/usr/share/postgresql/13/ \ -v 宿主机原数据库数据目录/data-old/:/var/lib/postgresql/data-old/ \ -v 宿主机新数据库数据目录/data/:/var/lib/postgresql/data/ \ postgres:16.9 bash
先切换到 postgres 用户, 并进入有写权限的目录, pg_upgrade 不允许以 root 用户执行
su - postgres cd ~
挂载两个版本的数据库可能会导致$PATH下命令冲突,这时pg_upgrade会无法找到,可以使用绝对路径
/usr/lib/postgresql/16/bin/pg_upgrade
此处的16是目标数据库版本,而不是旧版本
检查
pg_upgrade -b /usr/lib/postgresql/16/bin/ -B /usr/lib/postgresql/17/bin/ -d /var/lib/postgresql/data-old/ -D /var/lib/postgresql/data/ -c
看到所有检查都为OK可以进行升级
升级
pg_upgrade -b /usr/lib/postgresql/16/bin/ -B /usr/lib/postgresql/17/bin/ -d /var/lib/postgresql/data-old/ -D /var/lib/postgresql/data/
看到所有步骤都为OK则为升级成功,这时可以运行
/usr/lib/postgresql/16/bin/vacuumdb -U confluence --all --analyze-in-stages ./delete_old_cluster.sh
Optimizer statistics未被pg_upgrade升级,需要手动执行进行优化,此外也可以删除旧cluster的数据,反正也有一份备份。
完事退出容器
注
-
Debian12的容器可能在执行升级时可能还会出现缺少动态链接库的问题,需要拷贝libLLVM-15.so.1与libLLVM-15.so到容器中
该链接库在/usr/lib/x86_64-linux-gnu/下,拷贝到新容器/usr/lib/x86_64-linux-gnu/下即可 -
在升级成功后迁移数据库开启容器发现刷屏报错(这是Docker Confluence的配置,不是所有镜像都会遇到,具体问题具体分析)
FATAL: no pg_hba.conf entry for host "172.28.1.2", user "confluence", database "confluence", no encryption
复制原数据库的pg_hba.conf覆盖即可,原配置是直接
host all all all md5
这样有点暴力,不过在容器与内网隔离,也不是很危险,更安全的话可以修改为
host confluence confluence 172.0.0.1/8 md5
参考https://6xyun.cn/article/pg-upgrade 与 mentor文档
使用docker-postgres-upgrade镜像升级
在容器间把文件复制来复制去实在是太麻烦了,有没有更简便的方法呢,当然有,可以使用以下镜像,指定新旧cluster目录即可,当然也别忘了备份!
https://github.com/tianon/docker-postgres-upgrade