WAL-G: sovgad ak rekiperasyon PostgreSQL DBMS

Li te konnen depi lontan fè sovgad nan pil fatra SQL (itilize pg_dump oswa pg_dumpall) se pa yon bon lide. Pou fè backup DBMS PostgreSQL, li pi bon pou itilize lòd la pg_basebackup, ki fè yon kopi binè mòso bwa WAL. Men, lè ou kòmanse etidye pwosesis la tout antye de kreye yon kopi ak restorasyon, ou pral konprann ke ou bezwen ekri omwen yon koup nan tricycles pou sa a travay epi yo pa lakòz ou doulè tou de pi wo a ak anba a. Pou soulaje soufrans, WAL-G te devlope.

WAL-G se yon zouti ki ekri nan Go pou fè bak ak restore baz done PostgreSQL (ak pi resamman MySQL/MariaDB, MongoDB ak FoundationDB). Li sipòte travay ak depo Amazon S3 (ak analogue, pou egzanp, Yandex Object Storage), osi byen ke Google Cloud Storage, Azure Storage, Swift Object Storage ak tou senpleman ak sistèm nan dosye. Tout konfigirasyon an desann nan etap senp, men akòz lefèt ke atik sou li yo gaye sou Entènèt la, pa gen okenn manyèl konplè sou fason pou yo ki ta gen ladan tout etap yo soti nan kòmansman jiska fini (gen plizyè posts sou Habré, men anpil pwen yo rate la).

WAL-G: sovgad ak rekiperasyon PostgreSQL DBMS

Atik sa a te ekri premyèman pou sistematize konesans mwen. Mwen pa yon DBA epi mwen ka eksprime tèt mwen nan lang pwofàn yon kote, kidonk nenpòt koreksyon yo akeyi!

Separeman, mwen sonje ke tout bagay ki anba a enpòtan epi teste pou PostgreSQL 12.3 sou Ubuntu 18.04, tout kòmandman yo dwe egzekite kòm yon itilizatè privilejye.

Enstalasyon

Nan moman w ap ekri atik sa a, vèsyon ki estab nan WAL-G se v0.2.15 (mas 2020). Sa a se sa nou pral itilize (men si ou vle bati li tèt ou soti nan branch mèt la, Lè sa a, repozitwa a github gen tout enstriksyon yo pou sa a.). Pou telechaje ak enstale ou bezwen fè:

#!/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/

Apre sa, ou bezwen konfigirasyon WAL-G an premye, ak Lè sa a, PostgreSQL tèt li.

Mete kanpe WAL-G

Pou yon egzanp estoke sovgad, yo pral itilize Amazon S3 (paske li pi pre serveurs mwen yo ak itilizasyon li yo trè bon mache). Pou travay avèk li, ou bezwen yon "s3 bokit" ak kle aksè.

Tout atik anvan yo sou WAL-G te itilize konfigirasyon lè l sèvi avèk varyab anviwònman, men ak lage sa a anviwònman yo ka lokalize nan .walg.json dosye nan anyè lakay itilizatè postgres la. Pou kreye li, kouri script bash sa a:

#!/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

Kite m 'eksplike yon ti kras sou tout paramèt yo:

  • WALG_S3_PREFIX – chemen ki mennen nan bokit S3 ou a kote sovgad yo pral telechaje (ou ka swa nan rasin lan oswa nan yon katab);
  • AWS_ACCESS_KEY_ID - kle aksè nan S3 (an ka rekiperasyon sou yon sèvè tès, kle sa yo dwe gen Règleman ReadOnly! Sa a se dekri an plis detay nan seksyon an sou rekiperasyon an.);
  • AWS_SECRET_ACCESS_KEY - kle sekrè nan depo S3;
  • WALG_COMPRESSION_METHOD - metòd konpresyon, li se pi bon yo sèvi ak Brotli (depi sa a se vle di an lò ant gwosè final la ak vitès konpresyon / dekonpresyon);
  • WALG_DELTA_MAX_STEPS - kantite "deltas" anvan yo kreye yon backup konplè (yo ekonomize tan ak gwosè a nan done telechaje, men yo ka yon ti kras ralanti pwosesis rekiperasyon an, kidonk li pa rekòmande yo sèvi ak gwo valè);
  • PGDATA - chemen anyè a ak done baz done ou a (ou ka jwenn deyò nan kouri lòd la pg_lsclusters);
  • PGHOST – konekte ak baz done a, ak yon backup lokal li se pi bon fè li atravè yon priz Unix tankou nan egzanp sa a.

Lòt paramèt ka jwenn nan dokiman an: https://github.com/wal-g/wal-g/blob/v0.2.15/PostgreSQL.md#configuration.

Mete kanpe PostgreSQL

Nan lòd pou achiv la andedan baz done a telechaje WAL mòso bwa nan nwaj la epi restore yo nan men yo (si sa nesesè), ou bezwen mete plizyè paramèt nan dosye a konfigirasyon. /etc/postgresql/12/main/postgresql.conf. Jis pou kòmanse ou bezwen asire wke okenn nan paramèt ki anba yo pa mete nan nenpòt lòt valè, pou ke lè konfigirasyon an rechaje, DBMS a pa aksidan. Ou ka ajoute paramèt sa yo lè l sèvi avèk:

#!/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

Deskripsyon paramèt yo dwe mete:

  • wal_level – konbyen enfòmasyon yo ekri nan mòso bwa WAL, “replica” – ekri tout bagay;
  • archive_mode – pèmèt telechaje WAL mòso bwa lè l sèvi avèk kòmandman ki soti nan paramèt la achiv_kòmand;
  • achiv_kòmand – lòd pou achiv yon jounal WAL ranpli;
  • archive_timeout – achiv nan mòso bwa fèt sèlman lè li fin ranpli, men si sèvè ou a chanje/ajoute ti done nan baz done a, Lè sa a, li fè sans yo mete yon limit isit la nan segonn, apre sa yo pral rele lòd la achiv la fòs (Mwen ekri entansif nan baz done a chak segonn, kidonk mwen deside pa mete paramèt sa a nan pwodiksyon an);
  • restore_command – Yo pral itilize kòmandman pou retabli boutèy demi lit WAL la nan yon sovgad si "sovgad konplè" (sovgad baz) pa gen dènye chanjman ki fèt nan baz done a.

Ou ka li plis sou tout paramèt sa yo nan tradiksyon dokiman ofisyèl la: https://postgrespro.ru/docs/postgresql/12/runtime-config-wal.

Mete kanpe yon orè backup

Kèlkeswa sa yon moun ka di, fason ki pi pratik pou kouri li se cron. Sa a se sa nou pral configured yo kreye sovgad. Ann kòmanse ak lòd pou kreye yon backup konplè: nan wal-g sa a se agiman lansman an backup-pouse. Men, anvan, li pi bon pou kouri kòmandman sa a manyèlman soti nan itilizatè postgres la pou asire w ke tout bagay anfòm (e pa gen okenn erè aksè):

#!/bin/bash

su - postgres -c '/usr/local/bin/wal-g backup-push /var/lib/postgresql/12/main'

Agiman yo lansman endike chemen an nan anyè done a - mwen raple ou ke ou ka jwenn li soti nan kouri pg_lsclusters.

Si tout bagay te ale san erè epi done yo te chaje nan depo S3, Lè sa a, ou ka konfigirasyon lansman peryodik nan 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

Nan egzanp sa a, pwosesis backup la kòmanse chak jou a 4:15 am.

Efase ansyen sovgad

Gen plis chans, ou pa bezwen kenbe absoliman tout sovgad ki soti nan epòk Mezozoik la, kidonk li pral itil detanzantan "netwaye" depo ou (tou de "sovgad konplè" ak mòso bwa WAL). Nou pral fè sa tout atravè yon travay 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 pral kouri travay sa a chak jou a 6:30 am, efase tout bagay (sovgad konplè, delta ak WALs) eksepte kopi pou 10 dènye jou yo, men kite omwen yon backup. до dat espesifye pou nenpòt ki pwen apre dat yo te enkli nan PITR.

Restore soti nan yon backup

Se pa sekrè ki kle nan yon baz done ki an sante se restorasyon peryodik ak verifikasyon nan entegrite nan done yo andedan. Mwen pral di w ki jan yo refè lè l sèvi avèk WAL-G nan seksyon sa a, epi nou pral pale sou chèk pita.

Li se vo anyen separeman ke retabli nan yon anviwònman tès (tout bagay ki pa pwodiksyon) ou bezwen sèvi ak yon kont li sèlman nan S3 pou yo pa aksidantèlman ranplase sovgad. Nan ka WAL-G, ou bezwen mete dwa sa yo pou itilizatè S3 a nan Règleman Gwoup (Efè: Pèmèt): s3:GetObject, s3:ListBucket, s3:GetBucketLocation. Epi, nan kou, pa bliye mete archive_mode = koupe nan dosye paramèt la postgresql.conf, pou baz done tès ou a pa vle fè bak an silans.

Se restorasyon te pote soti ak yon ti mouvman nan men an efase tout done PostgreSQL (ki gen ladan itilizatè yo), kidonk tanpri fè anpil atansyon lè w ap kouri kòmandman sa yo.

#!/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

Pou moun ki vle tcheke pwosesis rekiperasyon an, yo te prepare yon ti moso nan majik bash anba a, se konsa ke nan ka ta gen pwoblèm nan rekiperasyon, script la pral aksidan ak yon kòd sòti ki pa zewo. Nan egzanp sa a, yo fè 120 chèk ak yon delè 5 segonn (yon total 10 minit pou rekiperasyon) pou chèche konnen si yo te efase dosye siyal la (sa a pral vle di ke rekiperasyon an te reyisi):

#!/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

Apre rekiperasyon siksè, pa bliye kòmanse tout pwosesis (pgbouncer/monit, elatriye) tounen.

Tcheke done apre rekiperasyon an

Li se enperatif tcheke entegrite nan baz done a apre restorasyon, pou ke yon sitiyasyon ak yon backup kase / kwochi pa leve. Epi li pi bon fè sa ak chak achiv kreye, men ki kote ak ki jan depann sèlman sou imajinasyon ou (ou ka ogmante sèvè endividyèl sou yon baz èdtan oswa kouri yon chèk nan CI). Men, nan yon minimòm, li nesesè yo tcheke done yo ak endèks nan baz done a.

Pou tcheke done yo, li ase yo kouri li nan yon pil fatra, men li pi bon ke lè w ap kreye baz done a ou gen chèk sòm aktive (sòm chèk done yo):

#!/bin/bash

if ! su - postgres -c 'pg_dumpall > /dev/null'
then
    echo 'pg_dumpall failed'
    exit 125
fi

Pou tcheke endèks - egziste amcheck modil, se pou nou pran rechèch la sql pou li soti nan Tès WAL-G epi bati yon ti lojik alantou li:

#!/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

Rezime

Mwen ta renmen eksprime rekonesans mwen anvè Andrey Borodin pou èd li nan prepare piblikasyon an ak mèsi espesyal pou kontribisyon li nan devlopman WAL-G!

Sa a fini nòt sa a. Mwen espere ke mwen te kapab transmèt fasilite nan konfigirasyon ak gwo potansyèl pou itilize zouti sa a nan konpayi ou. Mwen tande anpil bagay sou WAL-G, men mwen pa janm gen ase tan pou m chita epi kalkile li. Apre sa, apre mwen aplike li nan kay la, atik sa a soti nan mwen.

Separeman, li vo anyen ke WAL-G ka travay tou ak DBMS sa yo:

Sous: www.habr.com

Add nouvo kòmantè