执行定期备份并有一整套恢复计划是一个DBA的重要工作之一,这也是数据库可用性和完整性的保障。我们可以在多个机房之间部署流复制集群,以保证但节点故障,但是集群无法保证认为的意外DELETE或者DROP操作而备份可以。在这片文章中,我们会讨论PostgreSQL的一些可用的备份选项。
备份类型
通常有两种备份大类 - 逻辑备份和物理备份。在设计备份策略之前,首先需要认真理解这两种备份的不同。当然,备份类型也决定了你需要使用哪种特定的工具来实现。
逻辑备份
逻辑备份的数据通常存储为平文件,以人类可读活着容易理解的形式存储。这中格式非常有用,如果需要,我们设置可以从备份中找到单独的某行记录并恢复它。但是从另一方面来看,回复整个逻辑备份是比较慢的,因为数据库不得不对所有的数据加载一一处理,这种通过数据库实例入库数据的方式比直接复制数据文件要慢很多。
物理备份
实际上,数据最终是一些磁盘文件的组合,物理备份就是将这些文件抓取出来。我们可以在某一个给定的时间点将数据文件复制出来进行备份。真正操作起来的时候,它并不像执行一个简单的copy命令那么容易。因为在执行物理备份时,我们需要时刻清醒的意识到,此时可能正在发生数据库修改。为了确保物理备份的可用性,任何物理备份必须保持持续一致。
物理备份对恢复整个数据库十分有效,速度仅仅受限于磁盘活着网络等硬件。
PostgreSQL中的备份
PostgreSQL,与大多数其他关系型数据库一样,支持物理备份和逻辑备份。下面让我们一起来看一下如何进行操作:
PostgreSQL逻辑备份
PostgreSQL数据库逻辑备份通过工具pg_dump来实现,它支持导出多种格式:默认存储为平文件,我们也可以通过参数控制生成结果为tar文件活着其他压缩格式。这种备份可以通过pg_restore命令恢复,我们可以很容易的手动解压出SQL内容。下面具体来看一下如何用pg_dump创建一个备份:
首先,备份为SQL平文件:
root@vagrant-ubuntu-trusty-64:~/c# pg_dump -d pgbench -U psql -h 10.0.0.101 > pgbench.sql
Password:
查看备份文件,可以看到如下内容:
COPY pgbench_accounts (aid, bid, abalance, filler) FROM stdin;
1 1 0
2 1 0
3 1 0
4 1 0
5 1 0
6 1 0
7 1 0
8 1 0
9 1 0
10 1 0
11 1 0
12 1 0
13 1 0
14 1 0
如果你想输出特定的备份格式,需要定义如下:
root@vagrant-ubuntu-trusty-64:~# pg_dump -d pgbench -U psql -h 10.0.0.101 --format c -f /root/c/pgdump.c
Password:
恢复数据十分简单。如果备份是默认平文件格式,我们可以直接用psql工具将该SQL语句加载到数据库中。如果使用的是另外格式,可以用pg_restore格式加载。如果允许丢弃部分新数据,那可以将整个在线数据库删除后恢复整个备份(如果不进行删除操纵,那么恢复完后会存在双份数据的问题)。例如:
postgres=# drop database pgbench;
DROP DATABASE
postgres=# create database pgbench;
CREATE DATABASE
root@vagrant-ubuntu-trusty-64:~# pg_restore --format c /root/c/pgdump.c -d pgbench -U psql -W -h 10.0.0.101
Password:
最后需要注意一点,pg_dump生成的持续备份是在一个单一的食物里面完成的,这个特性说明PostgreSQL依赖于MVCC机制来保证当前的备份不被后来的事务影响。
PostgreSQL物理备份
物理备份只要备份就是全备份,所以恢复的时候也是全库恢复。物理备份最大的问题是持续备份。当然,最简单的办法就是将PostgreSQL数据库停掉,然后使用类似cp、scp活着rsync等工具直接备份。但是实际生产环境中,停掉数据库基本是不可能的,所以我们需要通过其他的方式来实现。步骤大概如下:
- 使用pg_start_backup('some label')来创建一个检查点;
- 复制数据目录的内容;
- 使用pg_stop_backup()停止备份。
这些操作可以通过工具pg_basebackup来实现:
root@vagrant-ubuntu-trusty-64:~# pg_basebackup -U psql -h 10.0.0.101 -x -D /pgbase/
如果后面你需要实现基于检查点的恢复,此刻需要开启WAL归档设置:
wal_level = archive
archive_mode = on
我们也可以通过设置archive_command参数将WAL段复制到一个单独的位置存储。
恢复物理备份也比较简单,只需要将备份数据复制到一个干净的PostgreSQL数据目录下即可。恢复完成后,一旦启动PostgreSQL实例进程,数据库便会自动恢复到备份的时间点。如果要基于时间点恢复,此时需要使用归档日志:首先恢复基础备份,然后创建一个recovery.conf文件定义一个恢复命令,这个命令用来告诉PostgreSQL如何重放WAL日志。
Ends~