一、简述

pg 9.1z之前,没有能和oracle的 rman相匹配的物理备份命令。开始github上有人分享了pg_rman备份命令,功能和 oracle的 rman类似,但是性能上有些。。。。

二、pg_rman简介

pg_rman就不做测试了,感兴趣的同学可以去github clone练习:pg_rman on Github 这个使用了pg 官方文档推荐的物理备份的机制:pg_start_backup()=>copy=>pg_stop_backup()的备份模式 。其用的不是流复制,而是文件拷贝。如果是在主库使用pg_rman备份,还是很方便。如果是在备库,就有些鸡肋。因为pg 的备库不能产生归档,所以需要通过nfs将主库的归档mount到 备库服务器,或者更改pg_rman归档目录为 pg_wal目录(这样做比较危险,容易误删 wal,所以不推荐这种方式)。

三、pg_basebackup简介

不过 从pg 9.1 推出了 pg_basebackup之后,这种情况有了很大的改善。pg_basebackup不仅可以用于搭建流复制环境,还可以用于数据库备份,可以说是dba的一大利器。常说,备份是重中之重,这是有道理的。

四、pg_basebackup工作原理

敲下命令回车之后,首先创建检查点,打开FPW,创建备份标签(存储检查点位置,时间等信息);通过流复制协议与数据库建立连接 ; WAL Sender进程向pg_basebackup发送数据库物理文件; pg_basebackup接收到文件后写入目标位置(压缩或不压缩)。pg_basebackup可以在备库直接运行。

五、分享一个备份脚本

  • wechat.py 是微信的告警脚本,这个可以采用自己熟悉的报警方式
  1. ##===========================================================
  2. ## pg_basebackup.sh
  3. ## created by sam
  4. ## 2020/03/16
  5. ## usage: pg_basebackup.sh
  6. ##============================================================
  7. source /home/postgres/.bash_profile
  8. set -o xtrace
  9. DATE=`date +%Y%m%d`;
  10. BACK_BASE=/backup
  11. SBIN_PATH=$BACK_BASE/sbin
  12. BACK_TODAY=$BACK_BASE/PGBK_${DATE}
  13. BACK_LOG=$BACK_BASE/logs/pg_basebackup_${DATE}.log
  14. #START BACKUP
  15. echo "`date +"%Y-%m-%d %H:%M:%S"` : START BACKUP............................................" > $BACK_LOG
  16. echo "`date +"%Y-%m-%d %H:%M:%S"` : Today backupset is in $BACK_TODAY" >> $BACK_LOG
  17. #执行备份命令
  18. # pg_basebackup --help
  19. # -F, --format=p|t output format (plain (default), tar)
  20. # -P, --progress show progress information
  21. # -v, --verbose output verbose messages
  22. # -X, --wal-method=none|fetch|stream include required WAL files with specified method
  23. # -z, --gzip compress tar output
  24. # -Z, --compress=0-9 compress tar output with given compression level
  25. # -R, --write-recovery-conf write configuration for replication
  26. pg_basebackup -Ft -Pv -Xf -z -Z2 -R -p 5432 -D $BACK_TODAY >> $BACK_LOG
  27. #检查备份是否成功
  28. if [[ $? -ne 0 ]];then
  29. message="Postgres 数据库服务器`hostname`在${DATE}备份失败"
  30. # 报警方式:微信,短信,邮件.....
  31. # python3 $SBIN_PATH/wechat.py $message
  32. echo "0"
  33. fi
  34. #保留最近2天备份集
  35. find $BACK_BASE -ctime +2 -name "PGBK_*" -exec rm -rf {} \; >> $BACK_LOG
  36. find $BACK_BASE/logs -ctime +2 -name "pg_basebackup_*" -exec rm -rf {} \; >> $BACK_LOG
  37. echo "`date +"%Y-%m-%d %H:%M:%S"` : BACKUP END............................................" >> $BACK_LOG

六、 pg_basebackup恢复数据库

几个关键变量设置好

  • PGDATA :数据库所在目录
  • ARCLOG:归档目录

6.1 解压备份文件

tar -xvf base.tar  -C $PGDATA

6.2 复制pg_wal目录下的日志文件至archive目录下

`cp $PGDATA/pg_wal/* $ARCLOG/

6.3 修改postgresql.auto.conf

restore_command = 'cp $ARCLOG/%f %p'

6.4 启动备机数据库,恢复完成

pg_ctl -D $PGDATA start

6.5 几种不同的恢复方式

通过修改postgresql.auto.conf来显示

  • 恢复到最新:
restore_command = 'cp $ARCLOG/%f %p' 
recovery_target_timeline = 'latest'
  • 恢复到指定的时间点:
restore_command = 'cp $ARCLOG/%f %p' 
recovery_target_time = '2020-03-16 13:16:49.007657+08'
  • 恢复到还原点:
    在备份开始时,创建还原点,然后恢复时可以指定恢复到还原点
SELECT pg_create_restore_point('restore_point1');

恢复到还原点:

restore_command = 'cp $ARCLOG/%f %p' 
recovery_target_name ='restore_point1'