当前位置: 首页 > news >正文

PG 17 增量备份功能介绍

背景

PG 17 新增了增量备份功能,可以通过 pg_basebackup --incremental=PATH_TO_MANIFEST 命令进行增量备份。

  • 官方文档:https://www.postgresql.org/docs/current/app-pgbasebackup.html

在先前版本,其实我们也可以利用 WAL 进行增量备份,逻辑如下:

  1. 某一天对数据库进行一次全量备份,获得一个全量备份集;
  2. 又过了一天,我们将这一天内数据库所有的 WAL 都存起来;
  3. 当我们想恢复数据库时,以全量备份为基础,回放第二步所有的 WAL,最终得到完整的数据集;

功能介绍

wal summarization

wal summarization 是增量备份必备的前置功能,起作用是生成一系列总结文件,记录某个 LSN 区间内,有哪些块被修改了。
在这里插入图片描述

这样增量备份的时候可以通过这些 summarization 文件,找到哪些数据文件发生过变更,增量备份只需要备份这些发生过变更的文件即可。

增量备份

在先前的版本中,我们可以使用 pg_basebackup 功能对数据库进行备份。
而增量备份的大致逻辑如下:

  1. 某一天对数据库进行一次全量备份,获得一个全量备份集;
  2. 又过了一天,我们以上述的全量备份集为基础进行增量备份,得到一个增量备份集 ,这个增量备份的内容就是这一天数据库的变更;
  3. 当我们想恢复数据库时,使用 pg_combinebackup 将全量备份集和增量备份集进行合并,就获得了一个完整的数据集。

优势 & 劣势

优势

可以假想一个场景:用户的大部分操作都是 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 分钟,快了十几倍。

劣势

  1. 上述场景的相反状态:如果每次更新都几乎修改了全量数据,那不如直接做全量备份;
  2. 目前不支持输出压缩包,现在增量打出来就是一个文件夹;

使用方法

本章以具体例子说明,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)

PITR 测试

我们构造一种场景:

  1. 向表 t 中插入一条数据,值为 1;
  2. 进行全量备份;
  3. 将表 t 中数据值改成 2;
  4. 将表 t 中数据值再多修改几次;
  5. checkpoint;
  6. 进行增量备份,并将两个备份集合并;

下述所有操作都是全新的数据库,因此 LSN 保持一致。

./initdb -D ../data
echo "archive_mode=on
summarize_wal=on
archive_command = 'cp %p /data2/pg/17/inst/data/archive/%f'" >> ../data/postgresql.conf
pg_ctl start -D ../data -l logfile
psql -c "create table t(a int); insert into t values(1);"
pg_basebackup -D /data2/pg/17/inst/full_backup 
psql -c "update t set a=2 where a=1;"
psql -c "SELECT pg_current_wal_lsn();"
psql -c "update t set a=3 where a=2;"
psql -c "update t set a=4 where a=3;"
psql -c "update t set a=5 where a=4;"
pg_basebackup --incremental=/data2/pg/17/inst/full_backup/backup_manifest -D /data2/pg/17/inst/increment_backup1/
pg_combinebackup /data2/pg/17/inst/full_backup /data2/pg/17/inst/increment_backup1/ -o /data2/pg/17/inst/new_data/

再往 new_data 目录下设置参数:

echo "restore_command = 'cp /data2/pg/17/inst/data/archive/%f %p'
recovery_target_lsn = '0/30000F8'
recovery_target_action=promote
port=5433 " >> ../new_data/postgresql.conf 
touch ../new_data/recovery.signal
pg_ctl start -D ../new_data -l logfile2

可以发现无法恢复到目标 LSN,因为实际上合并后的数据集和 increment_backup1 的 backup_label 相同,因此可以看作是以 increment_backup1 的时间作为 basebackup 开始的时间,而这个 LSN 点位是晚于我们指定的点位的(即 “将表 t 中数据值改成 2” 这个动作的点位),所以是无法对过去点位进行 PITR,这与原先的 pg_basebackup 功能是相同的。
在这里插入图片描述
当然了,如果选取的 LSN/时间 是晚于上述红框中的位点,并且 WAL 日志也都保留着,那就可以进行 PITR。

压测场景

我们边使用 pgbench -i -s 1000 postgres 给上写入压力,同时另开一个终端执行 pg_basebackup --incremental=/data2/pg/17/inst/full_backup/backup_manifest -D /data2/pg/17/inst/increment_backup ,发现增量备份会在压测过程中结束(保留部分压测数据)。

原理分析

参考资料

[1] https://www.postgresql.org/docs/current/app-pgbasebackup.html
[2] https://pganalyze.com/blog/5mins-postgres-17-incremental-backups


http://www.mrgr.cn/news/51412.html

相关文章:

  • 手把手教你玩转Midjourney,保姆级教程公开
  • Mac中使用brew安装指定版本软件包
  • [哈工大]战德臣 数据库系统 第3讲 关系模型之基本概念
  • torch运行异常·找不到指定的模块|fbgemm.dll
  • 百年德企科世达颠覆传统报销,依托分贝通实现差旅支出降本百万
  • VMware-Converter-Agent.exe 安装失败
  • 快快网络DDoS安全防护系统抵御了创纪录的 2.35 Tbps DDoS 攻击
  • 深入理解Qt中的QTableView、Model与Delegate机制
  • jvm虚拟机调优实战
  • 715: 字典序问题
  • EasyOCR——超强超便捷的OCR开源算法介绍与文本检测模型CRAFT微调方法
  • python+Mosh网课笔记01
  • WSL2配置代理解决git网络不通畅的问题
  • AI大模型与相对论的结合点的思考、应用及相对论原理与公式表达
  • 算法学习---递归算法
  • 单片机中断概念以及示例
  • 专用代理服务器及其功能
  • 微信小程序添加删除线和下划线
  • 大数据-174 Elasticsearch Query DSL - 全文检索 full-text query 匹配、短语、多字段 详细操作
  • 遥遥“羚”先,迈威通信荣膺武汉市科技创新瞪羚企业