实验环境:Linux Ubuntu 13.5
PostgreSQL版本: 13
服务器A:192.168.213.134
服务器B:192.168.213.135 (备份服务器)
主库是一直持续不断的提供服务的,即一直对主库有访问。而每天定时备份放在备份服务器上,是为了验证备份的可用性。本次实验使用了crontab创建定时任务,完成跨服务器的备份与恢复(恢复到指定时间点)。
一.服务器A开启日志归档
vim /etc/postgresql/13/main/postgresql.conf #开启日志归档,并修改恢复配置项\
wal_level = replica
archive_mode = on
archive_command ='cp %p /var/lib/postgresql/pgbackup/archive_wals/%f'
二. 在备份服务器B上创建定时备份脚本
2.1 创建并编写脚本内容
vim /var/lib/postgresql/backup.sh #创建并备份脚本脚本
内容如下:
#!/usr/bin/bash
DATE=$(date +%Y%m%d)
pg_basebackup -h 192.168.213.134 -D /var/lib/postgresql/pgbackup/bkdata_$DATE -Ft -z -P
#全量备份所有数据到 以备份日期命名的文件夹中
2.2 给脚本文件添加权限
chmod +x backup.sh #给脚本文件权限
2.3 检查并修正错误
完成以上操作后可用 ./backup.sh执行脚本文件,查看执行后的日志并修正显示的脚本错误。
**注意:**脚本的头部#!/usr/bin/bash 是为脚本设置的解释器,需要查看当前系统是否包含此解释器或路径是否与脚本头部相同;如果是脚本的解释器的路径有误,将脚本的头部的路径修改为当前系统的路径即可。若路径有误,可能会出现NO MTA installed,discarding output字样,导致crontab定时任务无法执行 可以用whereis查看,例如:
三.在备份服务器B上创建定时恢复脚本
3.1 创建并编写恢复脚本内容
vim /var/lib/postgresql/recovery.sh #创建并编写恢复脚本脚本
内容如下:
#!/usr/bin/bash DATE=$(date +%Y%m%d)
source ~/.bash_profile
/usr/lib/postgresql/13/bin/pg_ctl stop -m fast
echo '关闭服务器========================'
mv /var/lib/postgresql/13/main /var/lib/postgresql/13/main_old_data_$DATE
mkdir /var/lib/postgresql/13/main
chmod 0700 /var/lib/postgresql/13/main
echo '转移老数据,创建新的数据文件夹'
tar -xzvf /var/lib/postgresql/pgbackup/bkdata_$DATE/base.tar.gz -C /var/lib/postgresql/13/main
echo '解压备份文件到新数据文件夹'
tar -xzvf /var/lib/postgresql/pgbackup/bkdata_$DATE/pg_wal.tar.gz -C /var/lib/postgresql/13/main/pg_wal
echo '解压wal日志到新数据文件夹'
touch /var/lib/postgresql/13/main/recovery.signal
echo '创建恢复标记'
source ~/.bash_profile
/usr/lib/postgresql/13/bin/pg_ctl start
3.2 给脚本文件添加权限
chmod +x recovery.sh #给脚本文件权限
3.3 检查并修正错误
在执行了备份之后可以用 ./recovery.sh 执行脚本文件,查看执行后的日志并修正显示的脚本错误。
注意: 1.crontab执行计划任务时,它并不会从用户的profile文件中读取环境变量,所以会导致命令执行失败。source ~/.bash_profile是为了读取环境变量,内容如下:

2. 在Linux系统中,使用crontab执行脚本,由于crontab没有环境变量,它是找不到你使用的命令的,需要使用命令的全路径才可使用命令。
例如:/usr/lib/postgresql/13/bin/pg_ctl start 。
四. 加入定时任务
4.1 编辑定时任务
crontab -e #打开定时任务编辑页面编辑
内容如下:
56 18 * * * /var/lib/postgresql/backup.sh > /tmp/load.log 2>&1 &
#代表18:56执行backup.sh 并把所有日志输出到/tmp/load.log
24 19 * * * /var/lib/postgresql/recovery.sh > /tmp/load.log 2>&1 &
#代表19:24执行backup.sh 并把所有日志输出到/tmp/load.log
4.2 查看备份的输出日志
more /tmp/load.log #查看crontab输出日志

可知已完成备份。
4.3 查看系统日志
tail -n 50 /var/log/syslog #查看系统最后五十行的日志
可以查看到系统在18:56:01执行了脚本文件backup.sh 。

五.对数据库进行修改
在已经全量备份后的状态,我们可以对数据库做一些DML的操作,然后最后进行PITR的恢复来进行定时的备份恢复实践。全量备份进度可以通过vi /tmp/load.log进行查询。
5.1 查看表t2初始情况
psql -U postgres select * from t2; #查看表t2初始情况

5.2 对表t2做增删操作
insert into t2 values(4);
select now(); #此时时间 2021-12-28 18:59:30.541525+08
delete from t2 where id=2;
select * from t2; #查看表最后一次操作后的状态
select pg_switch_wal(); #切换下一个wal

六. 拷贝归档日志文件至备份服务器
在备份服务器定时恢复的时间之前,需要将新产生的wal文件拷贝到备份服务器中才能正常的进行恢复,所以在主服务器上输入:
scp /var/lib/postgresql/pgbackup/archive_wals/* postgres@192.168.213.135:/var/lib/postgresql/pgbackup/archive_wals
#将主服务器上新产生的wal文件全部拷贝到备份服务器B上

七. 修改恢复配置项
vim /etc/postgresql/13/main/postgresql.conf
restore_command = 'cp /var/lib/postgresql/pgbackup/archive_wals/%f %p'
recovery_target_time = '2021-12-28 18:59:30.541525+08'
#欲恢复至删除id=2数据之前的时间点
八. 等待自动恢复
到了定时恢复的时间后,可以通过vi /tmp/load.log查看crontab完整的执行情况,如下图:

九. 验证
如上,根据恢复配置项,数据库现在的状态应该是处于添加id=4之后,删除id=2之前,即表t2中应该含有id=2,3,4共三组数据,下一步进行验证。#在备服务器上查询表t2 `select * from t2;

定时备份、恢复成功。




