1. WAL-E/G

WAL-G是一款开源数据库wal管理工具,提供了高性能的wal备份/还原能力,为了能更深入的介绍WAL-G,我们先聊聊WAL-E!

WAL-E是由Heroku公司设计的PostgreSQL备份工具,基于Python开发。基于PostgresSQL的连续归档和PITR能力,WAL-E主要有以下几个功能:

  • 在archive_command中设置wal-push,将wal文件压缩保存到第三方存储系统中(通常是S3)。
  • 在restore_command中设置wal-pull,Postgres可以在恢复模式下从第三方存储系统中获取wal。
  • 通过backup-push/catchup-push创建全量/增量的BaseBackup,实现数据库的Clone(类似于pg_basebackup)。
  • 通过backup-fetch/catchup-fetch获取全量/增量的BaseBackup,实现数据库的恢复。

借助WAL-E,用户可以比较简单的设计一套数据库灾备、快照、Clone方案。

WAL-G使用Golang重写了WAL-E的所有功能,并且进行了大量优化,相比WAL-E有以下优势:

  • 4倍以上的性能提升(作者Blog中提到,WAL-E的主要瓶颈在于需要通过PIPE实现多进程的数据流)
  • 支持LZ4,LZMA,Brotli等多种压缩算法,默认使用Brotli
  • 对多线程有更好支持
  • 支持Postgres/MySQL/MariaDB/MS SQL Server/MongoDB/Redis等数据库
  • 兼容WAL-E的数据格式
  • 支持非独占的创建Basebackup(non-exclusive base backups)

官方给出的WAL-E和WAL-G性能对比:

平均吞吐 标准差 中位数
WAL-E 323Mb/s 236 307Mb/s
WAL-G 838Mb/s 4.2 838Mb/s

官方给出的测试中,WAL-G在r4.8xlarge规格的虚拟机上达到了磁盘性能的物理限制,且稳定性远超WAL-E。

2.Quick Start

WAL-G是一个命令行工具,常用到的命令包括以下5个:

Command Purpose Executed
backup-list 打印Basebackup列表 Manually
backup-push 生成Basebackup Manually or automatically
wal-push 推送wal到存储 Automatically (archive_command)
backup-fetch 还原Basebackup Manually
wal-fetch Get a WAL from the archive Automatically (restore_command)

通常情况下,上述命令的调用者是Postgrescrontab,前者通过archive_command/restore_command参数备份/恢复wal文件,后者定时创建基础数据库备份(BaseBackup)。

在gitlab公司的postgresql运维手册中,推荐用户每天定时调用backup-push生成一份全量basebackup,并且通过wal-push从Master Postgres备份当天所有wal文件。手册中并没有在所有Postgres使用wal-fetch命令,而只在特定节点中配置。这些节点被标记为"archive"或"delayed"副本,并关闭了streaming replication。每个BaseBackup文档保留14天后移入回收站,并在120天后彻底删除(删除时间和S3供应商有关,文中gitlab用的是GCS)。

3.BaseBackup

BaseBackup可以简单认为是数据库执行Checkpoint后,数据库目录下所有文件的副本,通过BaseBackup我们可以创建数据库replicas。

WAL-G 主要通过手工或者定时任务的方式创建BaseBackup,并在有需要时从BaseBackup将数据库恢复到指定目录。

1. 创建

WAL-G支持远程连接到Postgres创建BaseBackup,此时WAL-G通过replication的方式连接数据库,Postgres需要在pg_hba.conf中添加相应的权限。

以下命令创建一个BaseBackup,并且推送到S3中:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
wal-g \
--pghost xx.xx.xx.xx \                 
--pgport 5432 \
--pgdatabase postgres \
--pgsslmode require \
--pguser postgres \
--pgpassword xxxxxx \
--aws-s3-force-path-style true \                      # minio对S3协议的兼容配置
--walg-s3-prefix s3://wal-g/postgres-ins \            # wal-g表示minio上的bucket名称,postgres-ins存储路径
--aws-endpoint http://minio.example.com \             # s3连接地址
--aws-access-key accesskey \                              # minio 认证信息
--aws-secret-access-key secretaccesskey \                  # minio 认证信息
backup-push --full                                    #  --full 全量备份

执行完毕后登录到S3,可以看到生成的BaseBackup以及对应元数据文件:

image-20220105110853767

2. 还原

通过BaseBackup文件可以还原数据库,执行以下命令查看S3上的BaseBackup文件

1
2
3
4
5
6
7
wal-g \
--aws-s3-force-path-style true \
--walg-s3-prefix s3://wal-g/postgres-ins \
--aws-endpoint http://minio.example.com \
--aws-access-key accesskey \
--aws-secret-access-key secretaccesskey \
backup-list

输出如下:

image-20220105111423085

指定要恢复的BaseBackup名称,即可在指定目录还原数据库文件:

1
2
3
4
5
6
7
wal-g \
--aws-s3-force-path-style true \
--walg-s3-prefix s3://wal-g/postgres-ins \
--aws-endpoint http://minio.example.com \
--aws-access-key accesskey \
--aws-secret-access-key secretaccesskey \
backup-fetch /home/postgres/pgdata base_000000020000000000000268

4.WAL备份/还原

WAL-G备份和还原wal的操作主要通过postgres来完成,参考postgres官方文档中PITR的说明(或者我博客),用户可以在Postgres中指定以下内容来设置WAL-G。

备份配置:

1
2
3
archive_mode: 'on'
archive_timeout: 300s
archive_command: 'envdir /etc/wal-g.d/env wal-g wal-push %p'

还原配置:

1
restore_command: 'envdir /etc/wal-g.d/env wal-g wal-fetch "%f" "%p"'

上述配置中:

  • postgres运行在Master状态时,会调用archive_command归档wal文件。
  • postgres运行在Recovery状态时,会调用restore_command恢复wal文件。

需要注意,envdir是一个环境变量工具,当执行wal-g命令时,/etc/wal-g.d/env目录下的环境变量会自动注入。

PS:wal-g的所有参数都可以通过环境变量指定,具体参考wal-g/configuration

5.Spilo with WAL-G

Spilo 中使用WAL-G/WAL-E包括以下几处:

  • standby集群/replicas节点启动时Clone(数据目录init/reinit),即替代pg_basebackup
  • 配置Postgres的restore_command,standby节点启动时优先从WAL-G数据同步,即Stream Replication Slot功能一起工作

恢复模式时,Postgres获取wal的优先级: restore_command > pg_wal目录 > streaming replication,参考:https://lqingcloud.cn/post/postgres-02/#standby-server

Spilo镜像涉及到脚本包括以下三个:

  • restore_command.sh:wal恢复脚本,recovery.conf文件中配置在restore_command参数,参考
  • wale_restore.sh:replicas实例初始化脚本,参考
  • clone_with_wale.py:standby集群的初始化脚本,参考

在Spilo中wal-g/wal-e主要作为pg_basebackup替代用于获取wal,不做为主库和备库之间差异的同步工具(这一步分工作由pg_rewind完成)。

6.其他应用场景

  • 恢复Postgres集群到指定时间点,参考Patroni官方的一个issue

7.编译wal-g

wal-g提供基于ubuntu的二进制文件(wal-g/releases)。

1
2
3
4
5
6
7
# 在Centos环境下编译时,需要安装brotli/brotli-devel
yum -y install brotli brotli-devel
git clone https://github.com/wal-g/wal-g.git
cd wal-g
make pg_build
cp main/pg/wal-g /usr/local/bin/
wal-g --version

参考