WAL-G: chelezo na urejeshaji wa PostgreSQL DBMS

Imejulikana kwa muda mrefu kuwa kutengeneza nakala rudufu kwenye utupaji wa SQL (kwa kutumia pg_dampo au pg_dumpall) sio wazo zuri. Ili kuhifadhi nakala ya DBMS ya PostgreSQL, ni bora kutumia amri pg_basebackup, ambayo hufanya nakala ya binary ya magogo ya WAL. Lakini unapoanza kusoma mchakato mzima wa kuunda nakala na kurejesha, utaelewa kuwa unahitaji kuandika angalau tricycles kadhaa kwa hili kufanya kazi na sio kusababisha maumivu juu na chini. Ili kupunguza mateso, WAL-G ilitengenezwa.

WAL-G ni zana iliyoandikwa katika Go kwa kucheleza na kurejesha hifadhidata za PostgreSQL (na hivi majuzi zaidi MySQL/MariaDB, MongoDB na FoundationDB) Inasaidia kufanya kazi na hifadhi ya Amazon S3 (na analogues, kwa mfano, Hifadhi ya Kitu cha Yandex), pamoja na Hifadhi ya Wingu ya Google, Hifadhi ya Azure, Hifadhi ya Kitu cha Swift na kwa urahisi na mfumo wa faili. Usanidi wote unakuja kwa hatua rahisi, lakini kwa sababu ya ukweli kwamba nakala kuihusu zimetawanyika kote kwenye Mtandao, hakuna mwongozo kamili wa jinsi ya kujumuisha hatua zote kutoka mwanzo hadi mwisho (kuna machapisho kadhaa kwenye Habre, lakini pointi nyingi zimekosekana hapo).

WAL-G: chelezo na urejeshaji wa PostgreSQL DBMS

Nakala hii iliandikwa kimsingi ili kupanga maarifa yangu. Mimi si DBA na ninaweza kujieleza katika lugha ya watu wa kawaida mahali fulani, kwa hivyo masahihisho yoyote yanakaribishwa!

Kando, ninaona kuwa kila kitu hapa chini kinafaa na kimejaribiwa kwa PostgreSQL 12.3 kwenye Ubuntu 18.04, amri zote lazima zitekelezwe kama mtumiaji aliyebahatika.

Ufungaji

Wakati wa kuandika nakala hii, toleo thabiti la WAL-G ni v0.2.15 (Machi 2020). Hii ndio tutatumia (lakini ikiwa unataka kuijenga mwenyewe kutoka kwa tawi kuu, basi hazina ya github ina maagizo yote ya hii.) Ili kupakua na kusakinisha unahitaji kufanya:

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

Baada ya hayo, unahitaji kusanidi WAL-G kwanza, na kisha PostgreSQL yenyewe.

Kuanzisha WAL-G

Kwa mfano wa kuhifadhi chelezo, Amazon S3 itatumika (kwa sababu iko karibu na seva zangu na matumizi yake ni nafuu sana) Ili kufanya kazi nayo, unahitaji "ndoo ya s3" na funguo za kufikia.

Nakala zote za awali kuhusu WAL-G zilitumia usanidi kwa kutumia vigeu vya mazingira, lakini kwa toleo hili mipangilio inaweza kupatikana. .walg.json faili kwenye saraka ya nyumbani ya mtumiaji wa postgres. Ili kuiunda, endesha hati ifuatayo ya bash:

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

Acha nieleze kidogo juu ya vigezo vyote:

  • WALG_S3_PREFIX - njia ya ndoo yako ya S3 ambapo chelezo zitapakiwa (unaweza kwenye mzizi au folda);
  • AWS_ACCESS_KEY_ID - ufunguo wa ufikiaji katika S3 (katika hali ya urejeshaji kwenye seva ya majaribio, funguo hizi lazima ziwe na Sera ya KusomaTu! Hii inaelezwa kwa undani zaidi katika sehemu ya kurejesha.);
  • AWS_SECRET_ACCESS_KEY - ufunguo wa siri katika uhifadhi wa S3;
  • WALG_COMPRESSION_METHOD - njia ya kukandamiza, ni bora kutumia Brotli (kwa kuwa hii ndiyo maana ya dhahabu kati ya ukubwa wa mwisho na kasi ya compression / decompression);
  • WALG_DELTA_MAX_STEPS - idadi ya "deltas" kabla ya kuunda salama kamili (zinahifadhi muda na ukubwa wa data iliyopakuliwa, lakini inaweza kupunguza kidogo mchakato wa kurejesha, kwa hiyo haifai kutumia maadili makubwa);
  • PGDATA - njia ya saraka na data yako ya hifadhidata (unaweza kujua kwa kuendesha amri pg_lsclusters);
  • PHOST - kuunganisha kwenye hifadhidata, na chelezo ya ndani ni bora kuifanya kupitia tundu la unix kama katika mfano huu.

Vigezo vingine vinaweza kupatikana katika nyaraka: https://github.com/wal-g/wal-g/blob/v0.2.15/PostgreSQL.md#configuration.

Kuanzisha PostgreSQL

Ili jalada ndani ya hifadhidata kupakia kumbukumbu za WAL kwenye wingu na kuzirejesha kutoka kwao (ikiwa ni lazima), unahitaji kuweka vigezo kadhaa kwenye faili ya usanidi. /etc/postgresql/12/main/postgresql.conf. Kwa wanaoanza tu unahitaji kuhakikishakwamba hakuna mipangilio yoyote iliyo hapa chini iliyowekwa kwa maadili mengine yoyote, ili usanidi unapopakiwa upya, DBMS haivunji. Unaweza kuongeza vigezo hivi kwa kutumia:

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

Maelezo ya vigezo vya kuweka:

  • ngazi_ya_ukuta - ni habari ngapi ya kuandika katika kumbukumbu za WAL, "replica" - andika kila kitu;
  • archive_mode - Wezesha upakuaji wa magogo ya WAL kwa kutumia amri kutoka kwa kigezo archive_amri;
  • archive_amri - amri ya kuhifadhi kumbukumbu ya WAL iliyokamilishwa;
  • archive_timeout - uhifadhi wa kumbukumbu unafanywa tu wakati umekamilika, lakini ikiwa seva yako itabadilika / inaongeza data kidogo kwenye hifadhidata, basi ni busara kuweka kikomo hapa kwa sekunde, baada ya hapo amri ya kumbukumbu itaitwa kwa nguvu (Ninaandika kwa bidii kwa hifadhidata kila sekunde, kwa hivyo niliamua kutoweka paramu hii katika uzalishaji);
  • rudisha_amri - amri ya kurejesha kumbukumbu ya WAL kutoka kwa chelezo itatumika ikiwa "chelezo kamili" (chelezo ya msingi) haina mabadiliko ya hivi karibuni kwenye hifadhidata.

Unaweza kusoma zaidi juu ya vigezo hivi vyote katika tafsiri ya hati rasmi: https://postgrespro.ru/docs/postgresql/12/runtime-config-wal.

Kuweka ratiba ya chelezo

Chochote mtu anaweza kusema, njia rahisi zaidi ya kuiendesha ni cron. Hii ndio tutakayosanidi kuunda nakala rudufu. Wacha tuanze na amri ya kuunda nakala kamili: katika wal-g hii ndio hoja ya uzinduzi chelezo-kushinikiza. Lakini kwanza, ni bora kutekeleza amri hii kwa mikono kutoka kwa mtumiaji wa posta ili kuhakikisha kuwa kila kitu kiko sawa (na hakuna makosa ya ufikiaji):

#!/bin/bash

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

Hoja za uzinduzi zinaonyesha njia ya saraka ya data - nakukumbusha kuwa unaweza kuipata kwa kukimbia pg_lsclusters.

Ikiwa kila kitu kilienda bila makosa na data ilipakiwa kwenye hifadhi ya S3, basi unaweza kusanidi uzinduzi wa mara kwa mara katika 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

Katika mfano huu, mchakato wa kuhifadhi nakala huanza kila siku saa 4:15 asubuhi.

Inafuta chelezo za zamani

Uwezekano mkubwa zaidi, hauitaji kuweka nakala zote za enzi ya Mesozoic, kwa hivyo itakuwa muhimu mara kwa mara "kusafisha" uhifadhi wako ("hifadhi kamili" na kumbukumbu za WAL). Tutafanya haya yote kupitia kazi ya 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 atafanya kazi hii kila siku saa 6:30 asubuhi, akifuta kila kitu (chelezo kamili, deltas na WALs) isipokuwa nakala kwa siku 10 zilizopita, lakini akiacha angalau nakala moja. kwa tarehe maalum ili hatua yoyote baada ya tarehe zilijumuishwa katika PITR.

Inarejesha kutoka kwa chelezo

Sio siri kuwa ufunguo wa hifadhidata yenye afya ni urejeshaji wa mara kwa mara na uthibitishaji wa uadilifu wa data iliyo ndani. Nitakuambia jinsi ya kurejesha kwa kutumia WAL-G katika sehemu hii, na tutazungumzia kuhusu hundi baadaye.

Kwa tofauti, inafaa kuzingatia kwamba ili kurejesha katika mazingira ya majaribio (kila kitu ambacho si cha uzalishaji) unahitaji kutumia akaunti ya Kusoma Pekee katika S3 ili usibadilishe nakala rudufu kwa bahati mbaya. Kwa upande wa WAL-G, unahitaji kuweka haki zifuatazo kwa mtumiaji wa S3 katika Sera ya Kikundi (Athari: Ruhusu): s3:PataObject, s3:ListBucket, s3:GetBucketLocation. Na, bila shaka, usisahau kuweka archive_mode=off katika faili ya mipangilio postgresql.conf, ili hifadhidata yako ya majaribio haitaki kuchelezwa kimya kimya.

Urejesho unafanywa kwa harakati kidogo ya mkono kufuta data zote za PostgreSQL (pamoja na watumiaji), kwa hivyo tafadhali kuwa mwangalifu sana unapoendesha amri zifuatazo.

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

Kwa wale ambao wanataka kuangalia mchakato wa kurejesha, kipande kidogo cha uchawi wa bash kimeandaliwa hapa chini, ili katika kesi ya matatizo katika kurejesha, script itaanguka na msimbo wa kuondoka usio na sifuri. Katika mfano huu, ukaguzi 120 hufanywa na kuisha kwa sekunde 5 (jumla ya dakika 10 za urejeshaji) ili kujua ikiwa faili ya ishara ilifutwa (hii itamaanisha kuwa urejeshaji ulifanikiwa):

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

Baada ya kupona kwa mafanikio, usisahau kuanza michakato yote nyuma (pgbouncer/monit, nk).

Kuangalia data baada ya kupona

Ni muhimu kuangalia uadilifu wa hifadhidata baada ya urejeshaji, ili hali iliyo na chelezo iliyovunjika / iliyopotoka isitokee. Na ni bora kufanya hivyo na kila kumbukumbu iliyoundwa, lakini wapi na jinsi inategemea tu mawazo yako (unaweza kuinua seva za kibinafsi kwa kila saa au angalia CI). Lakini kwa kiwango cha chini, ni muhimu kuangalia data na indexes katika database.

Kuangalia data, inatosha kuiendesha kupitia dampo, lakini ni bora kwamba wakati wa kuunda hifadhidata una cheki zilizowezeshwa (ukaguzi wa data):

#!/bin/bash

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

Kuangalia indexes - ipo amcheck moduli, wacha tuchukue swala la sql kwa hilo kutoka Vipimo vya WAL-G na ujenge mantiki kidogo kuzunguka:

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

Kufupisha

Ningependa kutoa shukrani zangu kwa Andrey Borodin kwa msaada wake katika kuandaa uchapishaji na shukrani maalum kwa mchango wake katika maendeleo ya WAL-G!

Hii inahitimisha dokezo hili. Ninatumai kuwa niliweza kuwasilisha urahisi wa kusanidi na uwezekano mkubwa wa kutumia zana hii katika kampuni yako. Nilisikia mengi kuhusu WAL-G, lakini sikuwahi kuwa na wakati wa kutosha wa kukaa chini na kutafakari. Na baada ya kuitekeleza nyumbani, makala hii ilinitoka.

Kando, inafaa kuzingatia kuwa WAL-G pia inaweza kufanya kazi na DBMS ifuatayo:

Chanzo: mapenzi.com

Kuongeza maoni