1.版本信息
升级前 | 升级后 |
postgresql-14.11 | postgresql-16.2 |
2.升级准备
PostgreSQL 的大版本通常不会改变内部数据存储格式,但可能会有一些系统表结构变更
以及内置函数的变化等,使得升级并不像小版本那么容易。大版本的升级可以将数据以存
储的方式转储到文件,再将转储的数据文件导入到新版本中,也可以通过 pg_upgrade 进
行升级,还可以通过逻辑复制的方式进行版本升级,为数据库版本升级提供了更多的便利。
常用的大版本升级方法和适用场景如下:
升级方法 | 使用场景 | 停机时间 |
逻辑备份与还原
|
中小型数据库,例如小于 100 GB,支持跨平台数据迁移
|
取决于数据库的 大小
|
pg_upgrade 工具
|
大中型数据库,例如大于 100 GB,本机就地升级
| 几分钟 |
逻辑复制
|
大中型数据库,例如大于 100 GB,跨平台支持
| 几秒钟 |
无论采用了哪一种升级方式,升级之前的应用程序测试、数据库功能测试、连接驱动测试
都是非常必要的。数据库管理员在升级之前还应该做好升级失败的应对措施,尽可能保留
一份升级前的副本,以应对意外时的快速回滚。
3.升级步骤
注:
使用 pg_dumpall 方式升级,也就是转储方式升级,实际上是将数据库在旧版本中先备份,
备份结束后在新版本中进行还原的过程,需要有一定时间的停机维护窗口,升级持续的时
间主要取决于数据量的大小和磁盘的写入速度,如果数据量很大,升级会持续很长时间,
所以在升级之前一定要规划好停机维护时间。 使用转储方式升级也有一些优点。通过一次全库的转储和恢复的过程,新版本的数据库会 比较纯净,一些遗留的、未能回收的垃圾都可以清理干净
3.1设置旧库为只读状态
vi postgresql.conf
default_transaction_read_only=on
&&或者使用命令
ALTER SYSTEM SET default_transaction_read_only = 'on';
重启数据库:
pg_ctl stop
pg_ctl start
- 下载新源码包(注意:如果使用源码编译安装,需要注意安装文件除了 --prefix 之外的编译参数和旧版本保持一致)
[root@localhost postgresql]# wget https://ftp.postgresql.org/pub/source/v16.2/postgresql-16.2.tar.bz2
[root@localhost postgresql]# tar -xvf postgresql-16.2.tar.bz2
3.2源码编译安装新版本
[root@localhost postgresql-16.2]# mkdir -p /usr/local/pgsql16.2
#安装依赖包
[root@localhost postgresql-16.2]# yum install libicu-devel.x86_64 python3 python3-devel
[root@localhost postgresql-16.2]# ./configure --prefix=/usr/local/pgsql16.2 --with-perl --with-python --with-libxml --with-libxslt --with-openssl
[root@localhost postgresql-16.2]# make && make install
[root@localhost local]# unlink pgsql
[root@localhost local]# ln -s /usr/local/pgsql16.2 /usr/local/pgsql
[root@localhost local]# ll
total 0
drwxr-xr-x. 2 root root 6 Apr 11 2018 bin
drwxr-xr-x. 2 root root 6 Apr 11 2018 etc
drwxr-xr-x. 2 root root 6 Apr 11 2018 games
drwxr-xr-x. 2 root root 6 Apr 11 2018 include
drwxr-xr-x. 2 root root 6 Apr 11 2018 lib
drwxr-xr-x. 2 root root 6 Apr 11 2018 lib64
drwxr-xr-x. 2 root root 6 Apr 11 2018 libexec
lrwxrwxrwx 1 root root 20 May 2 06:45 pgsql -> /usr/local/pgsql16.2
drwxr-xr-x 6 root root 56 May 2 04:33 pgsql14.11
drwxr-xr-x 6 root root 56 Apr 29 08:06 pgsql14.6
drwxr-xr-x 6 root root 56 May 2 06:42 pgsql16.2
drwxr-xr-x. 2 root root 6 Apr 11 2018 sbin
drwxr-xr-x. 5 root root 49 Oct 5 2018 share
drwxr-xr-x. 2 root root 6 Apr 11 2018 src
[root@localhost local]# su - postgres
Last login: Thu May 2 04:44:39 UTC 2024 on pts/1
[postgres@localhost ~]$ mkdir /home/postgres/pgdata16
[postgres@localhost ~]$ ll /home/postgres/
total 8
-rw------- 1 postgres postgres 997 Apr 30 02:02 logfile
drwx------ 19 postgres postgres 4096 May 2 04:44 pgdata
drwxrwxr-x 2 postgres postgres 6 May 2 06:49 pgdata16
[postgres@localhost ~]$
[postgres@localhost ~]$ initdb --locale C -D /home/postgres/pgdata16/ -W
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.
[postgres@localhost ~]$ cd /home/postgres/pgdata16/
#根据实际情况修改如下文件
[postgres@localhost pgdata16]$ vim postgresql.conf&pg_hba.conf&pg_ident.conf
[postgres@localhost pgdata16]$ vim postgresql.conf #这里测试环境只修改了端口
port = 5433 # (change requires restart)
max_connections = 100 # (change requires restart)
#启动服务
[postgres@localhost pgdata16]$ pg_ctl start -D /home/postgres/pgdata16/
waiting for server to start....2024-05-02 06:57:29.862 UTC [3995] LOG: starting PostgreSQL 16.2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44), 64-
server started
[postgres@localhost pgdata16]$
3.3升级到新版本
[postgres@localhost pgdata]$ export LD_LIBRARY_PATH=/usr/local/pgsql16.2/lib
[postgres@localhost pgdata]$
[postgres@localhost pgdata]$ pg_dumpall -p 5432 | psql -p 5433
SET
SET
SET
ERROR: role "postgres" already exists #忽略报错
ALTER ROLE
You are now connected to database "template1" as user "postgres".
SET
SET
SET
SET
SET
set_config
------------
(1 row)
SET
SET
SET
SET
You are now connected to database "postgres" as user "postgres".
SET
SET
SET
SET
SET
set_config
------------
(1 row)
SET
SET
SET
SET
[postgres@localhost pgdata]$
3.4验证升级后的数据
[postgres@localhost pgdata]$ psql -p 5433
psql (16.2)
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Locale Provider | Collate | Ctype | ICU Locale | ICU Rules | Access privileges
-----------+----------+-----------+-----------------+---------+-------+------------+-----------+-----------------------
postgres | postgres | SQL_ASCII | libc | C | C | | |
template0 | postgres | SQL_ASCII | libc | C | C | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
template1 | postgres | SQL_ASCII | libc | C | C | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
testdb | postgres | SQL_ASCII | libc | C | C | | |
(4 rows)
postgres=# \c testdb
You are now connected to database "testdb" as user "postgres".
testdb=# \d
List of relations
Schema | Name | Type | Owner
--------+------+-------+----------
public | t1 | table | postgres
(1 row)
testdb=# select * from t1;
id | name
----+------------
1 | lxg
(1 row)
testdb=#