本系列主要是介绍基于pg10版本的日志备份技术,如何实现自动日志备份(主要是笔者业务上有这种功能,尝试了几天几夜,特此记录下),本篇文章是基础篇,主要介绍pg的几种数据备份方式。
如果你已经熟悉,可以看pg单机自动化日志备份系列二
一、pg_dump
) 和 pg_restore
以下描述摘自官方文档
pg_dump是一个用于备份PostgreSQL 数据库的工具。
它甚至可以在数据库正在使用的时候进行完整一致的备份。 pg_dump并不阻塞其它用户对数据库的访问(读或者写)
pg_restore用于恢复由pg_dump 转储的任何非纯文本格式中的PostgreSQL数据库。
它将发出必要的命令重建数据库,并把它恢复成转储时的样子。 归档(备份)文件还允许pg_restore有选择地进行恢复, 甚至在恢复前重新排列条目的顺序.
描述已经说了两者大概功能,笔者平时也用pg_dump + psql 进行一些数据的转移,但是从使用心得来看,pg_dump每次备份就相当于全量备份,所以进行数据恢复时,也不能恢复到某一个时间点的数据,所以不采用pg_dump + pg_restore 进行自动化日志备份。(由使用pg_dump需求的同学,请自行去查阅官方文档)
然后pg_dump每次只转储一个数据库,如果有更高的需求,可以看看pg_dumpall。
二、文件系统级别备份
说白了,就是复制pg的数据文件,但是在某些条件下,有缺点,比如用tar -cf backup.tar /var/lib/postgresql/data
进行复制,有一下两点:
1、数据库服务器必须被关闭,官方文档表示可能是tar和类似工具无法得到文件系统状态的一个原子的快照,还有服务器内部缓冲的原因。
2、如果想通过相应的文件或者目录来备份或恢复特定的表或者数据库,是行不通的,因为缺少必要的日志文件(日志文件包含了事务的提交状态)。
上面这种方式笔者没有尝试过(别怪我,真的是,精力有限。。。),不过,在开启wal归档备份的时候,笔者通过cp -rf /var/lib/postgresql/data/ /var/lib/postgresql/test
复制整个目录的方式(没有关闭数据库),可以进行一次全量备份,而且在数据库启动时,也能成功加载出数据。不过不能在任意时间点进行恢复。根据官方文档的解释,是因为创建了数据目录的的“一致快照”,而且备份文件在数据看来就像是出了故障,所以用备份数据启动数据库的时候,就会尝试重放WAL日志(就是做redo),成功的进行数据恢复。
三、wal归档 和 基础备份(全量备份)
wal归档就是预写式日志
,就是记录了数据页的修改记录。pg痛过开启wal归档,记录下事务的执行日志,通过这些日志就可以支持任意时间点的数据恢复,即PITR。具体详细介绍
启用wal归档功能,需要对pg配置文件postgresql.conf
进行修改:
1、wal_level = replica
2、archive_mode = on
# backup_in_progress文件用来辅助wal日志备份,通过删除配合test指令控制wal日志备份
3、archive_command = 'test ! -f /var/lib/postgresql/backup_in_progress || (test ! -f /var/lib/postgresql/pg_log_archive/%f && cp %p /var/lib/postgresql/pg_log_archive/%f)'
/var/lib/postgresql/pg_log_archive
是存放wal日志备份的地方。配置完成后,启动数据库,就开启了wal日志备份,在wal段文件达到16MB时,就会执行一次归档。当然也可以手动执行select pg_switch_wal();
进行归档。
wal归档功能有了,但是这只是相当于差异备份,还需要全量备份,下面就来看看全量备份(基础备份):
1、使用底层API进行,参考点
touch /var/lib/postgresql/backup_in_progress
# 开始基础备份,可以在代码里连接数据库执行
psql -c "select pg_start_backup('hot_backup');" # 需要用postgres用户
# 将数据库文件进行备份
tar -cf /var/lib/postgresql/backup.tar /var/lib/postgresql/data/
# 结束备份,可以在代码里连接数据库执行
psql -c "select pg_stop_backup();" # 需要用postgres用户
# 停止wal日志备份
rm /var/lib/postgresql/backup_in_progress
# 将wal日志和基础备份打包在一起
tar -rf /var/lib/postgresql/backup.tar /var/lib/postgresql/pg_log_archive
2、使用pg_basebackup
su - postgres; # 切换到 postgres用户
# 执行备份
pg_basebackup -Ft -X none -D - | gzip > /var/lib/postgresql/%f_base.tar.gz;
四、时间点恢复(PITR)
假设我们有一份备份文件,基础备份:/var/lib/postgresql/backup_base.tar.gz
和 wal归档目录:/var/lib/postgresql/pg_log_archive
,pg的数据目录是:/var/lib/postgresql/data/pgdata
通过以上步骤进行数据恢复:
1、解压数据
tar xvfz /var/lib/postgresql/backup_base.tar.gz -C /var/lib/postgresql/data/pgdata
2、配置recovery.conf
vim /var/lib/postgresql/data/pgdata/recovery.conf
# recovery.conf 配置下面两行
# 利用wal日志进行redo
restore_command = 'cp /var/lib/postgresql/pg_log_archive/%f %p'
# 指定要恢复的时间点,也可以不指定,直接恢复所有数据
recovery_target_time = '2019-10-10 18:00:00 UTC'
3、指定/var/lib/postgresql/data/pgdata
为pg的数据目录启动pg,就可以进行数据恢复。如果是指定恢复到某一时间点,即有recovery_target_time
配置项,在启动数据库后,还需要执行语句select pg_wal_replay_resume();
开启wal备份,完成本次数据恢复操作。
下一篇:pg单机自动化日志备份系列二