WAL-G: PostgreSQL DBMSen babeskopiak eta berreskuratzea

Aspalditik ezagutzen da segurtasun kopiak egitea SQL iraulketetan (erabiltzen pg_dump edo pg_dumpall) ez da ideia ona. PostgreSQL DBMSren babeskopiak egiteko, hobe da komandoa erabiltzea pg_basebackup, WAL erregistroen kopia bitarra egiten duena. Baina kopia bat sortzeko eta leheneratzeko prozesu osoa aztertzen hasten zarenean, ulertuko duzu gutxienez pare bat triziklo idatzi behar dituzula honek funtziona dezan eta ez dizula minik sortu goian eta behean. Sufrimendua arintzeko, WAL-G garatu zen.

WAL-G Go-n idatzitako tresna da PostgreSQL datu-baseen babeskopia egiteko eta leheneratzeko (eta berriki MySQL/MariaDB, MongoDB eta FoundationDB). Amazon S3 biltegiratze-rekin lan egiten du (eta analogoekin, adibidez, Yandex Object Storage), baita Google Cloud Storage, Azure Storage, Swift Object Storage eta, besterik gabe, fitxategi-sistemarekin. Konfigurazio osoa urrats soiletan jaisten da, baina horri buruzko artikuluak Interneten zehar sakabanatuta daudenez, ez dago hasieratik amaierara pauso guztiak barne hartuko dituen eskuliburu osorik (Habré-n hainbat argitalpen daude, baina puntu asko falta dira hor).

WAL-G: PostgreSQL DBMSen babeskopiak eta berreskuratzea

Artikulu hau batez ere nire ezagutza sistematizatzeko idatzi zen. Ez naiz DBA bat eta nonbait laiko hizkuntzan adieraz dezaket, beraz, edozein zuzenketa ongi etorria da!

Bereizita, azpian dagoen guztia garrantzitsua dela eta Ubuntu 12.3-n PostgreSQL 18.04-rako probatua dela ohartzen naiz, komando guztiak erabiltzaile pribilegiatu gisa exekutatu behar direla.

Instalazio-

Artikulu hau idazteko momentuan, WAL-G-ren bertsio egonkorra da v0.2.15 (2020ko martxoa). Hau da erabiliko duguna (baina zuk zeuk eraiki nahi baduzu adar maisutik, orduan github biltegiak horretarako argibide guztiak ditu). Deskargatu eta instalatzeko, egin behar duzu:

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

Horren ondoren, WAL-G konfiguratu behar duzu lehenik, eta gero PostgreSQL bera.

WAL-G konfiguratzea

Babeskopia gordetzeko adibide baterako, Amazon S3 erabiliko da (nire zerbitzarietatik gertuago dagoelako eta bere erabilera oso merkea da). Berarekin lan egiteko, "s3 bucket" bat eta sarbide-gakoak behar dituzu.

WAL-G-ri buruzko aurreko artikulu guztiek ingurune-aldagaiak erabiliz konfigurazioa erabiltzen zuten, baina bertsio honekin ezarpenak bertan kokatu daitezke .walg.json fitxategia postgres erabiltzailearen hasierako direktorioan. Sortzeko, exekutatu bash script hau:

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

Utzidazu parametro guztiei buruz pixka bat azaltzen:

  • WALG_S3_PREFIX – babeskopiak igoko diren zure S3 ontzirako bidea (errora edo karpeta batera dezakezu);
  • AWS_ACCESS_KEY_ID - sarbide-gakoa S3-n (probako zerbitzari batean berreskuratzen bada, gako hauek Irakurtzeko Bakarrik Politika izan behar dute! Hau zehatzago deskribatzen da berreskuratzeari buruzko atalean.);
  • AWS_SECRET_ACCESS_KEY - gako sekretua S3 biltegian;
  • WALG_COMPRESSION_METHOD – konpresio metodoa, hobe da Brotli erabiltzea (azken tamainaren eta konpresio/deskonpresio abiaduraren arteko urrezko batezbestekoa baita);
  • WALG_DELTA_MAX_STEPS – “delta” kopurua babeskopia osoa sortu aurretik (denbora eta deskargatutako datuen tamaina aurrezten dute, baina berreskuratze prozesua apur bat moteldu dezakete, beraz, ez da komeni balio handiak erabiltzea);
  • PGDATA - zure datu-baseko datuekin direktoriorako bidea (komandoa exekutatuz jakin dezakezu pg_lsclusters);
  • PGHOST – datu-basera konektatuz, tokiko babeskopia batekin hobe da adibide honetan bezala unix-socket baten bidez egitea.

Beste parametro batzuk dokumentazioan aurki daitezke: https://github.com/wal-g/wal-g/blob/v0.2.15/PostgreSQL.md#configuration.

PostgreSQL konfiguratzea

Datu-basearen barneko artxibatzaileak WAL erregistroak hodeira igo eta haietatik berrezar ditzan (beharrezkoa bada), hainbat parametro ezarri behar dituzu konfigurazio fitxategian. /etc/postgresql/12/main/postgresql.conf. Hasteko besterik ez ziurtatu behar duzubeheko ezarpenetako bat ere ez dela beste baliorik ezarri, konfigurazioa berriro kargatzen denean DBMS ez dadin huts egin. Parametro hauek gehi ditzakezu:

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

Ezarri beharreko parametroen deskribapena:

  • wal_maila – zenbat informazio idatzi WAL erregistroetan, “erreplika” – idatzi dena;
  • artxibo_modua – gaitu WAL erregistroak deskargatzeko parametroko komandoa erabiliz artxibo_agindua;
  • artxibo_agindua – Osatutako WAL erregistroa artxibatzeko komandoa;
  • archive_timeout – Erregistroak artxibatzea amaitzen denean bakarrik egiten da, baina zure zerbitzariak datu-basean datu gutxi aldatzen baditu/gehitzen baditu, zentzuzkoa da hemen muga bat segundotan ezartzea, eta ondoren artxibatzeko komandoa indarrez deituko da (Datu-basean intentsiboki idazten dut segundoro, beraz, parametro hau ekoizpenean ez ezartzea erabaki nuen);
  • leheneratu_agindua – babeskopia batetik WAL erregistroa berrezartzeko komandoa erabiliko da “bakopia osoa” (oinarrizko babeskopia) datu-baseko azken aldaketak ez baditu.

Parametro horiei guztiei buruz gehiago irakur dezakezu dokumentazio ofizialaren itzulpenean: https://postgrespro.ru/docs/postgresql/12/runtime-config-wal.

Babeskopia-egutegia konfiguratzea

Zer esanik ez, exekutatzeko modurik erosoena cron da. Hau da konfiguratuko duguna babeskopiak sortzeko. Has gaitezen babeskopia osoa sortzeko komandoarekin: wal-g-n hau da abiaraztearen argumentua backup-push. Baina lehenik eta behin, hobe da komando hau eskuz exekutatu postgres erabiltzailearengandik dena ondo dagoela ziurtatzeko (eta sarbide akatsik ez dagoela):

#!/bin/bash

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

Abiarazte-argumentuek datu-direktoriorako bidea adierazten dute - exekutatzen baduzu aurki dezakezula gogorarazten dizut pg_lsclusters.

Dena akatsik gabe joan bada eta datuak S3 biltegian kargatu badira, orduan aldizkako abiarazte konfigura dezakezu crontab-en:

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

Adibide honetan, babeskopia-prozesua egunero hasten da goizeko 4:15etan.

Babeskopia zaharrak ezabatzea

Seguruenik, ez dituzu Mesozoiko garaiko babeskopi guztiak gorde beharrik, beraz, erabilgarria izango da zure biltegiratzea aldian-aldian "garbitzea" (bai "kopia osoak" bai WAL erregistroak). Hau guztia cron zeregin baten bidez egingo dugu:

#!/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-ek zeregin hau egunero exekutatzen du goizeko 6:30etan, dena ezabatuz (kopia osoa, deltak eta WALak) azken 10 egunetako kopiak izan ezik, baina gutxienez babeskopia bat utziz to zehaztutako data, beraz, edozein puntu ondoren datak PITRn sartu ziren.

Babeskopia batetik leheneratzen

Ez da sekretua datu-base osasuntsu baten gakoa aldizkako leheneratzea eta barruan dauden datuen osotasuna egiaztatzea dela. WAL-G erabiliz nola berreskuratu esango dizut atal honetan, eta kontrolei buruz hitz egingo dugu geroago.

Bereizi egin behar da proba-ingurune batean (ekoizpena ez den guztia) leheneratzeko S3-n Irakurtzeko Bakarrik kontu bat erabili behar duzula segurtasun-kopiak ustekabean gainidazteko. WAL-G-ren kasuan, S3 erabiltzaileari honako eskubide hauek ezarri behar dizkiozu Talde Politikan (Efektua: Baimendu): s3:GetObject, s3:ListBucket, s3:GetBucketLocation. Eta, noski, ez ahaztu ezartzea artxibo_modua=desaktibatuta ezarpenen fitxategian postgresql.conf, zure proba datu-basearen babeskopia isilean egin nahi ez dadin.

Zaharberritzea eskuaren mugimendu arin batekin egiten da PostgreSQL datu guztiak ezabatuz (erabiltzaileak barne), beraz, kontu handiz ibili hurrengo komandoak exekutatzen dituzunean.

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

Berreskuratze-prozesua egiaztatu nahi dutenentzat, bash magia zati txiki bat prestatu da behean, beraz, berreskurapenean arazoak izanez gero, script-a zero ez den irteera-kode batekin huts egingo du. Adibide honetan, 120 egiaztapen egiten dira 5 segundoko denbora-muga batekin (guztira 10 minutu berreskuratzeko) seinale-fitxategia ezabatu den jakiteko (berreskuratzea arrakastatsua izan dela esan nahi du):

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

Berreskuratu ondoren, ez ahaztu prozesu guztiak berriro abiarazteko (pgbouncer/monit, etab.).

Berreskuratu ondoren datuak egiaztatzea

Ezinbestekoa da zaharberritu ondoren datu-basearen osotasuna egiaztatzea, babeskopia hautsita/makurtuta dagoen egoerarik ez gertatzeko. Eta hobe da hori egitea sortutako artxibo bakoitzarekin, baina non eta nola zure irudimenaren araberakoa da soilik (zerbitzariak orduro igo ditzakezu edo CI-n egiaztapen bat egin dezakezu). Baina, gutxienez, beharrezkoa da datu-basean dauden datuak eta indizeak egiaztatzea.

Datuak egiaztatzeko, nahikoa da dump bidez exekutatu, baina hobe da datu-basea sortzerakoan checksumak gaituta izatea (datuen egiaztagiriak):

#!/bin/bash

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

Indizeak egiaztatzeko - badago amcheck modulua, har dezagun bertatik sql kontsulta WAL-G probak eta eraiki horren inguruan logika apur bat:

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

Laburbilduz

Nire esker ona adierazi nahi diot Andrey Borodini argitalpena prestatzeko emandako laguntzagatik eta eskerrak bereziak WAL-G-ren garapenean egindako ekarpenagatik!

Horrek amaitzen du ohar hau. Espero dut konfiguratzeko erraztasuna eta zure enpresan tresna hau erabiltzeko ahalmen handia transmititu izana. WAL-G-i buruz asko entzun nuen, baina ez nuen inoiz esertzeko eta asmatzeko astirik izan. Eta etxean ezarri ondoren, artikulu hau atera zitzaidan.

Bereizita, kontuan izan behar da WAL-G-k honako DBMS hauekin ere lan egin dezakeela:

Iturria: www.habr.com

Gehitu iruzkin berria