使用 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: cannot execute DROP DATABASE in a read-only transaction). Честно говоря, я еще не понял, с чем это связано. Решается следующим образом (нужно будет малость подождать после исполнения команды):

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

На самом деле, есть возможность восстановить конкретный бэкап по его имени. Здесь я лишь укажу ссылку на описание данной фичи в документации. Разработчики советуют использовать данный параметр с осторожностью и объясняют почему. От себя могу добавить, что я его использовал. Если очень нужно — убедитесь, что после восстановления база вышла из recovery mode (select pg_is_in_recovery() должен показать «f») и на всякий случай сделайте полный бэкап после восстановления.

3.啟動叢集:

sudo pg_ctlcluster 11 main start

恢復備份後,我們需要進行第二次備份:

儲存庫(pgbackrest 使用者):

sudo pgbackrest --stanza=main backup

就這樣。 最後,我想提醒您,我絕不是想冒充高級 dba,一有機會就會使用雲端。 目前,我自己正在開始研究各種主題,例如備份、複製、監控等。 我寫一些關於結果的小報告,以便為社區做出一點貢獻,並為自己留下一些小備忘單。

在接下來的文章中,我將嘗試討論其他功能 - 資料還原到乾淨的叢集、備份加密和發佈到 S3、透過 rsync 進行備份。

來源: www.habr.com

添加評論