WAL-G: PostgreSQL andmebaasi varukoopiad ja taastamine

On juba ammu teada, et SQL-dumpide varundamine (kasutades pg_dump või pg_dumpall) ei ole kõige parem idee. PostgreSQL andmebaasi varundamiseks on parem kasutada käsku pg_basebackup, mis loob WAL-logide binaarse koopia. Kuid kui hakkate uurima kogu kopeerimise ja taastamise protsessi, siis saate aru, et peate kirjutama vähemalt paar kolme ratast, et kõik see töötaks ja ei tekitaks teile valu nii pealt kui ka alt. Valu leevendamiseks on loodud WAL-G.

WAL-G on Go-s kirjutatud tööriist PostgreSQL andmebaaside varundamiseks ja taastamiseks (ja viimasel ajal ka MySQL/MariaDB, MongoDB ja FoundationDB). See toetab töötamist Amazon S3 (ja analoogide, nagu Yandex Object Storage), samuti Google Cloud Storage, Azure Storage, Swift Object Storage ja lihtsalt failisüsteemiga. Kogu seadistamine seisneb lihtsates sammudes, kuid kuna artiklid selle kohta on internetis killustatud – ei ole täis how-to manuaali, mis hõlmaks kõiki samme algusest lõpuni (Habr'is on mitu postitust, kuid seal on palju aspekte puudutatud).

WAL-G: PostgreSQL andmebaasi varukoopiad ja taastamine

See artikkel on kirjutatud peamiselt selleks, et süsteemida oma teadmisi. Ma ei ole DBA ja mõnes kohas võin ennast väljendada tavakasutaja-arendaja keeles, seega on igasugused parandused teretulnud!

Eraldi mainin, et kõik allpooltoodud on актуально ja kontrollitud PostgreSQL 12.3 jaoks Ubuntu 18.04-l, kõik käsud peaksid olema täidetud privileegitud kasutaja poolt.

Paigaldamine

Selle artikli kirjutamise hetkel on WAL-G stabiilne versioon – v0.2.15 (märts 2020). Seda me kasutame (aga kui soovite seda ise master-haru järgi koguda, siis on githubi hoidlates kõik juhised selleks). Allalaadimise ja installimise jaoks tuleb teha:

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

Pärast seda tuleb kõigepealt konfigureerida WAL-G ja seejärel PostgreSQL.

WAL-G seadistamine

Näiteks varundamise jaoks kasutatakse Amazon S3 (sest see on minu serverite lähedal ja selle kasutamine on väga odav). Selle jaoks on vajalik 's3-bucket' ja juurdepäsuvõtmed.

Kõikides eelnevatest WAL-G artiklitest on kasutatud seadistust keskkonnamuutujate abil, kuid sellest versioonist alates saab seadeid paigutada .walg.json faili postgrese kasutaja kodudirektorisse. Selle loomiseks täidame järgmise bash-skripti:

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

Selgitan natuke kõigi parameetrite kohta:

  • WALG_S3_PREFIX – tee oma S3-ämbrisse, kuhu varukoopiad laaditakse (võib olla nii juurus kui ka kaustas);
  • AWS_ACCESS_KEY_ID – juurdepääsuvõti S3 (taasterakendamisel testserveris peavad need võtmed olema ReadOnly Policy! Sellest on lähemalt juttu taastamise jaotises);
  • AWS_SECRET_ACCESS_KEY – salajane võti S3-s;
  • WALG_COMPRESSION_METHOD – tihendamismeetod, parem on kasutada Brotli (sest see on kuldne kesktee lõppmahu ja tihendamis-/dekompressioonikiirusel);
  • WALG_DELTA_MAX_STEPS – «delta»de arv enne täieliku varukoopia loomist (aitavad säästa aega ja laaditavate andmete mahtu, kuid võivad veidi aeglustada taastamisprotsessi, seega on soovitatav mitte kasutada suuri väärtusi);
  • PGDATA – tee kaustasse, kus teie andmed asuvad (saate teada, käivitades käsu pg_lsclusters);
  • PGHOST – ühendus andmebaasi, kohaliku varukoopia korral on parem kasutada unix-soket, nagu antud näites.

Ülejäänud parameetreid saate vaadata dokumentatsioonist: https://github.com/wal-g/wal-g/blob/v0.2.15/PostgreSQL.md#configuration.

PostgreSQL seadistamine

Et arhiivija andmebaasis saaks iseseisvalt laadida WAL-logisid pilve ja taastuda neist (vajadusel) – tuleb konfiguratsioonifailis seada mitu parameetrit /etc/postgresql/12/main/postgresql.conf. Kuid enne seda peate veenduma, et allpool toodud seadeid ei ole määratud mingitesse teistesse väärtustesse, et konfiguratsiooni taaskäivitamisel – DBMS ei kukuks. Need parameetrid saab lisada järgmist moodi:

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

Seadistatud parameetrite kirjeldus:

  • wal_level – kui palju teavet kirjutada WAL-logidesse, "replica" – kirjutada kõik;
  • archive_mode – WAL-logide laadimise lubamine, kasutades parameetrist määratud käsku archive_command;
  • archive_command – käsk, et arhiveerida lõpetatud WAL-logi;
  • archive_timeout – logide arhiveerimine toimub ainult siis, kui see on lõpetatud, kuid kui teie server muudab/lisab andmeid andmebaasis harva, siis on mõistlik seada siin sekundite limit, mille möödumisel käsk arhiveerimisele sunnitakse (mul on intensive kirjutamine andmebaasi iga sekundi tagant, seega loobusin selle parameetri seadmisest tootmises);
  • restore_command – WAL-logi taastamise käsk varukoopiast, seda kasutatakse juhul, kui "täielik varukoopia" (base backup) ei kata viimaseid muudatusi andmebaasis.

Täiendavat teavet kõigi nende parameetrite kohta saab lugeda ametliku dokumentatsiooni tõlkes: https://postgrespro.ru/docs/postgresql/12/runtime-config-wal.

Varukoopiate ajakava seadistamine

Kuidas iganes seda vaadata, on kõige mugavam viis käivitamiseks cron. Just seda seadistame varukoopiate loomise jaoks. Alustame täieliku varukoopia loomisest: wal-g-s on see käivituse argument. backup-push. Kuid enne on parem see käsk manuaalselt postgres kasutajalt täita, et veenduda, et kõik on hästi (ja pole mingeid ligipääsu vigu):

#!/bin/bash

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

Käivituse argumentides on näidatud tee andmete katalooge, tuletan meelde, et selle saab teada, kui täita: pg_lsclusters.

Kui kõik läks veatult ja andmed laaditi S3 salvesse, siis on järgmine samm seadistada regulaarne käivitamine crontabis:

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

Antud näites käivitub varukoopia protsess iga päev kell 4:15 hommikul.

Vana varukoopia eemaldamine

Tõenäoliselt ei ole teil vaja hoida kõiki varukoopiaid, seega on kasulik regulaarselt oma salvestust ‘puhastada’ (nii ‘täielikud varukoopiad’ kui ka WAL-logid). Teeme seda samuti cron ülesande kaudu:

#!/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 täidab seda ülesannet iga päev kell 6:30 hommikul, eemaldades kõik (täielikud varukoopiad, delta ja WAL-id) peale need, mis on viimase 10 päeva jooksul tehtud, kuid hoiab vähemalt ühte varukoopiat määratud kuupäeval, et igasugune kuupäev kuni kuuluks PITR-i. pärast Kellelegi ei ole saladus, et tervisliku andmebaasi alus on regulaarne taastamine ja andmete terviklikkuse kontroll. Kuidas taastuda WAL-G abil – räägin sellest ja kontrollidest räägime hiljem.

Varukoopiast taastamine

Eraldi tasub märkida

et taastamiseks testkeskkonnas (kõik, mis ei ole tootmine) – tuleb kasutada S3-l lugemisõigustega kontot, et juhuslikult varukoopiaid mitte üle kirjutada. WAL-G puhul tuleb S3 kasutajale määrata järgmised õigused Group Policy-s ( Effect: Allows3:GetObject): s3:ListBucket, s3:GetBucketLocation, . Ja muidugi, eelnevalt ei tohi unustada seadaarchive_mode=off seadete failis , et teie testandmebaas ei sooviks vaikselt varukoopiaid teha. postgresql.confTaastamine toimub lihtsalt ühe käe liigutusega

kõikide PostgreSQL andmete (sealhulgas kasutajate) eemaldamisega, seega palun olge äärmiselt ettevaatlik, kui käivitate järgmised käsud. (sh,包括用户),因此请在执行以下命令时务必小心。

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

Kelle, kes soovivad taastamisprotsessi kontrollida — allpool on toodud väike bash-maagia, et probleemide korral taastamisel kukuks skript välja mitte nullilise väljumiskoodiga. Antud näites tehakse 120 kontrolli viie sekundi intervallidega (kokku 10 minutit taastamiseks), et teada saada, kas signaalifail on kustutatud (see tähendaks, et taastamine on eduka läbinud):

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

Pärast eduka taastamise lõpetamist ärge unustage taaskäivitada kõiki protsesse (pgbouncer/monit jne).

Andmete kontrollimine pärast taastamist

On hädavajalik kontrollida andmebaasi terviklikkust pärast taastamist, et vältida olukorda defekti/segase varukoopiaga. Ja parem on seda teha iga loodud arhiivi puhul, kuid kust ja kuidas - see sõltub ainult teie loomingulisusest (võite tõsta eraldi servereid tunni hinnaga või käivitada kontrolli CI-s). Kuid vähemalt - on vajalik andmeid ja indekseid andmebaasis kontrollida.

Andmete kontrollimiseks piisab neist dumpi kaudu läbiviimisest, kuid parem on, kui andmebaasi loomisel oleksid kontrollsummad aktiivsed (data checksums):

#!/bin/bash

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

Indeksite kontrollimiseks - olemas moodul amcheck, sql-päring selle jaoks võtame WAL-G testidest ja ehitame ümber väikese loogika:

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

Kokkuvõtteks

Täname Andrei Borodini abi eest publitseerimise ettevalmistamisel ja eraldi tänu tema panuse eest WAL-G arendusse!

Käesolev märkme on lõppemas. Loodan, et suutsin edastada seadistamise kerguse ja tohutu potentsiaali selle tööriista kasutamiseks teie ettevõttes. Olen kuulnud palju WAL-G-st, kuid ei olnud kunagi aega sellega tegeleda. Pärast selle enda juures rakendamist sai minust see artikkel.

Eraldi tasub märkida, et WAL-G võib töötada ka järgmiste andmebaasihaldussüsteemidega:

Allikas: habr.com

Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster