Kohë më parë është e njohur se bërja e backup-eve në SQL dump (duke përdorur pg_dump ose pg_dumpall) – nuk është ideja më e mirë. Për backup-in e bazave të të dhënave PostgreSQL, është më mirë të përdorish komandën pg_basebackup, e cila krijon një kopje binare të regjistrimeve WAL. Por kur fillon të studiohesh të gjithë procesin e krijimit dhe rikuperimit të kopjeve, do të kuptosh se duhet të shkruash së paku disa "bicikleta me tri rrota" që të gjitha këto funksionojnë dhe të mos të shkaktojnë dhimbje as lart as poshtë. Për të lehtësuar vuajtjet, u zhvillua WAL-G.
– është një mjet i shkruar në Go për rezervimin dhe rikuperimin e bazave të të dhënave PostgreSQL (dhe që nga kohët e fundit edhe MySQL/MariaDB, MongoDB dhe FoundationDB). Ai mbështet punën me depo të Amazon S3 (dhe ngjashme, për shembull, Yandex Object Storage), si dhe me Google Cloud Storage, Azure Storage, Swift Object Storage dhe thjesht me sistemin e skedarëve. I gjithë konfigurimi përbëhet nga hapa të thjeshtë, por për shkak se artikujt për të janë të shpërndarë në internet – nuk ka një manual të plotë how-to që të përfshijë të gjitha hapat nga fillimi në fund (në Habra ka disa postime, por shumë momente atje janë të lëna pas dore).

Ky artikull është shkruar kryesisht për të sistematizuar njohuritë e mia. Unë nuk jam DBA dhe ndonjëherë mund të shprehem në një gjuhë më të thjeshtë teknike, kështu që çdo korrigjim është i mirëpritur!
Do të theksoj veçmas se gjithçka më poshtë është e vlefshme dhe e verifikuar për PostgreSQL 12.3 në Ubuntu 18.04, të gjitha komandat duhet të kryhen nga një përdorues me privilegje.
Instalimi
Në momentin e shkruajtes së këtij artikulli, versioni stabil i WAL-G është . Ky është versioni që do të përdorim (por nëse dëshiron ta ndërtosh vetë nga dega master, në depozitën në github ka të gjitha udhëzimet për këtë). Për shkarkimin dhe instalimin, duhet të ekzekutosh:
#!/bin/bash
curl -L "https://github.com/wal-g/wal-g/releases/download/v0.2.15/wal-g.linux-amd64.tar.gz" -o "wal-g.linux-amd64.tar.gz"
tar -xzf wal-g.linux-amd64.tar.gz
mv wal-g /usr/local/bin/
Pas kësaj, duhet të konfigurosh së pari WAL-G, dhe pastaj PostgreSQL-in vetë.
Konfigurimi i WAL-G
Për shembull, për ruajtjen e backup-eve do të përdorim Amazon S3 (sepse është më afër serverëve të mi dhe përdorimi i tij është shumë i lirë). Për të punuar me të, nevojitet një "s3-bucket" dhe çelësat e aksesit.
Në të gjithë artikujt e mëparshëm mbi WAL-G është përdorur konfigurimi me ndihmën e variablëve të mjedisit, por që nga ky version, konfigurimet mund të vendosen në në katalogun e përdoruesit postgres. Për ta krijuar, do të ekzekutojmë skriptin bash të mëposhtëm:
#!/bin/bash
cat > /var/lib/postgresql/.walg.json << EOF
{
"WALG_S3_PREFIX": "s3://your_bucket/path",
"AWS_ACCESS_KEY_ID": "key_id",
"AWS_SECRET_ACCESS_KEY": "secret_key",
"WALG_COMPRESSION_METHOD": "brotli",
"WALG_DELTA_MAX_STEPS": "5",
"PGDATA": "/var/lib/postgresql/12/main",
"PGHOST": "/var/run/postgresql/.s.PGSQL.5432"
}
EOF
# обязательно меняем владельца файла:
chown postgres: /var/lib/postgresql/.walg.json
Pak do të shpjegoj për të gjitha parametrat:
- WALG_S3_PREFIX – rruga për bucket-in tuaj S3 ku do të ngarkohen kopjet rezervë (mund të jetë si në rrënjë ashtu edhe në një dosje);
- AWS_ACCESS_KEY_ID – çelësi i qasjes në S3 (në rast rikuperimi në serverin testues – këto çelësa duhet të kenë Politika ReadOnly! Për këtë është shkruar më shumë në seksionin për rikuperimin);
- AWS_SECRET_ACCESS_KEY – çelësi sekret në krijesën S3;
- WALG_COMPRESSION_METHOD – metoda e kompresimit, është më mirë të përdorni Brotli (sepse kjo është ari i mesëm midis madhësisë përfundimtare dhe shpejtësisë së kompresimit/zhvëndosjes);
- WALG_DELTA_MAX_STEPS – numri i "deltave" para krijimit të një kopje rezervë të plotë (lejojnë të kurseni kohë dhe madhësinë e të dhënave që ngarkohen, por mund të ngadalësojnë pak procesin e rikuperimit, kështu që nuk është e dëshirueshme të përdoren vlera të mëdha);
- PGDATA – rruga për direktorinë me të dhënat e bazës suaj (mund të mësoni duke ekzekutuar komandën pg_lsclusters);
- PGHOST – lidhja me bazën, kur bëni kopje rezervë lokale është më mirë të bëni përmes unix-socket si në këtë shembull.
Parametrat e tjerë mund të shihen në dokumentacion: .
Konfigurimi i PostgreSQL
Për të lejuar që arkivuesi brenda bazës të ngarkojë vetë WAL-logjet në cloud dhe të rikuperohet prej tyre (nëse është e nevojshme) – duhet të vendosni disa parametra në skedarin e konfigurimit /etc/postgresql/12/main/postgresql.conf. Por së pari ju duhet të siguroheni, që asnjë nga parametrat e mëposhtëm nuk është vendosur në ndonjë vlerë tjetër, në mënyrë që kur të rinisni konfigurimin – DBMS të mos bjerë. Këta parametra mund të shtohen me anë të:
#!/bin/bash
echo "wal_level=replica" >> /etc/postgresql/12/main/postgresql.conf
echo "archive_mode=on" >> /etc/postgresql/12/main/postgresql.conf
echo "archive_command='/usr/local/bin/wal-g wal-push "%p" >> /var/log/postgresql/archive_command.log 2>&1' " >> /etc/postgresql/12/main/postgresql.conf
echo “archive_timeout=60” >> /etc/postgresql/12/main/postgresql.conf
echo "restore_command='/usr/local/bin/wal-g wal-fetch "%f" "%p" >> /var/log/postgresql/restore_command.log 2>&1' " >> /etc/postgresql/12/main/postgresql.conf
# перезагружаем конфиг через отправку SIGHUP сигнала всем процессам БД
killall -s HUP postgres
Përshkrimi i parametrave të vendosur:
- wal_level – sa informacion duhet të shkruhet në WAL-logjet, "replica" – shkruani gjithçka;
- archive_mode – aktivizimi i ngarkimit të WAL-logjeve duke përdorur komandën nga parametri archive_command;
- archive_command – komanda për arkivimin e WAL-logut të përfunduar;
- archive_timeout – arkivimi i logjeve realizohet vetëm kur ai është e përfunduar, por nëse serveri juaj bën pak ndryshime/shtesa të dhënash në DB, atëherë ka kuptim të vendosni një kufi në sekonda, pas të cilit komanda e arkivimit do të thirret me forcë (kam një shkruar intensiv në bazë çdo sekondë, kështu që kam hequr dorë nga vendosja e këtij parametri në prodhim);
- restore_command – komanda për rikuperimin e WAL-logut nga kopja rezervë, do të përdoret në rast se në "kopjen rezervë të plotë" (base backup) mungojnë ndryshimet e fundit në DB.
Më shumë rreth të gjithë këtyre parametrave mund të lexoni në përkthimin e dokumentacionit zyrtar: .
Konfigurimi i programit të kopjimit
Sido që është, mënyra më e lehtë për të filluar është përdorimi i cron. Ky është ai që do të konfigurojmë për të krijuar kopje rezervë. Le të fillojmë me komandën për krijimin e një backup-i të plotë: në wal-g ky është argumenti i nisjes. backup-push. Por së pari, është më mirë ta ekzekutoni këtë komandë manualisht nga përdoruesi postgres, për të siguruar që gjithçka po shkon mirë (dhe nuk ka ndonjë gabim në qasje):
#!/bin/bash
su - postgres -c '/usr/local/bin/wal-g backup-push /var/lib/postgresql/12/main'
Në argumentet e nisjes është e specifikuar rruga për direktorinë me të dhëna – kujtoj se mund ta merrni atë duke ekzekutuar pg_lsclusters.
Nëse gjithçka kaloi pa gabime dhe të dhënat u ngarkuan në magazinën S3, atëherë mund të konfigurojmë një nisje periodike në crontab:
#!/bin/bash
echo "15 4 * * * /usr/local/bin/wal-g backup-push /var/lib/postgresql/12/main >> /var/log/postgresql/walg_backup.log 2>&1" >> /var/spool/cron/crontabs/postgres
# задаем владельца и выставляем правильные права файлу
chown postgres: /var/spool/cron/crontabs/postgres
chmod 600 /var/spool/cron/crontabs/postgres
Në këtë shembull, procesi i backup-it niset çdo ditë në orën 4:15 të mëngjesit.
Fshirja e kopjeve rezervë të vjetra
Së bashku me siguri nuk keni nevojë të ruani të gjitha kopjet rezervë nga epoka mezozoike, prandaj do të jetë e dobishme që herë pas here të "pastroni" magazinën tuaj (si "kopje rezervë të plota", ashtu edhe regjistrat WAL). Këtë do ta bëjmë gjithashtu përmes një detyre cron:
#!/bin/bash
echo "30 6 * * * /usr/local/bin/wal-g delete before FIND_FULL $(date -d '-10 days' '+%FT%TZ') --confirm >> /var/log/postgresql/walg_delete.log 2>&1" >> /var/spool/cron/crontabs/postgres
# ещё раз задаем владельца и выставляем правильные права файлу (хоть это обычно это и не нужно повторно делать)
chown postgres: /var/spool/cron/crontabs/postgres
chmod 600 /var/spool/cron/crontabs/postgres
Cron do ta ekzekutojë këtë detyrë çdo ditë në orën 6:30 të mëngjesit, duke fshirë gjithçka (kopje rezervë të plota, delta dhe WAL) përveç kopjeve për 10 ditët e fundit, por do të lërë të paktën një kopje rezervë në nga data e caktuar, për të siguruar që çdo pikë pas e datës të bjerë brenda PITR.
Rivendosja nga një kopje rezervë
Nuk është sekret për askënd që çelësi i një baze të shëndetshme është rivendosja periodike dhe kontrollimi i integritetit të të dhënave brenda. Si të rivendosni me ndihmën e WAL-G, do t'ju tregoj në këtë seksion, dhe do të flasim për kontrollet më vonë.
Është e rëndësishme të theksohet se për rivendosjen në një ambient testimi (çdo gjë që nuk është prodhim) – duhet të përdorni një llogari Read Only në S3, për të mos ngatërruar kopjet rezervë. Në rastin e WAL-G, duhet t'i jepni përdoruesit S3 të drejtat e mëposhtme në Politikat e Grupit (Efekti: Lejo): s3:GetObject, s3:ListBucket, s3:GetBucketLocation. Dhe, sigurisht, mos harroni të vendosni paraprakisht archive_mode=off në skedarin e konfigurimeve postgresql.conf, që baza juaj e testimit të mos tentojë të bëjë backup fshehurazi.
Rivendosja bëhet me një lëvizje të lehtë të dorës nga fshirja e të dhënave të gjitha PostgreSQL (duke përfshirë përdoruesit), prandaj, ju lutem, jini tejet të kujdesshëm kur të ekzekutoni komandat e ardhshme.
#!/bin/bash
# если есть балансировщик подключений (например, pgbouncer), то вначале отключаем его, чтобы он не нарыгал ошибок в лог
service pgbouncer stop
# если есть демон, который перезапускает упавшие процессы (например, monit), то останавливаем в нём процесс мониторинга базы (у меня это pgsql12)
monit stop pgsql12
# или останавливаем мониторинг полностью
service monit stop
# останавливаем саму базу данных
service postgresql stop
# удаляем все данные из текущей базы (!!!); лучше предварительно сделать их копию, если есть свободное место на диске
rm -rf /var/lib/postgresql/12/main
# скачиваем резервную копию и разархивируем её
su - postgres -c '/usr/local/bin/wal-g backup-fetch /var/lib/postgresql/12/main LATEST'
# помещаем рядом с базой специальный файл-сигнал для восстановления (см. https://postgrespro.ru/docs/postgresql/12/runtime-config-wal#RUNTIME-CONFIG-WAL-ARCHIVE-RECOVERY ), он обязательно должен быть создан от пользователя postgres
su - postgres -c 'touch /var/lib/postgresql/12/main/recovery.signal'
# запускаем базу данных, чтобы она инициировала процесс восстановления
service postgresql start
Për ata që dëshirojnë të kontrollojnë procesin e rikuperimit — më poshtë është përgatitur një copë bash-magjie, që në rast problemesh në rikuperim — skripti do të dështojë me një kod dalës jo zero. Në këtë shembull, bëhen 120 kontrolle me një kohë limite prej 5 sekondash (gjithsej 10 minuta për rikuperim), për të mësuar nëse është fshirë skedari i sinjalit (kjo do të thotë që rikuperimi ka përfunduar me sukses):
#!/bin/bash
CHECK_RECOVERY_SIGNAL_ITER=0
while [ ${CHECK_RECOVERY_SIGNAL_ITER} -le 120 ]
do
if [ ! -f "/var/lib/postgresql/12/main/recovery.signal" ]
then
echo "recovery.signal removed"
break
fi
sleep 5
((CHECK_RECOVERY_SIGNAL_ITER+1))
done
# если после всех проверок файл всё равно существует, то падаем с ошибкой
if [ -f "/var/lib/postgresql/12/main/recovery.signal" ]
then
echo "recovery.signal still exists!"
exit 17
fi
Pas një rikuperimi të suksesshëm, mos harroni të riktheni të gjitha proceset (pgbouncer/monit etj.).
Kontrolli i të dhënave pas rikuperimit
Duhet patjetër të kontrolloni integritetin e bazës pas rikuperimit, për të mos pasur situata me një kopje rezervë të prishur. Dhe është më mirë ta bëni këtë me çdo arkiv të krijuar, por ku dhe si – varet vetëm nga fantazia juaj (mund të ngrini servera të veçantë me pagesë mujore ose të filloni kontrollin në CI). Por së paku – është thelbësore të kontrolloni të dhënat dhe indekset në bazë.
Për kontrollin e të dhënave është mjaft të kaloni ato përmes dump-it, por është më mirë që gjatë krijimit të bazës të keni aktivizuar kontrollet e shumave ():
#!/bin/bash
if ! su - postgres -c 'pg_dumpall > /dev/null'
then
echo 'pg_dumpall failed'
exit 125
fi
Për kontrollin e indekseve – ekziston , sql-kërkesa ndaj tij do ta marrim nga dhe rreth tij do të ndërtoshim një logjikë të vogël:
#!/bin/bash
# добавляем sql-запрос для проверки в файл во временной директории
cat > /tmp/amcheck.sql << EOF
CREATE EXTENSION IF NOT EXISTS amcheck;
SELECT bt_index_check(c.oid), c.relname, c.relpages
FROM pg_index i
JOIN pg_opclass op ON i.indclass[0] = op.oid
JOIN pg_am am ON op.opcmethod = am.oid
JOIN pg_class c ON i.indexrelid = c.oid
JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE am.amname = 'btree'
AND c.relpersistence != 't'
AND i.indisready AND i.indisvalid;
EOF
chown postgres: /tmp/amcheck.sql
# добавляем скрипт для запуска проверок всех доступных баз в кластере
# (обратите внимание что переменные и запуск команд – экранированы)
cat > /tmp/run_amcheck.sh << EOF
for DBNAME in $(su - postgres -c 'psql -q -A -t -c "SELECT datname FROM pg_database WHERE datistemplate = false;" ')
do
echo "Database: ${DBNAME}"
su - postgres -c "psql -f /tmp/amcheck.sql -v 'ON_ERROR_STOP=1' ${DBNAME}" && EXIT_STATUS=$? || EXIT_STATUS=$?
if [ "${EXIT_STATUS}" -ne 0 ]
then
echo "amcheck failed on DB: ${DBNAME}"
exit 125
fi
done
EOF
chmod +x /tmp/run_amcheck.sh
# запускаем скрипт
/tmp/run_amcheck.sh > /tmp/amcheck.log
# для проверки что всё прошло успешно можно проверить exit code или grep’нуть ошибку
if grep 'amcheck failed' "/tmp/amcheck.log"
then
echo 'amcheck failed: '
cat /tmp/amcheck.log
exit 125
fi
Përmbledhje
Shpreh mirënjohjen time për Andrey Borodin për ndihmën në përgatitjen e publikimit dhe një falenderim të veçantë për kontributin e tij në zhvillimin e WAL-G!
Me këtë, kjo shënim erdhi në fund. Shpresoj se kam arritur të transmetoj lehtësinë e konfigurimit dhe potencialin e madh për përdorimin e këtij instrumenti në kompaninë tuaj. Kam dëgjuar shumë për WAL-G, por nuk kam pasur kurrë kohë për të u ulur dhe për ta kuptuar. Pas implementimit të tij në sistemin tim – kjo artikull shpërtheu nga unë.
Veçanërisht, duhet të theksoj se WAL-G gjithashtu mund të funksionojë me sistemet e tjera DB si:
- ;
- ;
- ;
- Dhe sipas komiteteve – pritet edhe disa të tjera!
Burimi: habr.com
