WAL-G: rugsteun en herstel van PostgreSQL DBMS

Dit is lank reeds bekend om te rugsteun na SQL-stortings (met bl_dump of pg_dumpall) is nie 'n goeie idee nie. Om PostgreSQL DBMS te rugsteun, is dit beter om die opdrag te gebruik pg_basisrugsteun, wat 'n binêre kopie van WAL-logs maak. Maar wanneer jy die hele rugsteun- en herstelproses begin leer, sal jy besef dat jy ten minste 'n paar driewiele moet skryf om dit te werk en nie jou pyn van bo en onder te veroorsaak nie. Om lyding te verlig, is WAL-G ontwikkel.

WAL-G is 'n instrument wat in Go geskryf is om PostgreSQL-databasisse te rugsteun en te herstel (en meer onlangs MySQL/MariaDB, MongoDB en FoundationDB). Dit ondersteun werk met Amazon S3-bergings (en analoë, byvoorbeeld, Yandex Object Storage), sowel as Google Cloud Storage, Azure Storage, Swift Object Storage en net met die lêerstelsel. Die hele opstelling kom neer op eenvoudige stappe, maar as gevolg van die feit dat artikels daaroor op die internet versprei is, is daar geen volledige handleiding wat al die stappe van en na sal insluit nie (daar is verskeie plasings op Habré, maar baie punte word daar gemis).

WAL-G: rugsteun en herstel van PostgreSQL DBMS

Hierdie artikel is hoofsaaklik geskryf om my kennis te sistematiseer. Ek is nie 'n DBA nie en ek kan iewers in leketaal praat, so enige regstellings is welkom!

Afsonderlik let ek daarop dat alles hieronder relevant en getoets is vir PostgreSQL 12.3 op Ubuntu 18.04, alle opdragte moet as 'n bevoorregte gebruiker uitgevoer word.

installasie

Ten tyde van hierdie skrywe is die stabiele weergawe van WAL-G v0.2.15 (Maart 2020). Ons sal dit gebruikmaar as jy dit self van die meestertak wil bou, dan het die github-bewaarplek al die instruksies hiervoor). Om af te laai en te installeer, moet jy hardloop:

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

Daarna moet jy eers WAL-G konfigureer, en dan PostgreSQL self.

WAL-G opstelling

Vir 'n voorbeeld van die berging van rugsteun, sal Amazon S3 gebruik word (want dit is nader aan my bedieners en dit is baie goedkoop om te gebruik). Om daarmee te werk, benodig jy 'n "s3-bucket" en toegangsleutels.

Alle vorige WAL-G-artikels het konfigurasie met omgewingsveranderlikes gebruik, maar vanaf hierdie vrystelling kan instellings in .walg.json-lêer in die tuisgids van die postgres-gebruiker. Om dit te skep, voer die volgende bash script uit:

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

Kom ek verduidelik 'n bietjie oor alles:

  • WALG_S3_PREFIX - die pad na jou S3-emmer waar rugsteun opgelaai sal word (jy kan óf na die wortel óf na die gids);
  • AWS_ACCESS_KEY_ID – toegang sleutel in S3 (in die geval van herstel op 'n toetsbediener - hierdie sleutels moet 'n Leesalleen-beleid hê! Dit word in meer besonderhede in die herstelafdeling bespreek.);
  • AWS_SECRET_ACCESS_KEY - geheime sleutel in S3-berging;
  • WALG_COMPRESSION_METHOD - kompressiemetode, dit is beter om Brotli te gebruik (aangesien dit die goue gemiddelde is tussen die finale grootte en die spoed van kompressie / dekompressie);
  • WALG_DELTA_MAX_STEPS - die aantal "deltas" voordat 'n volledige rugsteun geskep word (laat jou toe om tyd en die grootte van die afgelaaide data te bespaar, maar kan die herstelproses effens vertraag, dus is dit nie raadsaam om groot waardes te gebruik nie);
  • PGDATA - pad na die gids met jou databasis data (kan gevind word deur die opdrag uit te voer pg_lsclusters);
  • PGHOST - verbinding met die databasis, met 'n plaaslike rugsteun, dit is beter om dit deur unix-socket te doen, soos in hierdie voorbeeld.

Ander opsies kan in die dokumentasie gevind word: https://github.com/wal-g/wal-g/blob/v0.2.15/PostgreSQL.md#configuration.

Konfigureer PostgreSQL

Om die argiefhouer binne die databasis WAL-logboeke na die wolk op te laai en daarvan te herstel (indien nodig), moet u verskeie parameters in die konfigurasielêer stel /etc/postgresql/12/main/postgresql.conf. Net vir beginners jy moet seker maakdat geen van die instellings hieronder op enige ander waardes gestel is nie, sodat wanneer die konfigurasie herlaai word, die DBMS nie val nie. Jy kan hierdie opsies byvoeg met:

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

Beskrywing van die parameters wat ingestel moet word:

  • wal_vlak - hoeveel inligting om te skryf in WAL logs, "replica" - skryf alles;
  • argief_modus - aktiveer die laai van WAL-logboeke deur die opdrag van die parameter af te gebruik argief_opdrag;
  • argief_opdrag – 'n opdrag om die voltooide WAL-logboek te argiveer;
  • argief_tydverloop - argivering van logs word slegs uitgevoer wanneer dit voltooi is, maar as jou bediener min data by die databasis verander/byvoeg, dan maak dit sin om 'n limiet hier in sekondes te stel, waarna die argiveringsopdrag met geweld opgeroep sal word (Ek skryf elke sekonde intensief na die databasis, so ek het geweier om hierdie parameter in produksie te stel);
  • herstel_opdrag – die opdrag om die WAL-logboek vanaf 'n rugsteun te herstel sal gebruik word as die "volledige rugsteun" (basisrugsteun) nie die nuutste veranderinge in die databasis het nie.

U kan meer lees oor al hierdie parameters in die vertaling van die amptelike dokumentasie: https://postgrespro.ru/docs/postgresql/12/runtime-config-wal.

Stel 'n rugsteunskedule op

Hou daarvan of nie, maar die mees gerieflike manier om dit te laat loop is cron. Dit is wat ons sal konfigureer om rugsteun te skep. Kom ons begin met die opdrag om 'n volledige rugsteun te skep: in wal-g is dit die bekendstellingsargument rugsteun-stoot. Maar eers is dit beter om hierdie opdrag as 'n postgres-gebruiker handmatig uit te voer om seker te maak dat alles in orde is (en daar is geen toegangsfoute nie):

#!/bin/bash

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

Die bekendstellingsargumente bevat die pad na die datagids - ek herinner jou daaraan dat jy dit kan vind deur te hardloop pg_lsclusters.

As alles sonder foute verloop het en die data in die S3-berging gelaai is, kan u periodieke bekendstelling verder in crontab konfigureer:

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

In hierdie voorbeeld begin die rugsteunproses elke dag om 4:15 vm.

Vee ou rugsteun uit

Jy hoef waarskynlik nie absoluut alle rugsteun van die Mesozoïese era te hou nie, so dit is 'n goeie idee om jou berging van tyd tot tyd "skoon te maak" (beide "volle rugsteun" en WAL-logboeke). Ons sal dit alles ook doen deur 'n cron-taak:

#!/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 sal hierdie taak elke dag om 6:30 uitvoer en alles uitvee (volledige rugsteun, delta's en WAL's) behalwe vir die laaste 10 dae, maar ten minste een rugsteun laat aan gespesifiseerde datum na enige punt na datums het in PITR gekom.

Herstel tans vanaf 'n rugsteun

Dit is geen geheim dat die sleutel tot 'n gesonde databasis is om periodiek die integriteit van die data binne te herstel en na te gaan nie. Hoe om met WAL-G te herstel - ek sal jou in hierdie afdeling vertel, en ons sal later oor tjeks praat.

Dit is die moeite werd om afsonderlik op te let dat om op 'n toetsomgewing te herstel (alles wat nie produksie is nie) - moet jy 'n Leesalleen-rekening in S3 gebruik, om nie per ongeluk rugsteun te oorskryf nie. In die geval van WAL-G, moet jy die S3-gebruiker die volgende regte in Groepbeleid stel (Effek: Laat toe): s3:GetObject, s3: LysBucket, s3:GetBucketLocation. En, natuurlik, moenie vergeet om te plaas nie argief_modus=af in instellingslêer postgresql.confsodat jou toetsbasis nie in stilte wil rugsteun nie.

Herstel word gedoen met 'n effense beweging van die hand met verwyder alle PostgreSQL-data (gebruikers ingesluit), wees dus uiters versigtig wanneer jy die volgende opdragte uitvoer.

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

Vir diegene wat die herstelproses wil nagaan, is 'n klein stukkie bash-magie hieronder voorberei, sodat in die geval van probleme met herstel, die skrif sal ineenstort met 'n nie-nul uitgangkode. In hierdie voorbeeld word 120 kontroles gemaak met 'n tydsverloop van 5 sekondes (totaal 10 minute vir herstel) om uit te vind of die seinlêer uitgevee is (dit sal beteken dat die herstel suksesvol was):

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

Na 'n suksesvolle herstel, moenie vergeet om alle prosesse (pgbouncer / monit, ens.) te herbegin.

Dataverifikasie na herstel

Maak seker dat u die integriteit van die databasis na herstel nagaan, sodat daar geen situasie met 'n stukkende / krom rugsteun is nie. En dit is beter om dit met elke geskepte argief te doen, maar waar en hoe is volgens jou verbeelding (jy kan afsonderlike bedieners op 'n uurlikse basis verhoog of 'n tjek in CI uitvoer). Maar ten minste is dit nodig om die data en indekse in die databasis na te gaan.

Om die data na te gaan, is dit genoeg om dit deur 'n stortingsterrein te laat loop, maar dit is beter dat u kontrolesomme geaktiveer het wanneer u die databasis skep (data kontrolesomme):

#!/bin/bash

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

Om indekse na te gaan - bestaan amcheck module, sql-navraag daaruit sal ons neem WAL-G toetse en bou 'n bietjie logika rondom:

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

Op te som

Ek spreek my dank uit teenoor Andrey Borodin vir sy hulp met die voorbereiding van die publikasie en spesiale dank vir sy bydrae tot die ontwikkeling van WAL-G!

Dit sluit hierdie nota af. Ek hoop dat ek die gemak van aanpassing en die groot potensiaal vir die gebruik van hierdie hulpmiddel in u onderneming kon oordra. Ek het baie van WAL-G gehoor, maar daar was nie tyd om te gaan sit en dit uit te vind nie. En nadat ek dit by die huis geïmplementeer het, het hierdie artikel uit my gekom.

Afsonderlik is dit opmerklik dat WAL-G ook met die volgende DBBS kan werk:

Bron: will.com

Voeg 'n opmerking