PostgreSQL 17: 管理增量备份链

John Doe 七月 11, 2025

你知道如何管理 PostgreSQL 的增量备份吗?

沙滩上漫步的大象

特性提交日志

新增增量备份支持。

若要创建增量备份,需使用新的复制命令 UPLOAD_MANIFEST 上传先前备份的清单。先前的备份可以是全量备份,也可以是另一个增量备份。然后,使用带有 INCREMENTAL 选项的 BASE_BACKUP 来执行备份。pg_basebackup 现在提供了 --incremental=PATH_TO_MANIFEST 选项来触发此行为。

增量备份与常规的全量备份类似,不同之处在于:部分关系文件被替换为名称类似 INCREMENTAL.${ORIGINAL_NAME} 的文件,且 backup_label 文件中包含额外行,表明其为增量备份。新的 pg_combinebackup 工具可用于从一个全量备份和一系列增量备份中重建数据目录。

讨论:http://postgr.es/m/CA+TgmoYOYZfMCyOXFyC-P+-mdrZqm5pP2N7S-r0z3_402h9rsA@mail.gmail.com

示例

假设今天是周日,你按如下方式每周日进行一次全量备份:

$ mkdir -p /var/tmp/backups/sunday
$ pg_basebackup -D /var/tmp/backups/sunday/

周一至周六进行增量备份:

$ weekdays=('mon' 'tue' 'wed' 'thu' 'fri' 'sat')

$ for i in "${weekdays[@]}"
do
   mkdir -p /var/tmp/backups/$i
   pg_basebackup --incremental=/var/tmp/backups/sunday/backup_manifest --pgdata=/var/tmp/backups/$i
done

$ ls -la /var/tmp/backups/
total 36
drwxr-xr-x  9 postgres postgres 4096 Jun 12 17:13 .
drwxrwxrwt  7 root     root     4096 Jun 12 17:13 ..
drwxr-xr-x 20 postgres postgres 4096 Jun 12 17:10 fri
drwxr-xr-x 20 postgres postgres 4096 Jun 12 17:10 mon
drwxr-xr-x 20 postgres postgres 4096 Jun 12 17:10 sat
drwxr-xr-x 20 postgres postgres 4096 Jun 12 16:57 sunday
drwxr-xr-x 20 postgres postgres 4096 Jun 12 17:10 thu
drwxr-xr-x 20 postgres postgres 4096 Jun 12 17:10 tue
drwxr-xr-x 20 postgres postgres 4096 Jun 12 17:10 wed

这样,除周日外,每天都会生成一个增量备份,且所有增量备份都以周日的全量备份为起点。你也可以将之前的某个增量备份作为新的增量备份的起点,如下所示:

$ mkdir /var/tmp/backups/xx

$ pg_basebackup --incremental=/var/tmp/backups/wed/backup_manifest --pgdata=/var/tmp/backups/xx

$ ls /var/tmp/backups/xx
backup_label      pg_dynshmem    pg_notify     pg_subtrans  postgresql.auto.conf
backup_manifest   pg_hba.conf    pg_replslot   pg_tblspc    postgresql.conf
base              pg_ident.conf  pg_serial     pg_twophase
current_logfiles  pg_log         pg_snapshots  PG_VERSION
global            pg_logical     pg_stat       pg_wal
pg_commit_ts      pg_multixact   pg_stat_tmp   pg_xact

在这种情况下,新的增量备份基于之前的增量备份,无需引用之前的全量备份。

现在我们得到了以下的备份链:

  • 周日 - 全量备份
  • 周一 - 增量备份,基于周日
  • 周二 - 增量备份,基于周日
  • 周三 - 增量备份,基于周日
  • 周四 - 增量备份,基于周日
  • 周五 - 增量备份,基于周日
  • 周六 - 增量备份,基于周日

你可以使用 pg_combinebackup 工具合并部分备份,以缩短备份链。假设我们想在周三生成另一个全量备份,无需重新进行全量备份,只需将周日的全量备份与周三的增量备份合并:

$ pg_combinebackup /var/tmp/backups/sunday/ /var/tmp/backups/wed/ -o /var/tmp/backups/wed_full

$ ls /var/tmp/backups/wed_full
backup_label pg_dynshmem pg_notify pg_subtrans postgresql.auto.conf
backup_manifest pg_hba.conf pg_replslot pg_tblspc postgresql.conf
base pg_ident.conf pg_serial pg_twophase
current_logfiles pg_log pg_snapshots PG_VERSION
global pg_logical pg_stat pg_wal
pg_commit_ts pg_multixact pg_stat_tmp pg_xact

这样就得到了一个新的一致性全量备份,该备份可作为后续增量备份的起点:

$ mkdir /var/tmp/backups/oo

$ pg_basebackup --incremental=/var/tmp/backups/wed_full/backup_manifest --pgdata=/var/tmp/backups/oo

$ ls /var/tmp/backups/oo
backup_label      pg_dynshmem    pg_notify     pg_subtrans  postgresql.auto.conf
backup_manifest   pg_hba.conf    pg_replslot   pg_tblspc    postgresql.conf
base              pg_ident.conf  pg_serial     pg_twophase
current_logfiles  pg_log         pg_snapshots  PG_VERSION
global            pg_logical     pg_stat       pg_wal
pg_commit_ts      pg_multixact   pg_stat_tmp   pg_xact

要基于这个新的全量备份创建新的增量备份,只需遵循相同的步骤,并为新的增量备份指定该备份的备份清单:

$ mkdir /var/tmp/backups/pp

$ pg_basebackup --incremental=/var/tmp/backups/oo/backup_manifest --pgdata=/var/tmp/backups/pp

$ ls /var/tmp/backups/pp
backup_label      pg_dynshmem    pg_notify     pg_subtrans  postgresql.auto.conf
backup_manifest   pg_hba.conf    pg_replslot   pg_tblspc    postgresql.conf
base              pg_ident.conf  pg_serial     pg_twophase
current_logfiles  pg_log         pg_snapshots  PG_VERSION
global            pg_logical     pg_stat       pg_wal
pg_commit_ts      pg_multixact   pg_stat_tmp   pg_xact

将全量备份和这两个增量备份合并,可再次得到一个能直接启动的一致性全量备份:

$ pg_combinebackup /var/tmp/backups/wed_full /var/tmp/backups/oo /var/tmp/backups/pp -o /var/tmp/backups/kk
$ echo "port=8888" >> /var/tmp/backups/kk/postgresql.auto.conf 
$ chmod 700 /var/tmp/backups/kk
$ pg_ctl -D /var/tmp/backups/kk start

另一个使用场景:周日进行全量备份:

$ rm -rf /var/tmp/backups/
$ pg_basebackup -D /var/tmp/backups/sun

然后在周一和周二进行增量备份,其中周二的增量备份基于周一的增量备份:

$ pg_basebackup --incremental=/var/tmp/backups/sun/backup_manifest --pgdata=/var/tmp/backups/mon
$ pg_basebackup --incremental=/var/tmp/backups/mon/backup_manifest --pgdata=/var/tmp/backups/tue

周三将周日、周一和周二的备份合并,并基于此创建一个增量备份:

$ pg_combinebackup /var/tmp/backups/sun /var/tmp/backups/mon /var/tmp/backups/tue -o /var/tmp/backups/wed_full
$ pg_basebackup --incremental=/var/tmp/backups/wed_full/backup_manifest --pgdata=/var/tmp/backups/wed_incr

这表明:备份链的管理方式完全由你决定。每个备份都可以作为另一个备份的起点,将多个增量备份和最后一个全量备份合并为一个新的全量备份,有助于缩短备份链。这个概念非常不错,因为它为备份策略的实施提供了多种选择。

感谢所有参与的社区人员。

参考

提交日志:https://git.postgresql.org/pg/commitdiff/dc212340058b4e7ecfc5a7a81ec50e7a207bf288