Debian系统PostgreSQL 11升级13失败排查及最小停机升级方法
Debian环境PostgreSQL 11升级13失败问题解答
1. 本次升级操作失败的根本原因
核心原因是之前的升级操作残留了PostgreSQL 13版本main集群的配置或数据目录,导致pg_upgradecluster创建目标集群的步骤直接失败。
Debian系的pg_upgradecluster默认执行逻辑是先停旧集群,再为目标版本初始化同名集群,最后执行数据迁移。只要检测到/etc/postgresql/13/main(配置目录)或/var/lib/postgresql/13/main(数据目录)已经存在且非空,就会抛出cluster configuration already exists错误直接退出。
这次故障中脚本没有做完整的异常回滚:它停掉旧集群后,为了做升级前置检查临时用绕过systemd的方式启动了旧集群,异常退出时既没有把服务状态同步给systemd,也没有正确回收临时启动的进程,才导致旧集群服务状态异常。重启后systemd按标准单元流程拉起11版本集群,所以服务能恢复上线。
2. 服务启动报错中“the steps required by its unit configuration”的具体含义
这是systemd的通用启动校验失败提示,对应postgresql@.service单元定义的两个强制启动成功条件:
- 服务启动命令执行完成后,PostgreSQL主进程必须持续在后台运行,且PID文件的路径、权限完全符合单元配置要求
- 服务必须正常监听配置文件中指定的端口,可正常响应本地连接请求
你遇到报错时,升级脚本临时启动的PostgreSQL进程已经退出,systemd记录的单元状态与实际进程状态不匹配,既读不到有效的PID文件,也检测不到5432端口的监听进程,判定服务没有完成单元要求的启动流程,就会抛出该错误。
3. 最小停机时间的升级操作步骤
大部分准备工作都可以在旧集群正常对外提供服务时完成,不会影响业务:
- 前置清理(零业务影响):先执行
sudo pg_dropcluster 13 main --stop清理之前升级残留的13版本异常集群,如果命令提示集群不存在,手动删除/etc/postgresql/13/main和/var/lib/postgresql/13/main两个目录即可。 - 备份(零业务影响):执行
sudo -u postgres pg_basebackup -D /opt/pg11_full_backup -Ft -z -P做全量冷备,方便升级失败时快速回滚。 - 根据数据量选择对应升级方案:
- 数据量在100G以内时,直接用硬链接升级,停机时间通常在5分钟以内:
- 通知业务进入短维护窗口,停掉所有业务写入
- 按升级脚本的提示用systemctl停旧集群:
sudo systemctl stop postgresql@11-main - 执行硬链接模式升级:
sudo pg_upgradecluster --link 11 main,--link参数会直接硬链接旧版本数据文件到新版本目录,不需要全量拷贝数据,执行速度极快 - 升级完成后确认13版本集群正常监听5432端口,抽样验证业务数据、连接都正常
- 执行
sudo systemctl enable postgresql@13-main设置13集群开机自启,确认业务稳定运行1-2天后删除旧11集群即可
- 数据量超过100G时,可以用逻辑复制方案把停机时间压缩到1分钟以内:
- 零停机阶段先创建跑在5433端口的13集群:
sudo pg_createcluster 13 main -p 5433,启动后配置11主集群到13集群的逻辑复制,同步全量历史数据 - 等全量数据同步追平后,开启极短维护窗口,停掉业务写入,等待最后一批增量数据同步完成,校验两边数据一致
- 停11集群,把13集群的监听端口改成5432,重启13集群
- 恢复业务写入,验证功能正常后设置13集群开机自启,后续清理旧集群即可
- 零停机阶段先创建跑在5433端口的13集群:
- 数据量在100G以内时,直接用硬链接升级,停机时间通常在5分钟以内:
内容的提问来源于stack exchange,提问作者Jaap Joris Vens
相关产品推荐
相关产品推荐

