使用pg_upgrade升级容器内Postgres数据库

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镜像方法作者还没有在生产环境测试,使用风险自负!

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
  1. 1 XX:Calling tiko-μ
  2. 2 魔女的玩偶之家 Kiwiwalks
  3. 3 Summer Pockets 水月陵
  4. 4 Lasting Moment 鈴木このみ
  5. 5 花鳥風月 井ノ原智
XX:Calling - tiko-μ
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.