PG 17 增量备份功能介绍
背景
PG 17 新增了增量备份功能,可以通过 pg_basebackup --incremental=PATH_TO_MANIFEST
命令进行增量备份。
- 官方文档:https://www.postgresql.org/docs/current/app-pgbasebackup.html
在先前版本,其实我们也可以利用 WAL 进行增量备份,逻辑如下:
- 某一天对数据库进行一次全量备份,获得一个全量备份集;
- 又过了一天,我们将这一天内数据库所有的 WAL 都存起来;
- 当我们想恢复数据库时,以全量备份为基础,回放第二步所有的 WAL,最终得到完整的数据集;
功能介绍
wal summarization
wal summarization 是增量备份必备的前置功能,起作用是生成一系列总结文件,记录某个 LSN 区间内,有哪些表/索引被修改了。
这样增量备份的时候可以通过这些 summarization 文件,找到哪些数据文件发生过变更,增量备份只需要备份这些发生过变更的文件即可。
增量备份
在先前的版本中,我们可以使用 pg_basebackup 功能对数据库进行备份。
而增量备份的大致逻辑如下:
- 某一天对数据库进行一次全量备份,获得一个全量备份集;
- 又过了一天,我们以上述的全量备份集为基础进行增量备份,得到一个增量备份集 ,这个增量备份的内容就是这一天数据库的变更;
- 当我们想恢复数据库时,使用 pg_combinebackup 将全量备份集和增量备份集进行合并,就获得了一个完整的数据集。
这里第 2 步的增量备份
增量备份优势
可以假想一个场景:用户的大部分操作都是 update 同一行数据。在这种场景下,会生成很多的 WAL,但实际的数据文件变更却很少。在这种场景下,PG 17 的增量备份功能相比原先 redo WAL 的方式就具有非常大的优势。
根据 [2] 中提到的数据,EDB 做过相关的测试:
对一个数据库进行 24h 的 pgbench 测试,初始时数据库只有 3.3GB 大小,测试结束时数据库有 4.3 GB 大小,产生了 77GB 的 WAL 日志。
初始的全量备份集为 3.4GB,后续每 2h 进行一次增量备份,获得的 11 个增量备份集加起来大小只有 3.5GB。
接着,测试人员进行 PITR 测试,要求恢复到指定的时间点。使用原有的 redo WAL 的方式花了 78 分钟,而使用 PG 17 的增量备份只用了 4 分钟,快了十几倍。
使用方法
本章以具体例子说明,PG 17 增量备份的使用方法。
全量备份
启动实例后,首先配置参数 summarize_wal=on
来启用增量备份。灌入一些数据,构造初始数据集
alter system set summarize_wal to on;
select pg_reload_conf();
create table t(a int);
insert into t select generate_series(1,10000);
接着使用 pg_basebackup 命令,拉出一个全量的备份集
pg_basebackup -D /data2/pg/17/inst/full_backup
可以发现全量备份目录下基本就是数据库需要的文件,其中的 backup_manifest 文件记录了这次全量备份的文件名单。
增量备份 1
然后我们继续在原实例插入数据:
insert into t select generate_series(10000,20000);
然后使用增量备份功能,–incremental 指定刚刚全量备份的 manifest:
pg_basebackup --incremental=/data2/pg/17/inst/full_backup/backup_manifest -D /data2/pg/17/inst/increment_backup1/
这时候我们进入增量备份的文件目录,其大体结构和全量备份相似,只不过部分文件被替换成了 INCREMENTAL.${ORIGINAL_NAME} 形式
增量备份 2
然后我们再创建一张表,插入些数据
create table t2(a int);
insert into t2 values(1);
insert into t select generate_series(20001,20005);
进行第二次增量备份,基于第一次增量备份的 manifest 文件
pg_basebackup --incremental=/data2/pg/17/inst/increment_backup1/backup_manifest -D /data2/pg/17/inst/increment_backup2/
合并备份文件
使用 pg_combinebackup
工具进行备份合并,输出到 new_data 文件夹
pg_combinebackup /data2/pg/17/inst/full_backup /data2/pg/17/inst/increment_backup1/ /data2/pg/17/inst/increment_backup2/ -o /data2/pg/17/inst/new_data/
接着我们在新数据库启动实例,查询信息,发现果然已经合并完成:
postgres=# select count(*) from t;
count
-------
20006
(1 row)
postgres=# select * from t2;
a
---
1
(1 row)
参考资料
[1] https://www.postgresql.org/docs/current/app-pgbasebackup.html
[2] https://pganalyze.com/blog/5mins-postgres-17-incremental-backups