PostgreSQL在线增量备份与PITR还原

1、准备工作
1.1、wal日志级别
wal_level=archive 或 hot_standby 或 更高级别。
如果要使用pg_basebackup通过流复制协议远程备份,建议使用hot_standby及以上级别的wal。 pg9.6后映射到replica。

查看当前数据库wal_level:

itm_pg@docker-> pg_controldata |grep wal_level  
wal_level setting:                    replica

1.2、归档模式

archive_mode = on

1.3、归档命令
首先要创建用于存放wal归档文件目录, 数据库启动用户需要写权限。
itm_pg@docker-> mkdir -p /home/itm_pg/archdir
itm_pg@docker-> chmod 700 /home/itm_pg/archdir
然后在$PGDATA目录下创建归档脚本:

itm_pg@docker-> vi archive.sh

#!/bin/bash

export LANG=en_US.utf8  
export PGHOME=/home/itm_pg/pgsql10.3  
export LD_LIBRARY_PATH=$PGHOME/lib:/lib64:/usr/lib64:/usr/local/lib64:/lib:/usr/lib:/usr/local/lib:$LD_LIBRARY_PATH  
export DATE=`date +"%Y%m%d"`  
export PATH=$PGHOME/bin:$PATH:.  

BASEDIR="/home/itm_pg/archdir"  

if [ ! -d $BASEDIR/$DATE ]; then  
  mkdir -p $BASEDIR/$DATE  
  if [ ! -d $BASEDIR/$DATE ]; then  
    echo "error mkdir -p $BASEDIR/$DATE"  
    exit 1  
  fi  
fi  

cp $1 $BASEDIR/$DATE/$2  
if [ $? -eq 0 ]; then  
  exit 0  
else  
  echo -e "cp $1 $BASEDIR/$DATE/$2 error"  
  exit 1  
fi  

echo -e "backup failed"  
exit 1

给archive.sh添加可执行权限:
itm_pg@docker->chmod 700 archive.sh

在postgresql.conf中配置归档命令:
archive_command = ‘archive.sh %p %f’

建议设置work process,sender进程数,才可以通过pg_basebackup使用流复制协议进行备份。必须大于0,每个流复制连接需要一个wal sender进程。
max_worker_processes = 16
max_wal_senders = 8

建议设置wal_keep_segments,确保非常大的数据库,在漫长的备份时间周期内xlog不被覆盖。注意配置之后,pg_xlog至少会占用wal_keep_segments * wal文件大小 的空间。
wal_keep_segments = 1024
然后重启数据库即可。

2、备份
进行完上述配置后,就可以进行在线备份了。注意不能使用pg_dump之类的方法备份,因为逻辑备份没有增量备份的概念。
这里推荐使用的方法有:拷贝(cp命令)、rsync、pg_basebackup。本实验使用拷贝的方式进行。

首先在数据库中以超级用户执行:

itm_pg@docker-> psql
psql (10.3)
Type "help" for help.

postgres=# select pg_start_backup(now()::text);  
 pg_start_backup 
-----------------
 0/15000060
(1 row)

注意这个命令执行的目的并不是开始备份,而是在$PGDATA中记录一个标签文件, 包含标签名now()::text, 以及执行这条指令的启动时间和WAL位置。

可以查看标签文件信息:

itm_pg@docker-> cat backup_label 
START WAL LOCATION: 0/15000060 (file 000000010000000000000015)
CHECKPOINT LOCATION: 0/15000098
BACKUP METHOD: pg_start_backup
BACKUP FROM: master
START TIME: 2019-02-13 11:05:35 CST
LABEL: 2019-02-13 11:05:35.290332+08
然后拷贝文件:
itm_pg@docker-> cp -r -L $PGDATA /home/itm_pg/archdir/online_backup

拷贝完后清除备份文件中pg_xlog和pg_log中的内容, 因为这些是不需要的。
itm_pg@docker-> cd pg_wal/
itm_pg@docker-> rm -rf *
注:备份文件中若存在postmaster.pid 文件也需要删除!

然后使用超级用户在数据库中执行:

postgres=# select pg_stop_backup(); 
NOTICE:  pg_stop_backup complete, all required WAL segments have been archived
 pg_stop_backup 
----------------
 0/15000168
(1 row)

至此,备份就已经完成!

3、PITR还原

postgres=# create table pitr_test(id int, info text);  
CREATE TABLE
postgres=# insert into pitr_test values (1,'test'); 
INSERT 0 1
postgres=# begin;
BEGIN
postgres=# insert into pitr_test values (2,'test');
INSERT 0 1
postgres=# select pg_create_restore_point('pitr_test');  
 pg_create_restore_point 
-------------------------
 0/1601D100
(1 row)

postgres=# insert into pitr_test values (3,'test'); 
INSERT 0 1

切换日志,归档
postgres=# checkpoint;
CHECKPOINT
postgres=# select pg_switch_wal();
使用拷贝的备份和归档日志进行还原:

先关闭数据库:

itm_pg@docker-> pg_ctl stop -m fast
waiting for server to shut down… done
server stopped
删除数据目录及表空间文件目录:
itm_pg@docker-> cd pg_tblspc/
itm_pg@docker-> ll
total 0
itm_pg@docker-> cd $PGDATA
itm_pg@docker-> rm -rf *
还原备份(如果有表空间软链接也需要还原):
itm_pg@docker-> cp -r /home/itm_pg/archdir/online_backup/* $PGDATA/

配置recovery.conf文件:
itm_pg@docker-> cp $PGHOME/share/recovery.conf.sample ./recovery.conf
itm_pg@docker-> vi recovery.conf

restore_command = ‘recovery.sh /home/itm_pg/archdir/ %f %p’
recovery_target_name = ‘pitr_test’
recovery_target_timeline = ‘latest’
创建恢复脚本:
itm_pg@docker-> vi recovery.sh

#!/bin/bash  

export LANG=en_US.utf8  
export PGHOME=/home/itm_pg/pgsql10.3  
export LD_LIBRARY_PATH=$PGHOME/lib:/lib64:/usr/lib64:/usr/local/lib64:/lib:/usr/lib:/usr/local/lib:$LD_LIBRARY_PATH  
export DATE=`date +"%Y%m%d"`  
export PATH=$PGHOME/bin:$PATH:.  

BASEDIR=$1  

find $BASEDIR -name $2 -exec cp {} $3 /;

itm_pg@docker-> chmod 700 recovery.sh

启动数据库:
itm_pg@docker-> pg_ctl start
waiting for server to start….2019-02-13 11:18:32.988 CST [12365] LOG: 00000: listening on IPv4 address “0.0.0.0”, port 1921
2019-02-13 11:18:32.988 CST [12365] LOCATION: StreamServerPort, pqcomm.c:593
2019-02-13 11:18:32.988 CST [12365] LOG: 00000: listening on IPv6 address “::”, port 1921
2019-02-13 11:18:32.988 CST [12365] LOCATION: StreamServerPort, pqcomm.c:593
2019-02-13 11:18:32.989 CST [12365] LOG: 00000: listening on Unix socket “./.s.PGSQL.1921”
2019-02-13 11:18:32.989 CST [12365] LOCATION: StreamServerPort, pqcomm.c:587
2019-02-13 11:18:33.014 CST [12365] LOG: 00000: redirecting log output to logging collector process
2019-02-13 11:18:33.014 CST [12365] HINT: Future log output will appear in directory “log”.
2019-02-13 11:18:33.014 CST [12365] LOCATION: SysLogger_Start, syslogger.c:634
done
server started
验证还原点是否和预计匹配:

itm_pg@docker-> psql
psql (10.3)
Type "help" for help.

postgres=# select ctid,* from pitr_test ; 
 ctid  | id | info 
-------+----+------
 (0,1) |  1 | test
(1 row)

你可能感兴趣的:(PostgreSQL,PostgreSQL)