Debian 的 Postgres 早就升级到 13 了,但是由于我太懒就一直没有升级数据库,这次要往数据库放新数据了,就想趁这个机会刚好把数据都迁移到 13 吧。以前看过类似资料,postgres 本身提供了升级工具,所以我想找个靠铺点的教程一步步照着来应该问题不大。
找到了这个博文:How to upgrade PostgreSQL from 12 to 13 和 StackOverflow 上的一个回答:How to upgrade postgresql database from 10 to 12 without losing data for openproject 写的东西基本上一样,所以确定这就是正确的方法了,照着来吧。
首先自己查看 pg_hba.conf 和 postgresql.conf 按需更改,比如端口、数据存放目录、socket 目录等等。按照教程里 diff 看看文件差异:
1
2
|
diff /etc/postgresql/12/main/postgresql.conf /etc/postgresql/13/main/postgresql.conf
diff /etc/postgresql/12/main/pg_hba.conf /etc/postgresql/13/main/pg_hba.conf
|
再改起来很快。
配置文件改好就可以开始准备了,确保数据库未在后台运行情况下运行 check :
1
2
3
4
5
6
7
8
|
/usr/lib/postgresql/13/bin/pg_upgrade \
--old-datadir=/home/postgres/12/main/ \ # 自定义
--new-datadir=/home/postgres/13/main/ \
--old-bindir=/usr/lib/postgresql/12/bin \
--new-bindir=/usr/lib/postgresql/13/bin \
--old-options '-c config_file=/etc/postgresql/12/main/postgresql.conf' \
--new-options '-c config_file=/etc/postgresql/13/main/postgresql.conf' \
--check
|
结果我这儿一上来就报错:
1
2
|
could not open version file "/home/postgres/12/main/PG_VERSION": Permission denied
Failure, exiting
|
权限不对,我想那肯定是我使用本地用户登录的,换成那个一开始创建没怎么用的 postgres 吧我忘了用户密码,那就直接 sudo/doas 吧。结果:
1
2
|
pg_upgrade: cannot be run as root
Failure, exiting
|
这个命令不让管理员使用。好吧,只能切 sudo su postgres 用户了:
1
|
su: failed to execute /usr/bin/nologin: No such file or directory
|
我也不知道为什么,查了一下,原来是用户没有正确的登录 Shell,需要指定一个(StackOverflow: How to fix “login: no shell: No such file or directory” when I can not even login?)。sudo chsh postgres -s /bin/zsh 之后再 su 果然可以了。再来:
1
2
3
4
5
6
7
8
|
/usr/lib/postgresql/13/bin/pg_upgrade \
--old-datadir=/home/postgres/12/main/ \ # 自定义
--new-datadir=/home/postgres/13/main/ \
--old-bindir=/usr/lib/postgresql/12/bin \
--new-bindir=/usr/lib/postgresql/13/bin \
--old-options '-c config_file=/etc/postgresql/12/main/postgresql.conf' \
--new-options '-c config_file=/etc/postgresql/13/main/postgresql.conf' \
--check
|
这次报错又不一样了:
1
2
|
could not open log file "pg_upgrade_internal.log": Permission denied
Failure, exiting
|
依旧是 Google 一下,StackOverflow: “cannot write to log file pg_upgrade_internal.log” when upgrading from Postgresql 9.1 to 9.3 再次给出满分答案。再次继续,再次碰到新(还是旧问题?):
1
|
could not open version file "/home/postgres/13/main/PG_VERSION": No such file or directory`
|
哦,我自己创建的 /home/postgres/13 原来是不行的,查了一下 /usr/lib/postgresql/13/bin/initdb -D /home/postgres/13/main 才可以初始化这个目录为 data cluster。最后再来一次 checck:
1
2
|
lc_collate values for database "postgres" do not match: old "zh_CN.utf8 ", new "en_US.UTF-8"
Failure, exiting
|
两个数据库的 locale 设置不一致,删掉 /home/postgres/13/main 这个目录重新指定 locale 初始化 /usr/lib/postgresql/13/bin/initdb -D /home/postgres/13/main --lc-collate="zh_CN.utf8" 终于提示 *Clusters are compatible* 了,可以开心的迁移了。命令还是上面的,去掉 check 就行了:
1
2
3
4
5
6
7
|
/usr/lib/postgresql/13/bin/pg_upgrade \
--old-datadir=/home/postgres/12/main/ \ # 自定义
--new-datadir=/home/postgres/13/main/ \
--old-bindir=/usr/lib/postgresql/12/bin \
--new-bindir=/usr/lib/postgresql/13/bin \
--old-options '-c config_file=/etc/postgresql/12/main/postgresql.conf' \
--new-options '-c config_file=/etc/postgresql/13/main/postgresql.conf'
|
一路顺畅,没什么问题,比想象中快。然后就可以分别启动 12 和 13 两个版本数据库确保数据没有问题。没问题就可以清理了:
1
2
3
|
./delete_old_cluster.sh
doas apt purge postgresql-12 postgresql-client-12
doas rm -rf /home/postgres/12 /var/lib/postgresql/12
|
至此就可以数据无损的情况下从 Postgres 12 迁移到 13 了。