免責聲明
我是一名開發人員。 我僅以使用者身分編寫程式碼並與資料庫互動。 我絕不會冒充系統管理員,更不會冒充 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()"
На самом деле, есть возможность восстановить конкретный бэкап по его имени. Здесь я лишь
3.啟動叢集:
sudo pg_ctlcluster 11 main start
恢復備份後,我們需要進行第二次備份:
儲存庫(pgbackrest 使用者):
sudo pgbackrest --stanza=main backup
就這樣。 最後,我想提醒您,我絕不是想冒充高級 dba,一有機會就會使用雲端。 目前,我自己正在開始研究各種主題,例如備份、複製、監控等。 我寫一些關於結果的小報告,以便為社區做出一點貢獻,並為自己留下一些小備忘單。
在接下來的文章中,我將嘗試討論其他功能 - 資料還原到乾淨的叢集、備份加密和發佈到 S3、透過 rsync 進行備份。
來源: www.habr.com