【异地备份】pgbackrest如何将PostgreSQL数据库备份到S3中?

教育   2024-12-07 20:16   陕西  

简介

pgBackRest 是一个强大的开源备份和恢复工具,专为 PostgreSQL 数据库设计。它提供了高效、可靠的备份与恢复能力,并支持多种存储后端(如本地磁盘、网络存储、S3 兼容存储等)。

使用场景

  • 数据库备份到本地或远程存储。

  • 基于时间点的灾难恢复(PITR)。

  • 数据库升级或迁移时的数据保护。

  • 与 S3 或类似服务的集成,用于云备份。


pgBackRest 的核心功能

  1. 高效备份

  • 增量备份:只备份自上次完整备份以来更改的数据块,减少存储空间和备份时间。

  • 并行处理:支持多线程备份和恢复,提高速度。

  • 数据压缩:备份数据可进行压缩以节省存储空间。

  • 流复制备份:无需停机即可从主库或从库进行备份。

  1. 可靠恢复

  • 支持 PITR(Point-in-Time Recovery,时间点恢复)。

  • 可以恢复到指定的事务时间点或检查点。

  • 提供一致性检查以确保备份数据的完整性。

  1. 灵活存储支持

  • 支持本地文件系统、NFS、S3 兼容存储(如 AWS S3、MinIO)。

  • 支持多个存储库(例如本地和云存储同时备份)。

  1. 备份加密

  • 使用 AES-256-CBC 加密备份数据,确保数据安全。

  1. 备份管理

  • 自动删除过期的备份(通过保留策略管理)。

  • 可管理多个 PostgreSQL 实例的备份(基于 Stanza)。

  1. 监控与日志

  • 提供详细的日志记录,便于问题排查。

  • 提供统计信息,用于监控备份性能。


pgBackRest 的优点

  • 高性能:并行处理和增量备份提升了备份和恢复速度。

  • 稳定可靠:确保备份的一致性和完整性,适用于大规模数据库。

  • 灵活性:支持多种存储后端和配置方式,适应不同的部署场景。

  • 简洁配置:通过配置文件和命令行选项,便于集成和管理。


pgBackRest 的主要组件

  1. Stanza

  • 一个 Stanza 代表一个 PostgreSQL 实例。

  • 用于区分和管理多个数据库实例的备份。

  1. Repository

  • 存储备份数据的物理位置,可以是本地路径或 S3 存储。

  • 支持配置多个存储库。

  1. 备份类型

  • Full(全量备份):备份整个数据库。

  • Differential(差异备份):基于最近的全量备份,仅备份变化的数据。

  • Incremental(增量备份):基于最近的备份(全量或差异),仅备份变化的数据。


常用命令

  1. 初始化 Stanza

    1pgbackrest --stanza=mydb --pg1-path=/var/lib/postgresql/data stanza-create
  2. 检查配置

    1pgbackrest --stanza=mydb check
  3. 进行备份

    1pgbackrest --stanza=mydb backup
  4. 查看备份信息

    1pgbackrest --stanza=mydb info
  5. 恢复数据
    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

创建 S3 存储桶

登录到 S3 服务(如 AWS S3 或兼容的 S3 服务,如 MinIO),创建一个存储桶,用于存储备份数据。

注意:必须配置https访问,否则pgBackRest不能使用。


配置 pgBackRest

修改 pgbackrest.conf 文件,为存储库添加 S3 配置。

配置文件路径

  • 全局配置/etc/pgbackrest/pgbackrest.conf

  • 本地配置/var/lib/pgbackrest/pgbackrest.conf

配置示例

以下是将备份存储到 S3 的配置示例:

 1cat > /etc/pgbackrest/pgbackrest.conf << "EOF"
2[global]
3
4log-level-file=detail
5log-path=/var/log/pgbackrest
6start-fast=y
7process-max=4
8
9
10repo1-path=/pgbackrest
11repo1-retention-full=2
12repo1-retention-diff=1
13repo1-retention-archive=1
14
15repo1-s3-bucket=pgbk
16repo1-s3-endpoint=https://192.16.7.162:9003
17repo1-s3-key=12345678
18repo1-s3-key-secret=12345678
19repo1-type=s3
20repo1-s3-region=cn
21repo1-s3-uri-style=path
22repo1-s3-verify-tls=n
23
24[global:archive-push]
25compress-level=3 
26
27[pg16]
28pg1-path=/pg16/pgdata
29pg1-port=5441
30pg1-host-user=pg16
31
32EOF
参数名称描述
repo1-type=s3指定存储类型为 S3
repo1-path=/backup设置备份在 S3 存储桶中的路径
repo1-s3-bucket指定存储桶名称
repo1-s3-endpoint指定 S3 服务端点(如 s3.amazonaws.com 或自定义服务端点)
repo1-s3-keyS3 的访问密钥
repo1-s3-key-secretS3 的访问密钥对应的密码

若使用S3,则S3地址需要为https,不支持http:

1[pg16@lhrpgall ~]$ pgbackrest --stanza=pg16 --log-level-console=info stanza-create
22024-10-28 13:32:50.891 P00   INFO: stanza-create command begin 2.52.1--exec-id=2084081-6db25e43 --log-level-console=info --log-level-file=detail --log-path=/var/log/pgbackrest --pg1-path=/pg16/pgdata --pg1-port=5441 --repo1-s3-bucket=pgbk --repo1-s3-endpoint=http://172.16.7.162:9001 --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=cn --no-repo1-storage-verify-tls --repo1-type=s3 --stanza=pg16
32024-10-28 13:32:51.494 P00   INFO: stanza-create for stanza 'pg16' on repo1
4ERROR: [029]: expected protocol 'https' in URL 'http://192.16.7.162:9001'
52024-10-28 13:32:51.495 P00   INFO: stanza-create command end: aborted with exception [029]

配置https后,报错:

 1ERROR: [029]: unable to find child 'IsTruncated':0 in node 'ListAllMyBucketsResult'
2
3
4
5ERROR: [095]: unable to verify certificate presented by 'pgbk.127.0.0.1:9001 (127.0.0.1)': [18] self signed certificate
6           [CryptoError] on 12 retries from 104-60003ms: unable to verify certificate presented by 'pgbk.127.0.0.1:9001 (127.0.0.1)': [18] self signed certificate
7       --------------------------------------------------------------------
8       If SUBMITTING AN ISSUE please provide the following information:
9
10       version: 2.52.1
11       command: stanza-create
12       options: --exec-id=2161654-d1c7b9dd --log-level-console=debug --log-level-file=detail --log-path=/var/log/pgbackrest --pg1-path=/pg16/pgdata --pg1-port=5441 --repo1-s3-bucket=pgbk --repo1-s3-endpoint=https://127.0.0.1:9001 --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=cn --repo1-type=s3 --stanza=pg16
13
14       stack trace:

解决:增加: --repo-s3-uri-style=path repo1-s3-verify-tls=n   这里卡了麦老师很久。。。

参考:https://github.com/pgbackrest/pgbackrest/issues/2101

https://github.com/minio/minio/issues/19274

测试连接

 1source /home/pg16/.bash_profile
2pgbackrest --stanza=pg16 --log-level-console=info stanza-create
3
4pgbackrest --stanza=pg16 --log-level-console=info check
5pgbackrest --stanza=pg16 --log-level-console=info backup --type=full 
6pgbackrest --stanza=pg16 --log-level-console=info backup --type=diff 
7pgbackrest --stanza=pg16 --log-level-console=info backup --type=incr
8pgbackrest info
9
10
11
12create table t(id int, col2 text);
13insert into t select n, 'test123' || n || md5(random()::varcharfrom generate_series(16000000as 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|------------------------------------------|--------|---------------------|---------------------|------------|------------|----------------------|----------------------|------------------|------------------|--------------------------|--------------------------|------------------------------------------------------------------------------------------------------|
6520241030-093035F                         | full   | 2024-10-30 09:30:35 | 2024-10-30 09:30:53 | 588MB      | 588MB      | 180MB                | 180MB                | 1/D5000028       | 1/D5000138       | 0000000300000001000000D5 | 0000000300000001000000D5 |                                                                                                      |
6620241030-093114F                         | full   | 2024-10-30 09:31:14 | 2024-10-30 09:31:32 | 588MB      | 588MB      | 180MB                | 180MB                | 1/D7000028       | 1/D7000138       | 0000000300000001000000D7 | 0000000300000001000000D7 |                                                                                                      |
6720241030-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                                                                                     |
6820241030-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                                                  |
6920241030-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               |
7020241030-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                                                                                     |
7120241030-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                                                                                     |
7220241030-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                                                                                     |
7320241030-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上运行。



AiDBA
【PostgreSQL培训认证】【Oracle OCP、OCM、高可用(RAC+DG+OGG)培训认证】【MySQL OCP培训认证】【GreenPlum培训】【SQL Server培训】官网:www.dbaup.com,学习不止数据库
 最新文章