作者:王志斌,曾获得中国PostgreSQL数据库管理工程师(PGCE),是PostgreSQL官方认证讲师,盘古云课堂特邀金牌讲师。
Pgbackrest作为PostgreSQL数据库的备份和还原工具,在软件设计上综合考虑了功能和性能,包括完整性、一致性、安全性、数据压缩、异步并行等方面,其主要技术特性主要包括如下内容,如图所示:
- S3兼容
支持备份存储S3和Azure兼容对象存储上,如对象存储Minio。
- 压缩技术
支持gzip, bzip, lz4, zstd的压缩算法,并提供不同压缩等级。
- 异步、并行
在异步模式下通过并行推送和获取以加快处理速度,提高备份与还原处理效率。
- 校验和
采用checksum 算法,验证备份期间复制的每个文件的校验和。在完全备份期间,将验证所有页面的校验和,而在差异备份和增量式备份期间,将验证已更改文件的校验和。
- 加密
通过定义加密类型及密码,来保证备份数据的存储安全性。
在技术特性基础上,pgbackrest实现了备份、还原、保留策略、云端备份等相关功能,如图所示:
功能列表
- 备份方式
全量备份:将数据库集群的全部内容复制到备份中。数据库集群的第一个备份始终是全量备份。始终能够直接还原全量备份。全量备份不依赖于完整备份之外的任何文件来保持一致性。
增量备份:仅复制自上次全量备份以来已更改的那些数据库集群文件。通过复制所选差异备份中的所有文件以及先前全量备份中的相应未更改文件来还原差异备份。差异备份的优点在于,与全量备份相比,它需要的磁盘空间更少,但是,差异备份和全量备份都必须有效才能还原差异备份。
差异备份:仅复制自上次备份(可以是另一个增量备份,差异备份或全量备份)以来发生更改的那些数据库集群文件。由于增量备份仅包括自上次备份以来已更改的文件,因此它们通常比全量备份或差异备份小得多。与差异备份一样,增量备份依赖于其他备份才能有效还原增量备份。由于增量备份仅包括自上次备份以来的那些文件,因此,所有先前的增量备份(回到先前的差异备份),先前的差异备份和先前的全量备份都必须有效,才能执行增量备份的还原。如果不存在差异备份,则所有先前的所有增量备份都将还原为必须存在的先前的完整备份,并且完整备份本身必须有效才能还原增量备份。
- 保留策略
支持保留的备份数量,可以指定全量、差异备份的具体数量。
- 还原方式
支持全量、增量、差异还原以及时间点还原,还同时支持还原指定数据库、表空间和链接支持等。
- 异步归档
支持异步的推送和获取,利用pgbackrest并发特性,提升备份和还原的性能,同时在处理过程中对重新数据进行校验和处理,保证备份和还原数据正确性。
- 检查
检查命令验证pgBackRest和archive_command设置是否已正确配置以进行归档和备份。
- 监控
支持通过SQL查询方式,在PostgreSQL中创建函数查询检查信息,也可以通过Jq从Json中提取数据来进行查询。
- 加密
基于用户提供的密码及加密类型对存储库进行加密,防止未经授权访问存储库中的数据。
- 压缩
根据用户设定的压缩算法及压缩等级,将压缩后的数据存储到存储库中。
注:pgbackrest目前支持Postgresql 8.3以上版本
使用场景
Pgbackrest作为一款优秀的备份和还原工具,与PostgreSQL自带的pg_basebackup相比功能更加强大,尤其是体现在与应用场景的结合使用,下面主要从单机、远程、云端三个场景进行操作介绍:
操作环境系统版本:Centos 7
Pgbackrest版本:v2.24
PostgreSQL版本:12.2
单机使用
主机和备份存储在同一台物理主机上,为了确保备份数据的安全性,一般不推荐生成环境使用。
安装配置
首选需要进行源码下载和编译,然后配置pgbackrest的相关目录,并修改对应权限。
下载源码文件。
wget https://github.com/pgbackrest/pgbackrest/archive/release/2.26.tar.gz
安装编译相关依赖环境。
sudo yum install -y libxml2 libxml2-devel openssl openssl-devel
进行源码编译。
cd src/
./configure && make
拷贝执行程序到/usr/bin目录。
sudo cp pgbackrest /usr/bin
修改权限。
sudo chmod 755 /usr/bin/pgbackrest
创建配置日志目录。
sudo mkdir -p -m 770 /var/log/pgbackrest
修改访问权限
sudo chown pgbackrest:pgbackrest /var/log/pgbackrest
创建配置目录。
sudo mkdir -p /etc/pgbackrest
sudo mkdir -p /etc/pgbackrest/conf.d
创建配置文件。
sudo touch /etc/pgbackrest/pgbackrest.conf
sudo chmod 640 /etc/pgbackrest/pgbackrest.conf
修改访问权限。
sudo chown pgbackrest:pgbackrest /etc/pgbackrest/pgbackrest.conf
创建仓库路径。
sudo mkdir -p /var/lib/pgbackrest
sudo chmod 750 /var/lib/pgbackrest
sudo chown pgbackrest:pgbackrest /var/lib/pgbackrest
操作上述命令后,pgbackrest的配置基本完成,下面将进行配置节的操作。
服务器上配置节
在服务器上配置Pgbackrest节的相关内容,并修改Pgbackrest的配置文件。最后通过check命令来进行节的检查。
生成备份所需的密码。
openssl rand -base64 48
Dpy3iBVyfoAsDH+OQyApvpNT5ijs3jPI3fuVgTRKKbckN9HZe74ObGtsdkrhaa7T
修改配置文件。
vim /etc/pgbackrest/pgbackrest.conf
配置仓库路径。
[postgres]
pg1-path=/home/postgres/pg/data/
[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2
repo1-cipher-pass=Dpy3iBVyfoAsDH+OQyApvpNT5ijs3jPI3fuVgTRKKbckN9HZe74ObGtsdkrhaa7T
repo1-cipher-type=aes-256-cbc
process-max=3
[global:archive-push]
compress-level=3
配置归档。
vim /home/postgres/pg/data/postgresql.conf
archive_command = 'pgbackrest --stanza=postgres archive-push %p'
archive_mode = on
listen_addresses = '*'
log_line_prefix = ''
max_wal_senders = 3
wal_level = replica
重启数据库。
pg_ctl -D /home/postgres/pg/data restart
创建.pgpass文件,并设置环境变量。
vim ~/.pgpass
localhost:5432:postgres:postgres:postgres
chmod 0600 ~/.pgpass
设置环境变量。
vim ~/.bashrc
export PGPASSFILE=~/.pgpass
创建节
pgbackrest --stanza=postgres --log-level-console=info stanza-create
检查配置
pgbackrest --stanza=postgres --log-level-console=info check
创建备份
验证Pgbackrest的三种备份方式:即全量备份、增量备份、差异备份。
创建全量备份。
pgbackrest --stanza=postgres --log-level-console=info backup
插入部分数据后。
create table test1 (id int, rq date);
insert into test1 select generate_series(1,100000),now()+0;
执行增量备份。
pgbackrest --stanza=postgres --log-level-console=info --type=incr backup
查看备份信息。
pgbackrest info
插入部分数据后。
create table test2 (id int, rq date);
insert into test2 select generate_series(1,100000),now()+0;
执行差异备份。
pgbackrest --stanza=postgres --log-level-console=info --type=diff backup
可以通过以下命令,查看备份的详细信息。
pgbackrest info
远程仓库使用
远程仓库一般指通过建立单独的远端仓库,将数据备份到另一台物理主机上,实现可靠存储。
假设两台服务器,分别命名为Pg1和Pgbackrest1,其中:
Pg1:数据库服务器
Pgbackrest1: 远端仓库服务器
在Pgbackrest1上创建用户,并设置密码。
创建用户
useradd pgbackrest
passwd pgbackrest
在Pg1上创建用户,并设置密码。
useradd postgres
passwd postgres
配置SSH免密
在两个服务器上修改相关文件
vim /etc/hosts
192.168.56.3 Pg1
192.168.56.4 Pgbackrest1
vim /etc/ssh/sshd_config
PubkeyAuthentication yes
StrictHostKeyChecking no
在Pgbackrest1上创建ssh
su - pgbackrest
mkdir -m 750 /home/pgbackrest/.ssh
ssh-keygen -f /home/pgbackrest/.ssh/id_rsa -t rsa -b 4096 -N “”
在Pg1上创建ssh
su - postgres
mkdir -m 750 -p /home/postgres/.ssh
ssh-keygen -f /home/postgres/.ssh/id_rsa -t rsa -b 4096 -N ""
在Pgbackrest1上执行
ssh-copy-id -i ~/.ssh/id_rsa.pub postgres@Pg1
在Pg1上执行
ssh-copy-id -i ~/.ssh/id_rsa.pub pgbackrest@Pgbackrest1
配置pgbackrest
在Pgbackrest1上修改文件执行权限,(如何编译pgbackrest参见单机使用部分)。
chmod 755 /usr/bin/pgbackrest
在Pgbackrest1上创建配置文件和路径。
mkdir -p -m 770 /var/log/pgbackrest
chown pgbackrest:pgbackrest /var/log/pgbackrest
mkdir -p /etc/pgbackrest
mkdir -p /etc/pgbackrest/conf.d
touch /etc/pgbackrest/pgbackrest.conf
chmod 640 /etc/pgbackrest/pgbackrest.conf
chown pgbackrest:pgbackrest /etc/pgbackrest/pgbackrest.conf
在Pgbackrest1上创建仓库路径
mkdir -p /var/lib/pgbackrest
chmod 750 /var/lib/pgbackrest
chown pgbackrest:pgbackrest /var/lib/pgbackrest
在Pgbackrest1上修改配置文件
vim /etc/pgbackrest/pgbackrest.conf
内容如下:
[postgres]
pg1-host=Pg1
pg1-path=/home/postgres/postgres/data
pg1-host-user=postgres
pg1-user=sys
[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2
start-fast=y
在Pg1上执行,配置pgbackrest相关目录
chmod 755 /usr/bin/pgbackrest
mkdir -p -m 770 /var/log/pgbackrest
chown postgres:postgres /var/log/pgbackrest
mkdir -p /etc/pgbackrest
mkdir -p /etc/pgbackrest/conf.d
touch /etc/pgbackrest/pgbackrest.conf
chmod 640 /etc/pgbackrest/pgbackrest.conf
chown postgres:postgres /etc/pgbackrest/pgbackrest.conf
在Pg1上执行,修改pgbackrest配置文件
vim /etc/pgbackrest/pgbackrest.conf
增加如下内容:
[postgres]
pg1-path=/home/postgres/postgres/data
pg1-user=postgres
[global]
log-level-file=detail
repo1-host=Pgbackrest1
在Pg1上执行,配置数据库密码
vim ~/.pgpass
localhost:5432:postgres:postgres:postgres
chmod 0600 ~/.pgpass
在Pg1上执行,设置环境变量
vim ~/.bashrc
export PGPASSFILE=~/.pgpass
在Pg1上,更新postgresql.conf文件
archive_command = 'pgbackrest --stanza=postgres archive-push %p'
archive_mode = on
listen_addresses = '*'
log_line_prefix = ''
max_wal_senders = 3
wal_level = replica
重新启动PostgreSQL使配置文件更改生效。
执行备份
在Pgbackrest1上创建节
pgbackrest --stanza=postgres stanza-create --log-level-console=info
在Pgbackrest1上创建备份
pgbackrest --stanza=postgres backup --log-level-console=info
可以在备份路径下找到创建的路径和文件。
在Pg1上创建表,插入测试数据
psql -Upostgres -dpostgres
create table test(id int);
insert into test select generate_series(1,1000);
在Pgbackrest1上再次创建备份
pgbackrest --stanza=postgres backup --log-level-console=info
此时已经保存了两份备份,第一份为全量备份、第二份为增量备份。
执行还原
在Pg1上运行pgbackrest还原,需要先停止PostgreSQL,然后执行还原操作。
pgbackrest --stanza=postgres --log-level-console=info --delta restore
因为此时还原操作默认从第一份全量备份进行还原,没有之前的数据,所以从增量备份中还原数据,需要在–recovery-option中使用recovery_target来运行还原命令
pgbackrest --stanza=postgres--delta restore --recovery-option=recovery_target=immediate
再次检查数据库,发现之前插入的数据已经还原。
云端使用
由于现在很多企业的服务都逐步向云端迁移,而在云端环境中,对象存储越来越多被使用,因此本节将介绍在云端场景下,Minio作为对象存储,模拟Pgbackrest通过S3接口,将数据库备份存储到对象存储中,以下是具体配置过程:
配置Minio环境
首先创建minio的环境及相关配置,包括用户、数据目录、桶等内容。
安装minio
创建minio专属用户
$ useradd -s /sbin/nologin -d /opt/minio minio
创建minio的执行和数据目录
$ mkdir -p /opt/minio/bin
$ mkdir -p /opt/minio/data
部署minio程序到执行目录中
$ yum install -y wget
$ wget https://dl.min.io/server/minio/release/linux-amd64/minio -O /opt/minio/bin/minio
$ chmod +x /opt/minio/bin/minio
配置minio的相关参数
$ cat<<EOF | sudo tee "/opt/minio/minio.conf"
MINIO_VOLUMES=/opt/minio/data
MINIO_DOMAIN=minio.local
MINIO_OPTS="--certs-dir /opt/minio/certs --address :443 --compat"
MINIO_ACCESS_KEY="minioadmin"
MINIO_SECRET_KEY="minioadmin"
EOF
参数解释如下:
MINIO_VOLUMES:存储数据的目录
MINIO_DOMAIN: 访问的域名
MINIO_OPTS:证书访问路径
MINIO_ACCESS_KEY:用户名
MINIO_SECRET_KEY:访问密码
配置主机,将域名映射到本机上
$ chown -R minio:minio /opt/minio
$ cat<<EOF | sudo tee "/etc/hosts"
127.0.0.1 pgbackrest.minio.local minio.local s3.eu-west-3.amazonaws.com
EOF
配置证书,通过openssl生成对应公钥、私钥、证书
$ mkdir ~/certs
$ cd ~/certs
$ openssl genrsa -out ca.key 2048
$ openssl req -new -x509 -extensions v3_ca -key ca.key -out ca.crt -days 99999 -subj "/C=BE/ST=Country/L=City/O=Organization/CN=some-really-cool-name"
$ openssl genrsa -out server.key 2048
$ openssl req -new -key server.key -out server.csr -subj "/C=BE/ST=Country/L=City/O=Organization/CN=some-really-cool-name"
$ openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 99999 -sha256
$ mkdir -p -m 755 /opt/minio/certs
$ cp server.crt /opt/minio/certs/public.crt
$ cp server.key /opt/minio/certs/private.key
$ chown -R minio:minio /opt/minio/certs
$ chmod -R 644 /opt/minio/certs/public.crt
$ chmod -R 644 /opt/minio/certs/private.key
配置Minio配置为Linux服务
Create the systemd service:
$ cat<<EOF | sudo tee "/etc/systemd/system/minio.service"
[Unit]
Description=Minio
Documentation=https://docs.minio.io
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/opt/minio/bin/minio
[Service]
AmbientCapabilities=CAP_NET_BIND_SERVICE
WorkingDirectory=/opt/minio
User=minio
Group=minio
PermissionsStartOnly=true
EnvironmentFile=-/opt/minio/minio.conf
ExecStartPre=/bin/bash -c "[ -n \\"\${MINIO_VOLUMES}\\" ] || echo \\"Variable MINIO_VOLUMES not set in /opt/minio/minio.conf\\""
ExecStart=/opt/minio/bin/minio server \$MINIO_OPTS \$MINIO_VOLUMES
StandardOutput=journal
StandardError=inherit
# Specifies the maximum file descriptor number that can be opened by this process
LimitNOFILE=65536
# Disable timeout logic and wait until process is stopped
TimeoutStopSec=0
# SIGTERM signal is used to stop Minio
KillSignal=SIGTERM
SendSIGKILL=no
SuccessExitStatus=0
[Install]
WantedBy=multi-user.target
EOF
$ systemctl enable minio
$ systemctl start minio
$ firewall-cmd --quiet --permanent --add-service=https
$ firewall-cmd --quiet --reload
$ systemctl status minio
注:红色字体部分需要根据实际环境进行调整。
安装s3cmd,并创建bucket
$ yum install -y epel-release
$ yum --enablerepo epel-testing install -y s3cmd
$ cat<<EOF > ~/.s3cfg
host_base = minio.local
host_bucket = pgbackrest.minio.local
bucket_location = eu-west-3
use_https = true
access_key = minioadmin
secret_key = minioadmin
EOF
$ s3cmd mb --no-check-certificate s3://pgbackrest
Bucket 's3://pgbackrest/' created
$ mkdir /opt/minio/data/pgbackrest/repo
$ sudo chown minio: /opt/minio/data/pgbackrest/repo
$ s3cmd ls --no-check-certificate s3://pgbackrest/repo DIR s3://pgbackrest/repo/
配置Pgbackrest
配置pgBackRest指向S3 bucket
$ cat<<EOF | sudo tee "/etc/pgbackrest.conf"
[global]
repo1-path=/repo
repo1-type=s3
repo1-s3-endpoint=minio.local
repo1-s3-bucket=pgbackrest
repo1-s3-verify-tls=n
repo1-s3-key=minioadmin
repo1-s3-key-secret=minioadmin
repo1-s3-region=eu-west-3
repo1-retention-full=1
process-max=2
log-level-console=info
log-level-file=debug
start-fast=y
delta=y
[postgres]
pg1-path=/home/postgres/pg/data
EOF
执行操作
可以切换到pgbackres用户,进行节的创建,检查
$ su - pgbackrest
$ pgbackrest --stanza=postgres stanza-create
$ pgbackrest --stanza=postgres check
执行全量备份,并查看备份的详细情况
$ pgbackrest --stanza=postgres --type=full backup
$ pgbackrest --stanza=postgres info
常见问题
如何从备机做备份
主数据库和备用数据库都需要执行备份,大多数文件将从备用数据库复制以减少主数据库上的负载。可以以任何顺序配置数据库主机。pgbackrest将自动确定哪个是primary,哪个是standby。
通过配置备用主机并启用backup-standby选项,当存在多个备用数据库,则找到的第一个正在运行的备用数据库将用于备份。
[postgres]
pg1-host=pg-primary
pg1-path=/home/postgres/pg/data
pg2-host=pg-standby
pg2-path=/home/postgres/pg/data
[global]
backup-standby=y
process-max=3
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2
start-fast=y
如果得到“无法找到WAL段”的错误该怎么办,如何排除?
一个错误的原因可能是很多不同问题导致的,如下:
- 错误配置archive_command
- 错误配置pgbackrest的配置文件
- 网络或权限问题
- 第三方产品 (例如S3, Swift or Minio) 配置问题
- 大量的WAL排队等待归档
建议:
- 检查PostgreSQL中的archive_command
- 检查每台主机上的pgbackrest配置 (仓库主机和数据库主机)
- 运行检查命令,在pgbackrest配置文件上设置–archive-timeout为较高的值(或默认),以查看WAL队列是否需要更多时间来清除。如果系统生成大量WAL,那么考虑配置异步归档。
如何为每个命令进行单独配置?
pgbackrest能够为配置文件中的每个命令单独设置选项。
示例,每个命令都可以优化process-max?选项:
[global]
# used where not overridden
process-max=2
[global:backup]
# more cores for backup
process-max=4
[global:restore]
# all the cores for restore
process-max=8
[global:archive-push]
# more cores for archive-push
process-max=3
[global:archive-get]
# fewer cores for archive-get
process-max=1
能在S3桶名称中使用点(句点)吗?
RFC-2818不允许通配符在点(.)上匹配,因此s3存储桶名称不能包含点。如果S3存储桶名称中有点,则会出现错误,如在证书的通用名称或使用者替代名称中无法找到主机名’my.backup.bucket.s3.amazonaws.com’。
引文
[1] https://postgresconf.org/conferences/AsiaChina2020/program/proposals/backup-best-practices-with-pgbackrest
[2] https://pgbackrest.org/1/user-guide.html
[3] https://pgbackrest.org/1/configuration.html
[4] https://pgbackrest.org/1/command.html
[5] https://pgstef.github.io/2019/07/19/pgbackrest_s3_configuration.html
[6] https://tools.ietf.org/html/rfc2818
了解更多PostgreSQL热点资讯、新闻动态、精彩活动,请访问中国PostgreSQL官方网站:www.postgresqlchina.com
解决更多PostgreSQL相关知识、技术、工作问题,请访问中国PostgreSQL官方问答社区:www.pgfans.cn
下载更多PostgreSQL相关资料、工具、插件问题,请访问中国PostgreSQL官方下载网站:www.postgreshub.cn
转载:https://blog.csdn.net/weixin_46199817/article/details/115167166