PostgreSQL版本发布规则,一年一个大版本,一个季度一个小版本;PG遇到的BUG问题,社区会很快进行修复,并在下一个版本中发布,因此有必要进行对数据库版本升级,避免触发已知的BUG带来业务系统的不稳定。本文主要分享一下,PG小版本升级、跨版本升级和借助逻辑复制进行数据库升级。
PG小版本的迭代不会改变内部的存储格式,因此升级小版本只需要安装最新版本后,使用新版本重新启动数据库即可。
安装最新版本数据库
停止数据库实例
对数据目录进行备份
使用新版本启动数据库
调整环境变量,PGHOME/LD_LIRARAY_PATH等
注意:在安装新版本数据库时,要保证数据库块大小一致。
PG大版本升级,在9.4版本之间只能通过pg_upgrade进行,9.4版本之后可以通过第三方扩展插件pg_logical进行逻辑复制升级;10版本社区加入了逻辑复制功能,可以借助逻辑复制进行升级。
使用pg_dumpall和pg_dump进行逻辑转储恢复升级
使用pg_dumpall备份全局信息,角色和表空间
pg_dumpall-f /tmp/global.sql -g -d postgres -h 127.0.0.1 -p 5432 -U postgres
备份数据
pg_dump-f /tmp/data.sql -h 127.0.0.1 -d dbname -c -C -F p -E utf8 -Upostgres
在新版本数据库中进行恢复
psql-h 127.0.0.1 -d postgres < /tmp/global.sql
psql-h 127.0.0.1 -d postgres < /tmp/data.sql
注意:当数据库较大时,备份恢复耗时较久,严重影响业务
使用pg_upgrade进行升级
pg_upgrade是官方提供的版本升级工具,有普通模式和Link模式两种升级模式。在普通模式下,会把旧版本的数据拷贝到新版本中,需要确保有足够的磁盘空间存储新旧两份数据;Link模式下,只是在新版本的数据目录中建立了旧版本数据文件的硬连接,可以有效减少磁盘占用的空间。
在升级之前建议使用pg_upgrade-c参数检查新旧版本的兼容性,把每一项不兼容的问题解决后才可以顺利升级,-c参数只会检查新旧版本兼容性,不会运行真正的升级程序,不会修改数据文件,在运行结束后,会输出兼容性结果。
安装新版本并初始化数据目录
如果使用源码编译安装,configure配置和原库一致。可以使用pg_config查看旧版本数据库安装时的配置参数。
检查新旧版本兼容性
pg_upgrade-b /data/old_base -B /data/new_base -d /data/old_data -D/data/new_data -c -p 5432 -P 5433
所有的选项都是OK状态表示,校验通过;否则说明不兼容,根据提示信息进行处理。
停止旧版本数据库
pg_ctlstop -D /data/old_base 并修改pg_hba.conf为本地trust模式
使用pg_upgrade普通模式升级
pg_upgrade-b /data/old_base -B /data/new_base -d /data/old_data -D/data/new_data -p 5432 -P 5433
升级完成后,会生成两个脚本,analyze_new_cluster.sh,该脚本主要是分析收集新库的统计信息等;delete_old_cluster.sh是删除旧数据库的数据。
升级完成后修改相关环境变量并进行数据库验证
借助逻辑复制进行版本升级
逻辑复制功能,从10版本开始内置支持,也可以使用第三方逻辑复制插件pg_logical。逻辑复制是基于逻辑解析,主库将表中的WAL日志解析成一定格式并发送给逻辑备库,逻辑备库收到解析后的WAL日志进行重做,从而实现表数据同步。注意:WAL_LEVEL要设置为LOGICAL级别。
逻辑复制的限制:
目前不支持DDL解析,只能解析INSERT/UPDATE/DELETE/TRUNCATE
TEMPORARY表和UNLOGGED表不被复制
表必须有PRIMARY KEY或者唯一约束,否则UPDATE、DELETE操作无法复制
序列不被复制
大对象不被复制
新增加的表,不会自动加入订阅
逻辑复制升级步骤:
转储全局信息,角色、表空间
pg_dumpall-f /tmp/global.sql -g -d postgres -h 127.0.0.1
转储表结构信息
pg_dump-Fc -s -d postgres -p 5411 -U postgres -f /tmp/lrtest_schema.dmp
在目标端恢复上述备份
在源数据库上创建发布
createpublication test_pg12_upgrade_pub for all tables;
在目标端创建订阅
createsubscription test_pg12_upgrade_sub connection 'port=5432dbname=postgres user=postgres password=root' publicationtest_pg12_upgrade_pub;
默认会复制源端表中现有数据。
监控复制
select * from pg_stat_replication;