postgresql中提供了pitr作为增备的方案,在全量物理备份的基础上通过wal文件的备份来提供所有数据修改的记录,当需要还原的时候通过wal日志回放进行数据还原,还原后面在讲,本帖主要说明通过脚本和crontab定时任务来对数据库进行定期的自动全量备份和pitr增量备份,避免一个基础备份+长时间备份日志造成回滚或者还原话费大量的时间。
1、编写 base_backup.sh,提供定期全量基础备份。
该脚本执行过程中,会先执行pg_start_backup() 函数,然后开始进行整个$PGDATA目录压缩,完毕后执行 pg_stop_backup() 函数进行备份退出。所有完成后清理旧的全量备份文件。
#!/bin/bash base_dir="/home/lyf/pgback/back_9.6" pirt_dir="/home/lyf/pgback/back_9.6" pg_home="/home/lyf/9.6/pg9.6" pg_port=5555 pg_data="/home/lyf/9.6/pg9.6/data" # wal dir is not null if test -z "$pirt_dir" then echo "pirl_dir is null" exit else if [ ! -d "$pirt_dir" ] then mkdir "$pirt_dir" fi fi # info file _date=$(date +%y%m%d) echo $_date>"${pirt_dir}/info" if test -z "$base_dir" then echo "base dir is null" exit else echo "base dir is : ${base_dir}" fi if test -z "$pg_home" then echo "pg_home is null" exit else echo "pg_home is : ${base_dir}" fi if test -z "$pg_port" then echo "pg_port is null" pg_port=5432 fi if test -z "$pg_data" then echo "pg_data is null" pg_data="${pg_home}/data" fi echo "pg_home:${pg_home},pg_port=:${pg_port},pg_data:${pg_data}" #new dir #back base data ${pg_home}/bin/psql -U postgres -p ${pg_port} -h 127.0.0.1 -c " select pg_start_backup('${_date}') " #start back up zip -r "$base_dir"/"$_date".zip "$pg_data"/* #back end ${pg_home}/bin/psql -U postgres -p ${pg_port} -h 127.0.0.1 -c " select pg_stop_backup() " #clear old dir wal for p_dir in $(ls ${base_dir}) do if test -d ${base_dir}/${p_dir} && [ ${p_dir} \< $_date ] then echo "clear data ${p_dir}" rm -rf ${base_dir}/${p_dir} fi done # clear old base back zip for file in $(ls ${base_dir}/*.zip ) do fname=${file##*/} fdate=${fname%%.*} if ! test -z $fdate && [ $fdate \< $_date ] then echo "rm file:${base_dir}/${fname}" rm ${base_dir}/${fname} fi done # new wal back dir # export pitr_dir=${curr_dir}
需要修改其中各个配置为自己当前数据库的安装目录和配置。修改完毕后将该脚本添加到crontab任务列表中,该脚本目前有存在的缺陷为:全量备份时间间隔必须大于1天,因为全量备份的备份文件名是以天为单位创建的。
#10 0 * * * sh /home/lyf/pgback/base_backup.sh > /home/lyf/pgback/back.log 2>&1
所有的路径需要换为正确的路径。
2、编写pitr日志备份脚本 pitr.sh 。
该脚本配置postgresql.conf中的archive_command 来使用,通过配置文件将wal日志准确的放入最近一次全量备份后制定的wal日志目录。
#!/bin/bash # pirt_dir=${WAL_DIR} pirt_dir="/home/lyf/pgback/back_9.6" _p=$1 _f=$2 if [ x$_p = x ] then # has %p exit fi if [ x$_f = x ] then exit fi if test -z "$pirt_dir" then echo "wal dir is null" exit fi info_file="${pirt_dir}"/info if [ ! -f "$info_file" ] then _date=$(date +%y%m%d) echo $_date>"$info_file" fi info_context=$(cat "$info_file") echo "info context is ${info_context}" # echo "${info_context}" log_dir="$pirt_dir"/"$info_context" # echo "log_dir:${log_dir}" if [ ! -d "$log_dir" ] then mkdir "$log_dir" fi # echo "test cp " if [ ! -f "${log_dir}/%f" ] then echo "p is $_p" echo "f is $_f" # echo "%p $log_dir/%f" cp $_p ${log_dir}/$_f fi # test ! -f ${log_dir}/%f && cp %p ${log_dir}/%f
3、 修改postgresql的配置文件 postgresql.conf。
wal_level = replica # minimal,replica,or logical archive_mode = on archive_command = 'sh /home/lyf/pgback/pitr.sh(pitr.sh的路径) %p %f >> /home/lyf/pgback/pitr.log(日志记录文件) '
4、重启数据库。
此时增量备份即正常运作,在crontab中配置的时间点会做一次全量的基础备份,然后切换wal备份目录。
5、通过备份还原
5.1、停库。
5.2、先将当前的$PGDATA目录进行备份,完成后开始利用基础备份和wal日志来恢复。(此备份目的不多说了,所有对数据的操作之前最好都能有一次备份,即使当前的数据可能已经是损坏或者不想要的)
5.3、从备份目录中(配置文件中的$base_dir)解压缩备份的基础备份.zip文件,解压缩后修改 $PGDATA的指向为解压缩后的路径。
5.4、从share 目录移过来recovery.conf文件到新的$PGDATA中,编辑文件修改:restore_command=’ cp /home/lyf/pgback/back_9.6/20170531/%f %p’
标注:红色部分要替换为真实的pirt备份目录。参考pitr.sh中配置的目录中取和基础备份中文件名一致的文件夹即可。
5.5、启动数据库会,可以看到开始还原。
5.6、如果要还原到具体的targetlabel 或者time 修改一下的配置
#recovery_target_name = '' # e.g. 'daily backup 2011-01-26' # #recovery_target_time = '' # e.g. '2004-07-14 22:39:00 EST' # #recovery_target_xid = '' # #recovery_target_inclusive = true