Опровержение
Аз съм разработчик. Пиша код, взаимодействам с базата данни само като потребител. В никакъв случай не се правя на системен администратор и още повече на dba. Но…
Случи се така, че трябваше да организирам резервно копие на базата данни postgresql. Без облаци - поддържайте SSH и направете всичко да работи и да не иска пари. Какво правим в такива случаи? Точно така, пъхаме pgdump в cron, архивираме всичко в архива всеки ден и ако се разпръснем напълно, изпращаме този архив някъде далеч.
Този път трудността беше, че според плановете базата данни трябваше да расте с около + - 100 MB на ден. Разбира се, след няколко седмици желанието да архивирате всичко с pgdump ще изчезне. Това е мястото, където инкременталните архиви са полезни.
Интересно? Добре дошли под кат.
Инкременталното архивиране е вид архивиране, когато не се копират всички изходни файлове, а само нови и променени след създаването на предишното копие.
Като всеки разработчик, който ТОТАЛНО не желаеше (по това време) да разбере тънкостите на postgres, исках да намеря зелен бутон. Е, знаете, като в AWS, DigitalOcean: натиснах един бутон - получих репликация, натиснах втория - настроих резервни копия, третия - всичко се върна преди няколко часа. Не намерих бутон и красив GUI инструмент. Ако знаете такъв (безплатен или евтин) - пишете за него в коментарите.
Гугъл намерих два инструмента пгбарман и pgоблегалка. С първия просто не успях (много лоша документация, опитах се да взема всичко според стари ръководства), но второто се оказа на ниво документация, но не и без недостатък. За да се опрости работата на тези, които са изправени пред подобна задача, е написана тази статия.
След като прочетете тази статия, ще научите как да правите инкрементални архиви, да ги запазвате на отдалечен сървър (хранилище с резервни копия) и да ги възстановявате в случай на загуба на данни или други проблеми на главния сървър.
Обучение
Ще ви трябват два VPS, за да играете ръководството. Първото ще е хранилището (хранилището, в което ще бъдат архивите), а второто всъщност самият сървър с postgres (в моя случай версия 11 на postgres).
Предполага се, че на сървъра с postgres имате инсталиран root, sudo потребител, postgres потребител и самия postgres (потребителят на postgres се създава автоматично, когато се инсталира postgresql), а на сървъра на хранилището имате root и sudo потребител (потребителско име pgbackrest ще да се използва в ръководството).
За да имате по-малко проблеми при възпроизвеждане на инструкциите - пиша в курсив къде, с какъв потребител и с какви права съм изпълнил командата докато пишете и преглеждате статията.
pgмонтиране на облегалката
Хранилище (потребител на 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):
Процесът на инсталиране на pgbackrest на postgres сървър е подобен на инсталиране в хранилище (да, 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 потребителя. Трябва да въведете точно паролата на root потребителя на postgres сървъра!
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. Нека разрешим "чукване" на postgres сървъра от външен ip. За да направите това, редактирайте файла postgresql.conf (намиращ се в папката /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. Да направим необходимите настройки postgresql.conf (това е в папката /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
важно! След възстановяването може да се окаже, че базата данни виси в режим на възстановяване (ще има грешки като ГРЕШКА: не може да се изпълни 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.
Източник: www.habr.com