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)