惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
Schneier on Security
The Last Watchdog
The Last Watchdog
Cyberwarzone
Cyberwarzone
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cyber Attacks, Cyber Crime and Cyber Security
L
Lohrmann on Cybersecurity
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 司徒正美
The Cloudflare Blog
V
V2EX
博客园_首页
博客园 - 聂微东
Vercel News
Vercel News
人人都是产品经理
人人都是产品经理
G
GRAHAM CLULEY
T
Tenable Blog
Last Week in AI
Last Week in AI
Y
Y Combinator Blog
L
LINUX DO - 最新话题
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
SecWiki News
SecWiki News
博客园 - 三生石上(FineUI控件)
S
Secure Thoughts
N
News | PayPal Newsroom
T
The Blog of Author Tim Ferriss
The GitHub Blog
The GitHub Blog
T
Troy Hunt's Blog
博客园 - 【当耐特】
Forbes - Security
Forbes - Security
H
Hacker News: Front Page
A
About on SuperTechFans
B
Blog RSS Feed
Engineering at Meta
Engineering at Meta
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
D
DataBreaches.Net
P
Privacy & Cybersecurity Law Blog
Schneier on Security
Schneier on Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Google DeepMind News
Google DeepMind News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Jina AI
Jina AI
D
Docker
P
Proofpoint News Feed

Shanwer's Blog

奇怪的小米BE 6500 Pro – Shanwer's Blog 本站现已支持HTTP/3,那么,代价是什么 – Shanwer's Blog Debian12+KDE无法启用Wi-Fi网络的问题 – Shanwer's Blog Linux使用sing-box配置代理 – Shanwer's Blog 大二寒假实习面试 – Shanwer's Blog GitHub workflow的介绍与Git压缩commits的方法 – Shanwer's Blog 计算机科学学习指南 – Shanwer's Blog 记处理一个奇怪的锁屏显示问题 – Shanwer's Blog 数据结构课程设计 – Shanwer's Blog MC服务器迁移数据笔记 – Shanwer's Blog
使用pg_upgrade升级容器内Postgres数据库 – Shanwer's Blog
2025-05-15 · via Shanwer's Blog

本文最后更新于 394 天前,其中的信息可能已经有所发展或是发生改变。

PostgresSQL不同主要版本之间不兼容,需要手动升级
pg_dumpallpg_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.1libLLVM-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

 警告

请注意,使用docker-postgres-upgrade镜像方法作者还没有在生产环境测试,使用风险自负!