免责声明
我是一名开发人员。 我仅以用户身份编写代码并与数据库交互。 我绝不会冒充系统管理员,更不会冒充 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()"
事实上,可以通过名称来恢复特定的备份。 这里只有我
3.启动集群:
sudo pg_ctlcluster 11 main start
恢复备份后,我们需要进行第二次备份:
存储库(pgbackrest 用户):
sudo pgbackrest --stanza=main backup
就这样。 最后,我想提醒您,我绝不是想冒充高级 dba,一有机会就会使用云。 目前,我自己正在开始研究各种主题,例如备份、复制、监控等。 我写一些关于结果的小报告,以便为社区做出一点贡献,并为自己留下一些小备忘单。
在接下来的文章中,我将尝试讨论其他功能 - 数据恢复到干净的集群、备份加密和发布到 S3、通过 rsync 进行备份。
来源: habr.com