pg_rman 简介
pg_rman是一款专门为PostgreSQL数据库打造的优秀开源备份软件,其使用的思路类似Oracle的rman。此软件先前托管在sourceforge,现已移到了github上:
pg_rman的特点如下:
使用简单,一个命令即可完成备份和恢复
支持在线全备、增量备份、WAL日志的备份
支持备份压缩,通过gzip工具实现压缩
自动备份维护、自动删除过期的WAL备份文件
支持备份验证,通过使用文件的大小和数据块CRC实现校验
恢复期间无事务丢失,支持基于PITR的配置文件生成器
pg_rman最大的亮点就是实现了增量备份,注意不是基于WAL日志的增量备份,是基于上次全量备份之后发生的变化数据块的增量备份
pg_rman 部署
https://github.com/ossc-db/pg_rman/releases/
下载安装包,这里安装源码编译安装
unzip pg_rman-1.3.17.zip
cd pg_rman-1.3.17
vi .base_profie
参数说明
[postgres@lyp pg_rman-master]$ pg_rman --help
pg_rman manage backup/recovery of PostgreSQL database.
Usage:
pg_rman OPTION init #初始化
pg_rman OPTION backup #备份
pg_rman OPTION restore #恢复
pg_rman OPTION show [DATE] #查看历史备份
pg_rman OPTION show detail [DATE]
pg_rman OPTION validate [DATE] #验证备份
pg_rman OPTION delete DATE #删除备份
pg_rman OPTION purge #从备份目录中删除已实际的备份文件
Common Options:
-D, --pgdata=PATH location of the database storage area
-A, --arclog-path=PATH location of archive WAL storage area
-S, --srvlog-path=PATH location of server log storage area
-B, --backup-path=PATH #备份路径
-c, --check show what would have been done
-v, --verbose show what detail messages
-P, --progress show progress of processed files
Backup options:
-b, --backup-mode=MODE #备份类型,在增量备份之前要有全量full, incremental, or archive
-s, --with-serverlog also backup server log files
-Z, --compress-data compress data backup with zlib
-C, --smooth-checkpoint do smooth checkpoint before backup
-F, --full-backup-on-error switch to full backup mode
if pg_rman cannot find validate full backup
on current timeline
NOTE: this option is only used in --backup-mode=incremental or archive.
--keep-data-generations=NUM keep NUM generations of full data backup
--keep-data-days=NUM keep enough data backup to recover to N days ago
--keep-arclog-files=NUM keep NUM of archived WAL
--keep-arclog-days=DAY keep archived WAL modified in DAY days
--keep-srvlog-files=NUM keep NUM of serverlogs
--keep-srvlog-days=DAY keep serverlog modified in DAY days
--standby-host=HOSTNAME standby host when taking backup from standby
--standby-port=PORT standby port when taking backup from standby
Restore options:
--recovery-target-time time stamp up to which recovery will proceed
--recovery-target-xid transaction ID up to which recovery will proceed
--recovery-target-inclusive whether we stop just after the recovery target
--recovery-target-timeline recovering into a particular timeline
--recovery-target-action action the server should take once the recovery target is reached
--hard-copy copying archivelog not symbolic link
Catalog options:
-a, --show-all #查看所有被删除的备份
Delete options:
-f, --force #强制删除,当全备只有一个时,不允许删除,该参数可以强制删除
Connection options:
-d, --dbname=DBNAME database to connect
-h, --host=HOSTNAME database server host or socket directory
-p, --port=PORT database server port
-U, --username=USERNAME user name to connect as
-w, --no-password never prompt for password
-W, --password force password prompt
Generic options:
-q, --quiet don't show any INFO or DEBUG messages
--debug show DEBUG messages
--help show this help, then exit
--version output version information, then exit
1. 介绍
对于刚接触pg_rman的用户来说会有一些迷茫,使用上常常遇到一些问题,原因是对pg_rman的备份原理不是很清楚,所以这里把pg_rman的备份原理给介绍一下:
pg_rman不是使用流复制协议进行拷份的,而是使用文件拷贝,即先在主库上执行pg_start_backup()函数,然后拷贝整个数据库的数据目录,最后再执行 pg_stop_backup()函数来结束备份。
所以pg_rman必须和数据库节点跑在一起。否则可以想的到是是无法拷贝数据库的数据文件,从而无法备份。所以通常备份时,需要使用NAS等NFS共享方法把备份机的文件系统mount到数据库机器上。
pg_rman可以在standby节点上做全库的备份,但需要通过网络连接到主库上执行pg_start_backup和pg_stop_backup。
pg_rman需要主库打开了归档才能更好的备份,所以需要在postgresql.conf中打开归档,以便让pg_rman判断出数据库的归档目录在哪里。pg_rman主要是读取postgresql.conf文件中archive_command参数的值。
pg_rman还能备份PostgreSQL数据库的一般程序日志,即pg_log目录的日志文件。所以pg_rman会读取postgresql.conf中的log_directory参数以确定这些日志在哪个目录下。当然这些程序日志通常不是太重要,可以不备份。
注意:因为pg_rman是用postgresql.conf中读取archive_command和log_directory参数的值,如果你在PostgreSQL的配置文件使用了include其他文件或者配置在postgresql.auto.conf中,pg_rman读取到的这两个值将不准确,会导致一些问题,所以建议你仅仅把参数配置在postgresql.conf中,而不要使用其他配置文件
这里再说点题外话,pg_rman需要主库打开了归档才能更好的备份,这是有点不太方便。虽然在生产上的Oracle数据库中都是打开归档的,但在PostgreSQL中通常是可以不用打开归档的,原因是PostgreSQL中的归档与Oracle中的归档有些不一样。PostgreSQL中没有严格区分在线redo日志和归档,在PostgreSQL中每写满一个WAL日志后,如果打开了归档,就会调用参数“archive_command”指定的命令,此通常此命令就是把此WAL日志拷贝到另一个目录中,其实就是相当于备份到其它目录中。而PostgreSQL中可以通过流复制更实时接收WAL日志,所以不一定要用归档的模式来备份WAL日志。所以这也是pg_rman没有使用流复制导致在备份上产生的不太方便的地方。
pg_rman与rman一样都是把数据库备份到一个统一的备份仓库中,这个备份仓库中可以有多个全备份、多个增量备份,通过pg_rman的备份可以方便的看到这个备份仓库中有哪些备份,在后面的内容中会详细讲解这一些部分,这里主要是为了让大家知道pg_rman能做什么。一个备份仓库实际上就是一个目录,但pg_rman在这个目录中存有每次备份的信息,如某一次备份是全量备份还是增量份份,备份的结果是占用了多少G的空间,备份开始时间和结束时间等等信息。
pg_rman不能完成跨机器的备份,也就是备份的空间需要在与要备份的数据库在同一台机器上,同时pg_rman没有WEB管理界面。如果想实现这些功能,可以使用CLup软件, 具体见 CLup数据备份 。
通过上面的介绍,想必大家对pg_rman有了一个初步的认识,如果想有更深的认识,就需要看下面的更详细的内容了。
安装
pg_rman官方已为大家准备了方便的rpm安装包,在Redhat6.X和Redhat7.X(当然CentOS6.X和Cent7.X是一样)可以直接使用此rpm包,rpm包的下载路径为:
https://github.com/ossc-db/pg_rman/releases
网站上看到的rpm包的情况如下:
安装之前最好使用PostgreSQL官方的rpm安装好了PostgreSQL数据库软件,当安装pg_rman时,会安装到相应PostgreSQL软件的相应目录中去。
安装过程很简单,直接用rpm命令进行安装即可,如下所示:
rpm -ivh pg_rman-1.3.7-1.pg10.rhel7.x86_64.rpm
2. 初次使用
使用之前,当然要先有一个PostgreSQL,笔者通常喜欢系统原先的操作系统用户postgres删除掉,原因这个用户的home目录不是在/home/postgres目录下,而是在/var/目录下,笔者不喜欢。
笔者的建用户命令为:
groupadd -g 701 postgres
useradd -m -g postgres -u 701 postgres
有人问为何gid和uid为701,因为在笔者的机器上Oracle的uid使用的是501,MySQL的uid使用的是601,所以PostgreSQL使用的是701。
笔者通常在postgres用户的.bash_profile做下面的配置:
export PGDATA=~/pgdata
export PATH=/usr/pgsql-10/bin:$PATH
export LD_LIBRARY_PATH=/usr/pgsql-10/lib:$LD_LIBRARY_PATH
export PGHOST=/tmp
export LANG=en_US.UTF-8
为何要设置export PGHOST=/tmp
呢?原因是通过rpm包安装的PostgreSQL,会把socket doamin文件放到/var目录下,让psql不带任何命令行参数时无法直接登录数据库。当然在我的postgresql.conf中也有下面的配置:
unix_socket_directories = '/tmp'
注意原先的配置是unix_socket_directories = '/var/run/postgresql, /tmp
,把“/var/run/postgresql”删除掉了。
在使用pg_rman之前,要打开归档,在笔者的postgresql.conf中的打开归档的配置为:
archive_mode = on
archive_command = 'test ! -f /home/postgres/pgarch/%f && cp %p /home/postgres/pgarch/%f'
整个pg_rman就是一个命令行的工具,此程序的名称就是“pg_rman”,
[postgres@pg01 ~]$ which pg_rman
/usr/pgsql-10/bin/pg_rman
[postgres@pg01 ~]$ pg_rman --help
pg_rman manage backup/recovery of PostgreSQL database.
Usage:
pg_rman OPTION init
pg_rman OPTION backup
pg_rman OPTION restore
pg_rman OPTION show [DATE]
pg_rman OPTION show detail [DATE]
pg_rman OPTION validate [DATE]
pg_rman OPTION delete DATE
pg_rman OPTION purge
...
...
...
使用pg_rman之前需要先初始化一个备份仓库,所谓的备份仓库就是一个路径,当然我们需要保证这个路径下的文件系统有足够的空间。
可以设置一个环境变量BACKUP_PATH指向这个备份仓库的路径,如下所示:
export BACKUP_PATH=~/backups
当然也可以不设置BACKUP_PATH环境变量。如果此环境变量没有设置不指定,每次就需要用“-B”参数来指定这个路径,所有稍有点麻烦,建议还是设置上比较好,同样也设置在.bash_profile文件中。
在备份之前需要初使化一个备份仓库,用命令pg_rman init
完成备份仓库的初始化,如下所示:
[postgres@pg01 ~]$ pg_rman init -B ~/backups
INFO: ARCLOG_PATH is set to '/home/postgres/pgarch'
INFO: SRVLOG_PATH is set to '/home/postgres/pgdata/log'
当然因为我们设置了环境变量export BACKUP_PATH=~/backups
,所以上面的命令中不指定“-B”参数也是可以的。
初始化备份仓库实际上是在备份仓库下面建一些目录和元数据文件:
[postgres@pg01 ~]$ ll ~/backups/
total 8
drwx------ 4 postgres postgres 34 Nov 23 15:02 backup
-rw-rw-r-- 1 postgres postgres 77 Nov 23 15:02 pg_rman.ini
-rw-rw-r-- 1 postgres postgres 40 Nov 23 15:02 system_identifier
drwx------ 2 postgres postgres 6 Nov 23 15:02 timeline_history
这些元数据文件包括备份的配置文件“pg_rman.ini”、数据库的systemid、时间线文件历史等等,当然我们最需要关心的是配置文件“pg_rman.ini”,目前此文件的内容如下:
[postgres@pg01 ~]$ cat ~/backups/pg_rman.ini
ARCLOG_PATH='/home/postgres/pgarch'
SRVLOG_PATH='/home/postgres/pgdata/log'
下面我们就可以执行一次全备份了:
[postgres@pg01 ~]$ pg_rman backup --backup-mode=full
INFO: copying database files
INFO: copying archived WAL files
INFO: backup complete
INFO: Please execute 'pg_rman validate' to verify the files are correctly copied.
我们用pgbench对数据库产生一些变更,然后再做一次增量备份:
pgbench做一些变更:
[postgres@pg01 pgdata]$ pgbench -i
creating tables...
100000 of 100000 tuples (100%) done (elapsed 0.16 s, remaining 0.00 s)
vacuum...
set primary keys...
done.
执行增量备份的命令:
[postgres@pg01 ~]$ pg_rman backup --backup-mode=incremental --with-serverlog -B ~/backups
INFO: copying database files
ERROR: cannot take an incremental backup
DETAIL: There is no validated full backup with current timeline.
哎呀,增量备份怎么不成功,看日志信息“There is no validated full backup”是没有有效的全量备份,前面才做完全量备份怎么没有有效的全量备份呢?
原来pg_rman做完备份后,需要再用命令pg_rman validate
校验备份,检验备份没有问题之后,这个备份才成为有效的备份,在前面的全备份执行完后也有这方面的提示INFO: Please execute 'pg_rman validate' to verify the files are correctly copied.
。
这时我们可以用pg_rman show
查看备份情况,看看当前备份的状态是多少:
[postgres@pg01 ~]$ pg_rman show
=====================================================================
StartTime EndTime Mode Size TLI Status
=====================================================================
2018-11-23 17:45:36 2018-11-23 17:45:36 INCR 0B 1 ERROR
2018-11-23 17:45:07 2018-11-23 17:45:09 FULL 50MB 1 DONE
可以看到我们的全量备份的状态目前是DONE
的,这表示备份完成了,还没有校验,我们执行校验命令:
[postgres@pg01 ~]$ pg_rman validate
INFO: validate: "2018-11-23 17:45:07" backup and archive log files by CRC
INFO: backup "2018-11-23 17:45:07" is valid
然后用pg_rman show
查看状态:
[postgres@pg01 ~]$ pg_rman show
=====================================================================
StartTime EndTime Mode Size TLI Status
=====================================================================
2018-11-23 17:45:36 2018-11-23 17:45:36 INCR 0B 1 ERROR
2018-11-23 17:45:07 2018-11-23 17:45:09 FULL 50MB 1 OK
这时可以看到那个全量备份的状态从DONE
变成了OK
,这时就可以做增量备份了:
[postgres@pg01 ~]$ pg_rman backup --backup-mode=incremental --with-serverlog
INFO: copying database files
INFO: copying archived WAL files
INFO: copying server log files
INFO: backup complete
INFO: Please execute 'pg_rman validate' to verify the files are correctly copied.
[postgres@pg01 ~]$ pg_rman show
=====================================================================
StartTime EndTime Mode Size TLI Status
=====================================================================
2018-11-23 17:47:44 2018-11-23 17:47:46 INCR 67MB 1 DONE
2018-11-23 17:45:36 2018-11-23 17:45:36 INCR 0B 1 ERROR
2018-11-23 17:45:07 2018-11-23 17:45:09 FULL 50MB 1 OK
每次备份完成,不要忘了做pg_rman validate
:
[postgres@pg01 ~]$ pg_rman validate
INFO: validate: "2018-11-23 17:47:44" backup, archive log files and server log files by CRC
INFO: backup "2018-11-23 17:47:44" is valid
[postgres@pg01 ~]$ pg_rman show
=====================================================================
StartTime EndTime Mode Size TLI Status
=====================================================================
2018-11-23 17:47:44 2018-11-23 17:47:46 INCR 67MB 1 OK
2018-11-23 17:45:36 2018-11-23 17:45:36 INCR 0B 1 ERROR
2018-11-23 17:45:07 2018-11-23 17:45:09 FULL 50MB 1 OK
我们也可以用pg_rman delete
把之前的备份删除旧:
[postgres@pg01 ~]$ pg_rman delete '2018-11-23 17:45:36'
INFO: delete the backup with start time: "2018-11-23 17:45:36"
WARNING: cannot delete backup with start time "2018-11-23 17:45:07"
DETAIL: This is the latest full backup necessary for successful recovery.
[postgres@pg01 ~]$ pg_rman show
=====================================================================
StartTime EndTime Mode Size TLI Status
=====================================================================
2018-11-23 17:47:44 2018-11-23 17:47:46 INCR 67MB 1 OK
2018-11-23 17:45:07 2018-11-23 17:45:09 FULL 50MB 1 OK
注意:删除备份时指定的时间点“2018-11-23 17:45:36”,并不是表示把这个时间点的备份删除掉,而是删除掉不需要的备份,让剩下的备份集能恢复这个时间点,一定要记住!!!,所以上面的命令的意思是在执行完删除操作之后,保证剩下的备份集能够恢复到“2018-11-23 17:45:36”这个时间点。
实际上,pg_rman delete
虽然把备份删除掉了,但是一些备份信息仍然遗留在元数据中,这些信息用pg_rman show -a
还能看到:
[postgres@pg01 backups]$ pg_rman show -a ===================================================================== StartTime EndTime Mode Size TLI Status ===================================================================== 2018-11-23 17:47:44 2018-11-23 17:47:46 INCR 67MB 1 OK 2018-11-23 17:45:36 2018-11-23 17:45:36 INCR 0B 1 DELETED 2018-11-23 17:45:07 2018-11-23 17:45:09 FULL 50MB 1 OK
这时需要用pg_rman purge命令清除掉已删除的备份的元信息:
[postgres@pg01 backups]$ pg_rman purge INFO: DELETED backup "2018-11-23 17:45:36" is purged [postgres@pg01 backups]$ pg_rman show -a ===================================================================== StartTime EndTime Mode Size TLI Status ===================================================================== 2018-11-23 17:47:44 2018-11-23 17:47:46 INCR 67MB 1 OK 2018-11-23 17:45:07 2018-11-23 17:45:09 FULL 50MB 1 OK
pg_rman.ini 文件
pg_rman初始化之后会在备份目录中产生 pg_rman.ini 文件,基于该文件可以制定备份策略,在进行备份操作时会自动检查
KEEP_ARCLOG_FILES = 10 --保存归档文件个数
KEEP_SRVLOG_FILES = 10 --保存日志文件个数
KEEP_DATA_GENERATIONS=4 --保留4份全备数量
KEEP_DATA_DAYS=30 --数据保留30天,
KEEP_ARCLOG_DAYS=35 --WAL日志保留60天
KEEP_SRVLOG_DAYS=180 --LOG日志保留180天数
参考文章
评论