简介
pgBackRest 是一个强大的开源备份和恢复工具,专为 PostgreSQL 数据库设计。它提供了高效、可靠的备份与恢复能力,并支持多种存储后端(如本地磁盘、网络存储、S3 兼容存储等)。
使用场景
数据库备份到本地或远程存储。
基于时间点的灾难恢复(PITR)。
数据库升级或迁移时的数据保护。
与 S3 或类似服务的集成,用于云备份。
pgBackRest 的核心功能
高效备份
增量备份:只备份自上次完整备份以来更改的数据块,减少存储空间和备份时间。
并行处理:支持多线程备份和恢复,提高速度。
数据压缩:备份数据可进行压缩以节省存储空间。
流复制备份:无需停机即可从主库或从库进行备份。
可靠恢复
支持 PITR(Point-in-Time Recovery,时间点恢复)。
可以恢复到指定的事务时间点或检查点。
提供一致性检查以确保备份数据的完整性。
灵活存储支持
支持本地文件系统、NFS、S3 兼容存储(如 AWS S3、MinIO)。
支持多个存储库(例如本地和云存储同时备份)。
备份加密
使用 AES-256-CBC 加密备份数据,确保数据安全。
备份管理
自动删除过期的备份(通过保留策略管理)。
可管理多个 PostgreSQL 实例的备份(基于 Stanza)。
监控与日志
提供详细的日志记录,便于问题排查。
提供统计信息,用于监控备份性能。
pgBackRest 的优点
高性能:并行处理和增量备份提升了备份和恢复速度。
稳定可靠:确保备份的一致性和完整性,适用于大规模数据库。
灵活性:支持多种存储后端和配置方式,适应不同的部署场景。
简洁配置:通过配置文件和命令行选项,便于集成和管理。
pgBackRest 的主要组件
Stanza
一个 Stanza 代表一个 PostgreSQL 实例。
用于区分和管理多个数据库实例的备份。
Repository
存储备份数据的物理位置,可以是本地路径或 S3 存储。
支持配置多个存储库。
备份类型
Full(全量备份):备份整个数据库。
Differential(差异备份):基于最近的全量备份,仅备份变化的数据。
Incremental(增量备份):基于最近的备份(全量或差异),仅备份变化的数据。
常用命令
初始化 Stanza
1pgbackrest --stanza=mydb --pg1-path=/var/lib/postgresql/data stanza-create
检查配置
1pgbackrest --stanza=mydb check
进行备份
1pgbackrest --stanza=mydb backup
查看备份信息
1pgbackrest --stanza=mydb info
恢复数据
bash<br />pgbackrest --stanza=mydb restore<br />
使用 pgBackRest 将数据备份到 S3 存储可以通过配置 S3
存储库完成,具体步骤如下:
安装pgBackRest
确保 pgBackRest 已经安装,并且支持 S3。需要确认 libcurl
支持已编译到 pgBackRest 中。
1wget https://github.com/pgbackrest/pgbackrest/archive/refs/tags/release/2.54.tar.gz
2
3
4yum -y install libyaml-devel libxml2 libxml2-devel bzip2 bzip2-devel
5export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/pg16/pg16/lib
6export PATH=$PATH:/pg16/pg16/bin
7
8
9
10tar -zxvf 2.54.tar.gz
11cd pgbackrest-release-2.54/src
12./configure
13make -j8
14make install
15
16
17ln -s /usr/local/bin/pgbackrest /usr/bin/pgbackrest
18
19
20chmod 755 /usr/local/bin/pgbackrest
21mkdir -p -m 770 /var/log/pgbackrest
22chown postgres:postgres /var/log/pgbackrest
23mkdir -p /etc/pgbackrest
24mkdir -p /etc/pgbackrest/conf.d
25touch /etc/pgbackrest/pgbackrest.conf
26chmod 640 /etc/pgbackrest/pgbackrest.conf
27chown postgres:postgres /etc/pgbackrest/pgbackrest.conf
28mkdir -p /var/lib/pgbackrest
29chmod 750 /var/lib/pgbackrest
30chown postgres:postgres /var/lib/pgbackrest
配置 pgBackRest
修改 pgbackrest.conf
文件,为存储库添加 S3 配置。
配置文件路径
全局配置:
/etc/pgbackrest/pgbackrest.conf
本地配置:
/var/lib/pgbackrest/pgbackrest.conf
配置示例
以下是将备份存储到 S3 的配置示例:
1yum install -y fuse-sshfs
2
3
4sshfs -o allow_other -p 922 root@172.16.7.162:/minio/data/pgbk/pg15 /bk
5
6
7
8
9ln -s /usr/local/bin/pgbackrest /usr/bin/pgbackrest
10
11
12chmod 755 /usr/local/bin/pgbackrest
13mkdir -p -m 777 /var/log/pgbackrest
14mkdir -p /etc/pgbackrest
15mkdir -p /etc/pgbackrest/conf.d
16touch /etc/pgbackrest/pgbackrest.conf
17chmod 777 /etc/pgbackrest/pgbackrest.conf
18mkdir -p /var/lib/pgbackrest
19chmod 777 /var/lib/pgbackrest
20
21mkdir -p /tmp/pgbackrest/
22chmod 777 -R /tmp/pgbackrest/
23
24
25
26
27alter system set archive_command = 'pgbackrest --stanza=pg16 archive-push %p';
28alter system set archive_mode = on;
29alter system set listen_addresses = '*';
30alter system set max_wal_senders = 10;
31alter system set wal_level = replica;
32
33pg_ctl restart
34
35
36
37cat > /etc/pgbackrest/pgbackrest.conf <<"EOF"
38[global]
39log-level-file=detail
40log-path=/var/log/pgbackrest
41repo1-host-user=root
42repo1-path=/bk/repos
43start-fast=y
44process-max=4
45repo1-retention-full=2
46repo1-retention-diff=1
47repo1-retention-archive=1
48
49
50[pg16]
51pg1-path=/pg16/pgdata
52pg1-port=5441
53pg1-host-user=pg16
54
55EOF
测试连接
1# 设置数据库参数
2alter system set archive_command = 'pgbackrest --stanza=pg01 archive-push %p';
3alter system set archive_mode = on;
4alter system set listen_addresses = '*';
5-- alter system set log_line_prefix = '';
6alter system set max_wal_senders = 10;
7alter system set wal_level = replica;
8
9# 重启数据库
10pg_ctl restart
11
12
13
14
15pgbackrest --stanza=pg16 --log-level-console=info stanza-create
16pgbackrest --stanza=pg16 --log-level-console=info check
17
18
19pgbackrest --stanza=pg16 --log-level-console=info backup --type=full
20
21
22pgbackrest --stanza=pg16 --log-level-console=info backup --type=diff
23
24
25pgbackrest --stanza=pg16 --log-level-console=info backup --type=incr
26
27
28pgbackrest info
29
30
31
32create table t(id int, col2 text);
33insert into t select n, 'test123' || n || md5(random()::varchar) from generate_series(1, 60000) as n;
格式化pgbackrest info的备份结果为表格形式
1cat > pgbackrest_table.sh <<"EOF"
2#!/bin/bash
3
4# 获取 pgBackRest 信息并解析 JSON
5pgbackrest info --stanza=$1 --output=json | jq -r '
6[
7 "Label", "Type", "Start Timestamp", "Stop Timestamp", "DB Size", "DB bk Size", "Repo bks_all Size", "Repo bks Size", "Start LSN", "Stop LSN", "Archive Start", "Archive Stop", "Reference"
8],
9(
10 .[0].backup[] | [
11 .label,
12 .type,
13 .timestamp.start,
14 .timestamp.stop,
15 .info.size,
16 .info.delta,
17 .info.repository.size,
18 .info.repository.delta,
19 .lsn.start,
20 .lsn.stop,
21 .archive.start,
22 .archive.stop,
23 (if .reference then (.reference | join(", ")) else "" end) # 处理可能为空的 reference 数组
24 ]
25) | @tsv' | while IFS=$'\t' read -r label type start_ts stop_ts size delta repo_size repo_delta start_lsn stop_lsn archive_start archive_stop reference; do
26 # 检查是否是标题行
27 if [[ "$label" == "Label" ]]; then
28 printf "|------------------------------------------|--------|---------------------|---------------------|------------|------------|----------------------|----------------------|------------------|------------------|--------------------------|--------------------------|------------------------------------------------------------------------------------------------------|\n"
29 printf "| %-40s | %-6s | %-19s | %-19s | %-10s | %-10s | %-20s | %-20s | %-16s | %-16s | %-24s | %-24s | %-100s |\n" \
30 "$label" "$type" "$start_ts" "$stop_ts" "$size" "$delta" "$repo_size" "$repo_delta" "$start_lsn" "$stop_lsn" "$archive_start" "$archive_stop" "$reference"
31 # 输出分隔行
32 printf "|------------------------------------------|--------|---------------------|---------------------|------------|------------|----------------------|----------------------|------------------|------------------|--------------------------|--------------------------|------------------------------------------------------------------------------------------------------|\n"
33 continue
34 fi
35
36 # 使用 numfmt 格式化大小到 MB 或 GB
37 size=$(numfmt --to=iec --suffix=B "$size")
38 delta=$(numfmt --to=iec --suffix=B "$delta")
39 repo_size=$(numfmt --to=iec --suffix=B "$repo_size")
40 repo_delta=$(numfmt --to=iec --suffix=B "$repo_delta")
41
42 # 东八区
43 start_ts=$(TZ='Asia/Shanghai' date -d @"$start_ts" +"%Y-%m-%d %H:%M:%S")
44 stop_ts=$(TZ='Asia/Shanghai' date -d @"$stop_ts" +"%Y-%m-%d %H:%M:%S")
45
46 # 打印格式化的内容,并在每列前后加竖线
47 printf "| %-40s | %-6s | %-19s | %-19s | %-10s | %-10s | %-20s | %-20s | %-16s | %-16s | %-15s | %-15s | %-100s |\n" \
48 "$label" "$type" "$start_ts" "$stop_ts" "$size" "$delta" "$repo_size" "$repo_delta" "$start_lsn" "$stop_lsn" "$archive_start" "$archive_stop" "$reference"
49done
50printf "|------------------------------------------|--------|---------------------|---------------------|------------|------------|----------------------|----------------------|------------------|------------------|--------------------------|--------------------------|------------------------------------------------------------------------------------------------------|\n"
51echo " "
52
53EOF
54
55
56cp pgbackrest_table.sh /usr/local/bin/
57chmod +x pgbackrest_table.sh
58sh pgbackrest_table.sh pg16
59
60
61[pg15@pg15 ~]$ sh pgbackrest_table.sh pg16
62|------------------------------------------|--------|---------------------|---------------------|------------|------------|----------------------|----------------------|------------------|------------------|--------------------------|--------------------------|------------------------------------------------------------------------------------------------------|
63| Label | Type | Start Timestamp | Stop Timestamp | DB Size | DB bk Size | Repo bks_all Size | Repo bks Size | Start LSN | Stop LSN | Archive Start | Archive Stop | Reference |
64|------------------------------------------|--------|---------------------|---------------------|------------|------------|----------------------|----------------------|------------------|------------------|--------------------------|--------------------------|------------------------------------------------------------------------------------------------------|
65| 20241030-093035F | full | 2024-10-30 09:30:35 | 2024-10-30 09:30:53 | 588MB | 588MB | 180MB | 180MB | 1/D5000028 | 1/D5000138 | 0000000300000001000000D5 | 0000000300000001000000D5 | |
66| 20241030-093114F | full | 2024-10-30 09:31:14 | 2024-10-30 09:31:32 | 588MB | 588MB | 180MB | 180MB | 1/D7000028 | 1/D7000138 | 0000000300000001000000D7 | 0000000300000001000000D7 | |
67| 20241030-093114F_20241030-093150D | diff | 2024-10-30 09:31:50 | 2024-10-30 09:31:51 | 588MB | 9.5KB | 180MB | 798B | 1/D9000028 | 1/D9000100 | 0000000300000001000000D9 | 0000000300000001000000D9 | 20241030-093114F |
68| 20241030-093114F_20241030-093316I | incr | 2024-10-30 09:33:16 | 2024-10-30 09:33:18 | 588MB | 9.9KB | 180MB | 834B | 1/DB000028 | 1/DB000100 | 0000000300000001000000DB | 0000000300000001000000DB | 20241030-093114F, 20241030-093114F_20241030-093150D |
69| 20241030-093114F_20241030-093321I | incr | 2024-10-30 09:33:21 | 2024-10-30 09:33:23 | 588MB | 11KB | 180MB | 862B | 1/DD000028 | 1/DD000100 | 0000000300000001000000DD | 0000000300000001000000DD | 20241030-093114F, 20241030-093114F_20241030-093150D, 20241030-093114F_20241030-093316I |
70| 20241030-093114F_20241030-093334D | diff | 2024-10-30 09:33:34 | 2024-10-30 09:33:36 | 588MB | 11KB | 180MB | 998B | 1/DE000028 | 1/DF000050 | 0000000300000001000000DE | 0000000300000001000000DF | 20241030-093114F |
71| 20241030-093114F_20241030-101302D | diff | 2024-10-30 10:13:02 | 2024-10-30 10:13:23 | 692MB | 588MB | 213MB | 198MB | 1/E9000028 | 1/E9000138 | 0000000300000001000000E9 | 0000000300000001000000E9 | 20241030-093114F |
72| 20241030-093114F_20241030-101438D | diff | 2024-10-30 10:14:38 | 2024-10-30 10:14:59 | 692MB | 588MB | 213MB | 198MB | 1/EB000028 | 1/EB000138 | 0000000300000001000000EB | 0000000300000001000000EB | 20241030-093114F |
73| 20241030-093114F_20241030-101913I | incr | 2024-10-30 10:19:13 | 2024-10-30 10:19:15 | 692MB | 13KB | 213MB | 1.3KB | 1/ED000028 | 1/ED000138 | 0000000300000001000000ED | 0000000300000001000000ED | 20241030-093114F, 20241030-093114F_20241030-101438D |
74|------------------------------------------|--------|---------------------|---------------------|------------|------------|----------------------|----------------------|------------------|------------------|--------------------------|--------------------------|------------------------------------------------------------------------------------------------------|
“database size”:是数据库的完整未压缩大小
“database backup size”是要实际备份的数据库中的数据量(对于完全备份,这两个值将相同)。“backup set size”包括此备份中的所有文件以及存储库中所需的任何引用备份,以从此备份恢复数据库
“backup size”仅包括此备份中的文件(对于完全备份,这两个值也将相同)。如果在 pgBackRest 中启用了压缩,则存储库大小反映压缩后的文件大小。
总结
1、若报错,可以修改 --log-level-console=detail 或 debug来显示更详细的日志
2、可以观察数据库的告警日志分析问题
3、--stanza
在所有配置中应该保持一致
4、还原的时候,pgbackrest需要安装在需要还原到的所在的主机上,可以不用安装PG环境,否则报错:ERROR: [072]: restore command must be run on the PostgreSQL host
5、全量+增量还原都可以使用PITR基于时间点的恢复,否则默认恢复到最新的时间点
6、建议增加参数start-fast=y
,因为若是测试环境,则检查点很慢,备份的话会等待下次检查点
7、数据库服务器 和 备份服务器,都需要安装,且要求相同版本pgBackRest 。
8、远程备份需要提前配置互信ssh,推荐直接使用root用户的互信,不过数据库用户的互信也需要配置。
9、归档命令archive_command必须配置包含pgbackrest,配置为如下方式:
1alter system set archive_command = 'pgbackrest --stanza=pg03 archive-push %p';
会自动将归档日志归档到repo中,远程服务器也会自动进行归档到远程的repo中。
10、数据库的socket文件应该在/var/run/postgresql/生成一份。例如:ln -s /pg15/pgdata/.s.PGSQL.5440 /var/run/postgresql/.s.PGSQL.5440
11、远程备份支持S3,但是需要https配置。若远程备份,则推荐使用sshfs备份,方便简单。
12、pgbackrest_2.54需要Linux 8系统,pgbackrest_2.52.1可以在Linux 7上运行。