使用 pgbackrest 进行增量 postgresql 备份 - 开发人员为年轻战士提供的课程

免责声明

我是一名开发人员。 我仅以用户身份编写代码并与数据库交互。 我绝不会冒充系统管理员,更不会冒充 dba。 但…

恰巧我需要整理一个postgresql数据库的备份。 没有云 - 只需使用 SSH 并确保一切正常,无需付费。 遇到这种情况我们该怎么办? 没错,我们将 pgdump 推送到 cron 中,每天将所有内容备份到存档中,如果完全丢失,我们会将这个存档发送到很远的地方。

这次的困难在于,根据计划,数据库每天应该增长约+- 100 MB。 当然,几周后使用 pgdump 备份所有内容的愿望就会消失。 这就是增量备份可以发挥作用的地方。

有趣的? 欢迎来到猫。

增量备份是一种备份类型,此时并非复制所有源文件,而是仅复制新文件以及自创建上一个副本以来发生更改的文件。

就像任何(当时)绝对不愿意了解 postgres 的复杂性的开发人员一样,我想找到绿色按钮。 嗯,你知道,就像在 AWS、DigitalOcean 中一样:按下一个按钮 - 进行复制,按下第二个按钮 - 设置备份,第三个按钮 - 将所有内容回滚几个小时。 我没有找到按钮或漂亮的 GUI 工具。 如果您知道其中之一(免费或便宜),请在评论中写下。

谷歌搜索后我发现了两个工具 巴曼 и PG靠背。 我在第一个中根本没有成功(文档非常稀疏,我试图根据旧手册找出所有内容),但在第二个中,文档达到了标准,但并非没有缺陷。 为了简化那些面临类似任务的人的工作,写了这篇文章。

阅读本文后,您将了解如何进行增量备份,将其保存到远程服务器(具有备份的存储库),并在主服务器上发生数据丢失或其他问题时恢复它们。

训练

要复制该手册,您将需要两个 VPS。 第一个是存储(将存储备份的存储库),第二个实际上是带有 postgres 的服务器本身(在我的例子中,是 postgres 的版本 11)。

假设在带有postgres的服务器上你有root,sudo用户,postgres用户并且安装了postgres本身(postgres用户是在安装postgresql时自动创建的),并且在存储库服务器上有root和sudo用户(在手册中)将使用用户名 pgbackrest)。

为了让您在重现说明时遇到更少的问题,我用斜体字书写 我在哪里、用什么用户和什么权限执行了命令 在撰写和检查文章时。

安装 pgbackrest

存储库(用户 pgbackrest):

1. 从 pgbackrest 下载存档并将其内容传输到 /build 文件夹:

sudo mkdir /build
sudo wget -q -O - 
       https://github.com/pgbackrest/pgbackrest/archive/release/2.18.tar.gz | 
       sudo tar zx -C /build

2.安装组装所需的依赖项:

sudo apt-get update
sudo apt-get install build-essential libssl-dev libxml2-dev libperl-dev zlib1g-dev 
       libpq-dev

3. 组装靠背:

cd /build/pgbackrest-release-2.18/src && sudo ./configure
sudo make -s -C /build/pgbackrest-release-2.18/src

4、将可执行文件复制到/usr/bin目录下:

sudo cp /build/pgbackrest-release-2.18/src/pgbackrest /usr/bin
sudo chmod 755 /usr/bin/pgbackrest

5. Pgbackrest需要perl。 安装:

sudo apt-get install perl

6. 为日志创建目录,并赋予它们一定的权限:

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

7. 检查:

pgbackrest version

Postgres 服务器(sudo 用户或 root):

在带有 postgres 的服务器上安装 pgbackrest 的过程与在存储库上安装过程类似(是的,pgbackrest 必须安装在两台服务器上), 但在第 6 段中,第二个也是最后一个命令:

sudo chown pgbackrest:pgbackrest /var/log/pgbackrest
sudo chown pgbackrest:pgbackrest /etc/pgbackrest/pgbackrest.conf

用。。。来代替:

sudo chown postgres:postgres /var/log/pgbackrest
sudo chown postgres:postgres /etc/pgbackrest/pgbackrest.conf

通过无密码 SSH 设置服务器之间的交互

为了让pgbackrest正常工作,需要使用密钥文件配置postgres服务器和存储库之间的交互。

存储库(用户 pgbackrest):

创建密钥对:

mkdir -m 750 /home/pgbackrest/.ssh
ssh-keygen -f /home/pgbackrest/.ssh/id_rsa 
       -t rsa -b 4096 -N ""

警告! 我们在没有 sudo 的情况下运行上述命令。

Postgres 服务器(sudo 用户或 root):

创建密钥对:

sudo -u postgres mkdir -m 750 -p /var/lib/postgresql/.ssh
sudo -u postgres ssh-keygen -f /var/lib/postgresql/.ssh/id_rsa 
       -t rsa -b 4096 -N ""

存储库(sudo 用户):

将 postgres 服务器的公钥复制到存储库服务器:

(echo -n 'no-agent-forwarding,no-X11-forwarding,no-port-forwarding,' && 
       echo -n 'command="/usr/bin/pgbackrest ${SSH_ORIGINAL_COMMAND#* }" ' && 
       sudo ssh root@<postgres_server_ip> cat /var/lib/postgresql/.ssh/id_rsa.pub) | 
       sudo -u pgbackrest tee -a /home/pgbackrest/.ssh/authorized_keys

在此步骤中,您将被要求输入 root 用户的密码。 需要输入postgres服务器root用户的密码!

Postgres 服务器(sudo 用户):

使用 postgres 将存储库公钥复制到服务器:

(echo -n 'no-agent-forwarding,no-X11-forwarding,no-port-forwarding,' && 
       echo -n 'command="/usr/bin/pgbackrest ${SSH_ORIGINAL_COMMAND#* }" ' && 
       sudo ssh root@<repository_server_ip> cat /home/pgbackrest/.ssh/id_rsa.pub) | 
       sudo -u postgres tee -a /var/lib/postgresql/.ssh/authorized_keys

在此步骤中,您将被要求输入 root 用户的密码。 您需要准确输入存储库root用户的密码!

检查:

存储库(root用户,为了实验的纯度):

sudo -u pgbackrest ssh postgres@<postgres_server_ip>

Postgres服务器(root用户,为了实验的纯粹性):

sudo -u postgres ssh pgbackrest@<repository_server_ip>

我们确保我们能够毫无问题地访问。

设置 postgres 服务器

Postgres 服务器(sudo 用户或 root):

1. 让我们允许从外部 IP 访问 postgres 服务器。 为此,请编辑文件 配置文件 (位于 /etc/postgresql/11/main 文件夹中),向其中添加以下行:

listen_addresses = '*'

如果这样的行已经存在,请取消注释或将参数值设置为“*”。

在文件中 的pg_hba.conf (也位于文件夹中 /etc/postgresql/11/main)添加以下行:

hostssl  all  all  0.0.0.0/0  md5
host  all  all  0.0.0.0/0  md5

其中:

hostssl/host - подключаемся через SSL (или нет)
all - разрешаем подключение ко всем базам
all - имя пользователя, которому разрешаем подключение (всем)
0.0.0.0/0 - маска сети с которой можно подключаться
md5 - способ шифрования пароля

2. 让我们进行必要的设置 配置文件 (它在文件夹中 /etc/postgresql/11/main)让 pgbackrest 工作:

archive_command = 'pgbackrest --stanza=main archive-push %p' # Где main - название кластера. При установке postgres автоматически создает кластер main.
archive_mode = on
max_wal_senders = 3
wal_level = replica

3. 让我们在 pgbackrest 配置文件 (/etc/pgbackrest/pgbackrest.conf) 中进行必要的设置:

[main]
pg1-path=/var/lib/postgresql/11/main

[global]
log-level-file=detail
repo1-host=<repository_server_ip>

4.重新加载postgresql:

sudo service postgresql restart

设置存储库服务器

存储库(pgbackrest 用户):

让我们在配置文件中进行必要的设置 PG靠背
(/etc/pgbackrest/pgbackrest.conf):

[main]
pg1-host=<postgres_server_ip>
pg1-path=/var/lib/postgresql/11/main

[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2 # Параметр, указывающий сколько хранить полных бэкапов. Т.е. если у вас есть два полных бэкапа и вы создаете третий, то самый старый бэкап будет удален. Можно произносить как "хранить не более двух бэкапов" - по аналогии с ротациями логов. Спасибо @Aytuar за исправление ошибки.
start-fast=y # Начинает резервное копирование немедленно, прочитать про этот параметр можно тут https://postgrespro.ru/docs/postgrespro/9.5/continuous-archiving

创建存储库

存储库(pgbackrest 用户):

为集群创建新存储 :

sudo mkdir -m 770 /var/lib/pgbackrest
sudo chown -R pgbackrest /var/lib/pgbackrest/
sudo -u pgbackrest pgbackrest --stanza=main stanza-create

Проверка

Postgres 服务器(sudo 用户或 root):

我们检查 postgres 服务器:

sudo -u postgres pgbackrest --stanza=main --log-level-console=info check

存储库(pgbackrest 用户):

我们检查存储库服务器:

sudo -u pgbackrest pgbackrest --stanza=main --log-level-console=info check

我们确保在输出中看到“检查命令结束:成功完成”行。

疲劳的? 让我们继续最有趣的部分。

进行备份

存储库(pgbackrest 用户):

1. 执行备份:

sudo -u pgbackrest pgbackrest --stanza=main backup

2. 确保已创建备份:

ls /var/lib/pgbackrest/backup/main/

Pgbackrest 将创建第一个完整备份。 如果您愿意,可以再次运行备份命令并确保系统创建增量备份。

如果您想再次进行完整备份,请指定一个附加标志:

sudo -u pgbackrest pgbackrest --stanza=main --type=full backup

如果您想要详细的控制台输出,还需指定:

sudo -u pgbackrest pgbackrest --stanza=main --type=full --log-level-console=info backup

恢复备份

Postgres 服务器(sudo 用户或 root):

1. 停止正在运行的集群:

sudo pg_ctlcluster 11 main stop

2. 从备份恢复:

sudo -u postgres pgbackrest --stanza=main --log-level-console=info --delta --recovery-option=recovery_target=immediate restore

要将数据库恢复到上次完整备份的状态,请使用不指定recovery_target的命令:

sudo -u postgres pgbackrest --stanza=main --log-level-console=info --delta restore

重要的! 恢复后,可能会出现数据库卡在恢复模式的情况(会出现ERROR:无法在只读事务中执行DROP DATABASE之类的错误)。 说实话,我还没明白这有什么关系。 解决方法如下(命令执行后需要稍等一下):

sudo -u postgres psql -c "select pg_wal_replay_resume()"

事实上,可以通过名称来恢复特定的备份。 这里只有我 我将在文档中提供此功能描述的链接。 开发人员建议谨慎使用此选项并解释原因。 我可以补充一下我自己使用过它。 如果确实需要,请确保恢复后数据库退出恢复模式(选择 pg_is_in_recovery() 应显示“f”),并且为了以防万一,在恢复后进行完整备份。

3.启动集群:

sudo pg_ctlcluster 11 main start

恢复备份后,我们需要进行第二次备份:

存储库(pgbackrest 用户):

sudo pgbackrest --stanza=main backup

就这样。 最后,我想提醒您,我绝不是想冒充高级 dba,一有机会就会使用云。 目前,我自己正在开始研究各种主题,例如备份、复制、监控等。 我写一些关于结果的小报告,以便为社区做出一点贡献,并为自己留下一些小备忘单。

在接下来的文章中,我将尝试讨论其他功能 - 数据恢复到干净的集群、备份加密和发布到 S3、通过 rsync 进行备份。

来源: habr.com

添加评论