下载地址:
ossc-db/pg_rman: Backup and restore management tool for PostgreSQL (github.com)https://github.com/ossc-db/pg_rman代码由日本电信的运维团队维护。
针对不同的PostgreSQL版本,使用不同的分支编译,我的PG版本试12.6,对应的分支为REL_12_STABLE。
pg_rman的编译要依赖PG的源码,或者是包含PG头文件和库文件的PG安装包,我之前从源码编译安装了PG,所以只要设置了PATH和LD_LIBRARY_PATH就行,本质上,编译pg_rman时,是使用了PG安装文件中的pg_config,来设置头文件和库文件的编译选项。
git clone https://github.com/ossc-db/pg_rman.git
cd pg_rman
git co -b rel_12_stable origin/REL_12_STABLE
make
make install
# make install 将pg_rman安装到PostgreSQL安装目录的bin目录下
如果是第一次用,要初始化,使用pg_rman有个前提,就是要求PG服务端要开启归档日志,即archive_mode要设为on或always, 同时设置archive_command,这是必须的。
对于Oracle DBA,大多数情况,pg_rman中的概念,可以对比Oracle的RMAN。
pg_rman init \
-B /mnt/disk01/debug-PostgreSQL/bkp-dir \
-D /mnt/disk01/debug-PostgreSQL/_pg_root \
-S /mnt/disk01/debug-PostgreSQL/log \
-A /mnt/disk01/debug-PostgreSQL/arcdir
INFO: ARCLOG_PATH is set to '/mnt/disk01/debug-PostgreSQL/arcdir'
INFO: SRVLOG_PATH is set to '/mnt/disk01/debug-PostgreSQL/log'
-B 是设置pg_rman的工作目录,要求绝对路径,存储的是pg_rman的元数据、备份的数据,对应的环境变量是 BACKUP_PATH。
-D 是PG数据目录,要求绝对路径,是PG初始化时创建的那个目录,对应的环境变量是 PGDATA。
-S 是PG的运行日志所在目录,即postgresql.conf中log_directory参数指向的路径,要求绝对路径,注意这个不是WAL目录或归档日志目录,对应的环境变量是 SRVLOG_PATH。
-A 是PG的归档日志所在目录,即postgresql.conf中archive_command中保存归档日志命令的目的路径,要求绝对路径,对应的环境变量是 ARCLOG_PATH。
这些参数最好设置环境变量,不然每个命令都要带着。
pg_rman和Oracle的RMAN不同的是,并不是执行pg_rman后进入一个命令行环境,而是pg_rman后面紧接着子命令,一个pg_rman + 子命令,完成一个任务。
pg_rman支持下面一些子命令:
假设已经设置了下面的环境变量
export BACKUP_PATH=/mnt/disk01/debug-PostgreSQL/bkp-dir
export SRVLOG_PATH=/mnt/disk01/debug-PostgreSQL/log
export ARCLOG_PATH=/mnt/disk01/debug-PostgreSQL/arcdir
export PGDATA=/mnt/disk01/debug-PostgreSQL/_pg_root
PG服务器已经启动,并且使用默认端口5432,pg_man和PG服务器在同一台机器上
pg_rman backup -b full
# 之后还要执行validate,这样这个备份才可用,才能用来恢复
pg_rman validate
# 增量备份
pg_rman backup -b incremental
pg_rman validate
# 查看备份
pg_rman show
[postgres@qinh154 debug-PostgreSQL]$ pg_rman show
=====================================================================
StartTime EndTime Mode Size TLI Status
=====================================================================
2023-10-07 17:14:18 2023-10-07 17:14:20 INCR 33MB 1 OK
2023-10-07 17:06:46 2023-10-07 17:06:49 FULL 84MB 1 OK
# 备份归档日志也很有用,缺点是太占空间
pg_rman backup -b archive
pg_rman validate
pg_rman show
=====================================================================
StartTime EndTime Mode Size TLI Status
=====================================================================
2023-10-07 17:17:01 2023-10-07 17:17:02 ARCH 16MB 1 OK
2023-10-07 17:14:18 2023-10-07 17:14:20 INCR 33MB 1 OK
2023-10-07 17:06:46 2023-10-07 17:06:49 FULL 84MB 1 OK
pg_rman的备份以时间作为id,所以选择备份用来恢复时,通过选择StartTime或EndTime,删除备份也是如此。
恢复需要先停PG服务器,假设已经设置了下面的环境变量:
export BACKUP_PATH=/mnt/disk01/debug-PostgreSQL/bkp-dir
export SRVLOG_PATH=/mnt/disk01/debug-PostgreSQL/log
export ARCLOG_PATH=/mnt/disk01/debug-PostgreSQL/arcdir
export PGDATA=/mnt/disk01/debug-PostgreSQL/_pg_root
可以通过--recovery-target-time和--recovery-target-timeline指定恢复到时间点附近的备份:
pg_rman restore --recovery-target-time='2023-10-07 15:31:28' --recovery-target-timeline=2
或直接 pg_rman restore 恢复到最新的备份。
注意,pg_rman的备份恢复时基于pg_basebackup的,因此备份其实是在做basebackup,而恢复时用备份的basebackup覆盖当前的数据目录,因此postgresql.conf都会恢复为备份时的设置。
恢复其实分两步:
第一步是PG服务器停机时restore,即用备份的数据目录覆盖当前的数据目录。
第二步是recovery,即利用PG自己的恢复机制,pg_rman在postgresql.conf里设置好恢复时间和时间线,创建recovery.signal :
restore_command = 'cp /mnt/disk01/debug-PostgreSQL/arcdir/%f %p'
recovery_target_time = '2023-10-07 17:14:18'
recovery_target_timeline = '1'
然后,启动PG服务器,PG服务器就按照配置自动恢复了,如果恢复完成,PG服务器会自动删除 recovery.signal,注意不要手动删除recovery.signal,有时候可能很长时间不能恢复完成,可以登录PG服务器执行select pg_is_in_recovery()查看状态,如果为t则仍然在恢复中,此时数据库是不可写的,此时查看日志应该提示登录PG服务器并且执行
select pg_wal_replay_resume();
还有,就是恢复完成后,要记得手动删除这三个参数!
这里有个细节要注意:在recovery时,postgresql.conf 中开启归档日志的参数archive_mode,最好是on,如果是always,那么在recovery时也会产生归档日志,这样会与归档日志目录下原有的归档日志,在文件名上有冲突,而用on,在recovery时就不会产生归档日志。