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).
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:
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:
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.
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:
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.
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:
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: