WAL-G: kaydinta iyo soo kabashada PostgreSQL DBMS

Waxaa muddo dheer la ogaa in samaynta nuqul ka mid ah qashinka SQL (adoo isticmaalaya pg_daad ama pg_dumpall) ma aha fikrad wanaagsan. Si loo kaydiyo PostgreSQL DBMS, way fiicantahay in la isticmaalo amarka pg_basebackup, kaas oo ka dhigaya koobi laba-jibbaaran oo qoraallada WAL ah. Laakiin marka aad bilowdo inaad barato dhammaan habka abuurista nuqulka iyo soo celinta, waxaad fahmi doontaa inaad u baahan tahay inaad qorto ugu yaraan dhowr baaskiil oo saddex lugood ah si ay tani u shaqeyso oo aysan kuu keenin xanuun xagga sare iyo hoose labadaba. Si loo yareeyo dhibaatada, WAL-G waa la sameeyay.

WAL-G waa qalab ku qoran Go oo loogu talagalay soo celinta iyo soo celinta xogta macluumaadka ee PostgreSQL (iyo dhawaanahan MySQL/MariaDB, MongoDB iyo FoundationDB). Waxay taageertaa ku shaqeynta kaydinta Amazon S3 (iyo analoog, tusaale ahaan, Kaydinta Shayga Yandex), iyo sidoo kale Kaydinta Google Cloud, Kaydinta Azure, Kaydinta Shayga Degdega ah iyo si fudud ula nidaamka faylka. Qalabaynta oo dhan waxay hoos ugu dhacdaa tillaabooyin fudud, laakiin sababtoo ah maqaallada ku saabsan waxay ku kala firirsan yihiin internetka, ma jiraan wax-buuxa oo dhammaystiran oo ay ku jiraan dhammaan tillaabooyinka bilawga ilaa dhammaadka (waxaa jira dhowr qoraallo oo ku yaal Habré, balse qodobbo badan ayaa halkaa ku seegaya).

WAL-G: kaydinta iyo soo kabashada PostgreSQL DBMS

Maqaalkan waxa loo qoray ugu horrayn si aan u habeeyo aqoontayda. Anigu ma ihi DBA oo waxaan ku sheegi karaa naftayda luqadda caadiga ah meel, marka wixii sixid ah waa la soo dhaweynayaa!

Dhanka kale, waxaan ogsoonahay in wax kasta oo hoos ku qoran ay khuseeyaan oo lagu tijaabiyay PostgreSQL 12.3 ee Ubuntu 18.04, dhammaan amarrada waa in loo fuliyaa isticmaale mudnaan leh.

Ku rakibida

Waqtiga qorista maqaalkan, nooca xasilloon ee WAL-G waa v0.2.15 (Maarso 2020). Tani waa waxa aan isticmaali doono (laakiin haddii aad rabto inaad adigu ka dhisto laanta master-ka, markaa kaydka github wuxuu leeyahay dhammaan tilmaamaha tan). Si aad u soo dejiso oo aad u rakibto waxaad u baahan tahay:

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

Taas ka dib, waxaad u baahan tahay inaad marka hore habayso WAL-G, ka dibna PostgreSQL lafteeda.

Dejinta WAL-G

Tusaale ahaan kaydinta kaydka, Amazon S3 waa la isticmaali doonaa (sababtoo ah waxay u dhowdahay server-kayga, isticmaalkeeduna waa mid aad u jaban). Si aad ula shaqeyso, waxaad u baahan tahay "baaldi s3" iyo furayaasha gelitaanka.

Dhammaan maqaalladii hore ee ku saabsanaa WAL-G waxay isticmaaleen qaabaynta iyadoo la isticmaalayo doorsoomayaasha deegaanka, laakiin sii dayntan habayntu waxay ku jiri kartaa .walg.json ku jira tusaha guriga ee isticmaalaha postgres. Si aad u abuurto, socodsii qoraalka bash ee soo socda:

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

Aan wax yar ka sharaxo dhammaan halbeegyada:

  • WALG_S3_PREFIX - Jidka baaldigaaga S3 halkaasoo kaydinta lagu dhejin doono (waxaad geli kartaa xididka ama gal);
  • AWS_ACCESS_KEY_ID - furaha gelitaanka ee S3 (Haddii ay dhacdo in lagu soo kabsado server-ka tijaabada ah, furayaashani waa inay lahaadaan Siyaasadda ReadOnly! Tan waxaa si faahfaahsan loogu qeexay qaybta soo kabashada.);
  • AWS_SECRET_ACCESS_KEY - furaha sirta ah ee kaydinta S3;
  • WALG_COMPRESSION_Habka - Habka isku-buufinta, way fiicantahay in la isticmaalo Brotli (maadaama tani ay tahay celceliska dahabiga ah ee u dhexeeya cabbirka ugu dambeeya iyo xawaaraha cadaadiska / hoos u dhigista);
  • WALG_DELTA_MAX_STEPS - tirada "deltas" ka hor inta aan la abuurin gurmad buuxa (waxay kaydiyaan waqti iyo cabbirka xogta la soo dejiyey, laakiin wax yar ayay hoos u dhigi karaan habka soo kabashada, markaa ma aha mid lagu talinayaa in la isticmaalo qiimaha waaweyn);
  • PGDATA - jidka loo maro tusaha xogta xogtaada (waxaad ku ogaan kartaa adigoo ordaya amarka pg_lsclusters);
  • PGHOST - Ku xidhida kaydka xogta, oo leh kayd maxalli ah waxa fiican in lagu sameeyo unix-socket sida tusaalahan.

Qodobo kale ayaa laga heli karaa dukumeentiyada: https://github.com/wal-g/wal-g/blob/v0.2.15/PostgreSQL.md#configuration.

Dejinta PostgreSQL

Si archiver-ka ku dhex jira kaydka xogta uu u soo geliyo diiwaannada WAL ee daruuraha oo uu ka soo celiyo iyaga (haddii loo baahdo), waxaad u baahan tahay inaad dejiso dhowr cabbir oo faylka qaabeynta /etc/postgresql/12/main/postgresql.conf. Kaliya bilow waxaad u baahan tahay inaad hubisoin goobaha hoose midkoodna aan lagu dejin wax qiyam ah, si marka qaabeynta dib loo soo dejiyo, DBMS ma burburto. Waxaad ku dari kartaa xuduudahan adigoo isticmaalaya:

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

Sharaxaadda xuduudaha la dejinayo:

  • wal_level - intee in le'eg macluumaadka lagu qoro diiwaannada WAL, "koob" - wax walba qor;
  • Habka kaydka - awood soo dejinta WAL logs iyadoo la isticmaalayo amarka ka soo jeeda xadka kayd_amar;
  • kayd_amar - amarka kaydinta diiwaanka WAL oo dhammaystiran;
  • kayd_waqti dhamaatey - Kaydinta diiwaannada waxaa la sameeyaa kaliya marka la dhammeeyo, laakiin haddii server-kaagu isbeddelo / ku daro xog yar database, markaa waxaa macno leh in la xaddido halkan ilbiriqsiyo gudahood, ka dib markaa amarka kaydinta ayaa loogu yeeri doonaa si qasab ah (Si degdeg ah ayaan u qoraa xog-ururinta ilbiriqsi kasta, sidaa darteed waxaan go'aansaday inaanan dejin halbeeggan wax-soo-saarka);
  • soo celi amarka - Amarka dib u soo celinta log WAL ee kaydka ayaa la isticmaali doonaa haddii "buuxa kaydinta" (base backup) ay ka maqan tahay isbeddeladii ugu dambeeyay ee kaydka.

Waxaad ka akhrisan kartaa wax badan oo ku saabsan dhammaan cabbirradan tarjumaada dukumeentiga rasmiga ah: https://postgrespro.ru/docs/postgresql/12/runtime-config-wal.

Dejinta jadwal gurmad ah

Wax kasta oo la odhan karo, habka ugu habboon ee loo socodsiiyo waa cron. Tani waa waxa aan u habayn doono si aan u abuurno gurmad. Aan ku bilowno amarka si aan u abuurno gurmad buuxa: Wal-g tani waa doodda bilawga ah dib u riixid. Laakiin marka hore, way fiicantahay in amarkan gacanta lagu maamulo isticmaale postgres si loo hubiyo in wax walba ay fiican yihiin (oo aysan jirin khaladaad marineed):

#!/bin/bash

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

Doodaha bilawga ah waxay muujinayaan jidka loo maro hagaha xogta - waxaan ku xasuusinayaa inaad ku ogaan karto adigoo ordaya pg_lsclusters.

Haddii wax waliba khaladaad la'aan yihiin oo xogta lagu shubay kaydinta S3, markaa waxaad ku habeyn kartaa bilawga xilliyeed ee 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

Tusaalahan, habka gurmadku wuxuu bilaabmaa maalin kasta 4:15 subaxnimo.

Tirtirka kaydkii hore

Waxay u badan tahay, uma baahnid inaad gabi ahaanba kaydiso dhammaan kaydka xilligii Mesozoic, markaa waxay faa'iido u yeelan doontaa inaad "nadiifiso" kaydintaada (labadaba "buuxa kaydinta" iyo diiwaanka WAL). Waxaan tan oo dhan ku samayn doonaa iyada oo loo marayo hawl yar:

#!/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 waxa uu socodsiin doonaa hawshan maalin kasta 6:30 subaxnimo, isaga oo tirtiri doona wax kasta (buuxa kaydinta, deltas iyo WALs) marka laga reebo koobiyada 10-kii maalmood ee u dambeeyay, laakiin ka tagaya ugu yaraan hal kayd si ay u taariikh cayiman si ay dhibic kasta после taariikhaha ayaa lagu daray PITR.

Soo celinta kaydka

Wax qarsoodi ah maaha in furaha xogta caafimaadku yahay soo celinta xilliyeed iyo xaqiijinta daacadnimada xogta gudaha. Waxaan kuu sheegi doonaa sida aad uga soo kabsato adigoo isticmaalaya WAL-G qaybtan, oo waxaan ka hadli doonaa jeegaga dambe.

Waa in si gaar ah loo xuso in si loo soo celiyo jawi tijaabo ah (wax kasta oo aan wax soo saarka ahayn) aad u baahan tahay in la isticmaalo Read Only account ee S3 si aadan si shil ah u qorin nuqul ka mid ah. Xaaladda WAL-G, waxaad u baahan tahay inaad dejiso xuquuqaha soo socda ee isticmaalaha S3 ee Siyaasadda Kooxda (Saamayn: Allow): s3: Hel Walxaha, s3:ListBucket, s3:GetBucketLocation. Iyo, dabcan, ha ilaawin inaad dejiso archive_mode= off ee faylka dejinta postgresql.conf, si aanay xogtaada imtixaanku u doonayn in si hoose loogu kabo.

Soo celinta waxaa lagu sameeyaa dhaqdhaqaaq yar oo gacanta ah tirtirida dhammaan xogta PostgreSQL (oo ay ku jiraan isticmaalayaasha), markaa fadlan si aad ah uga taxaddar markaad socodsiiso amarada soo socda.

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

Kuwa doonaya inay hubiyaan habka soo kabashada, qayb yar oo sixir bash ah ayaa hoos loo diyaariyey, si haddii ay dhacdo dhibaatooyin soo kabashada, qoraalka ayaa ku dhici doona code ka bixitaan aan eber ahayn. Tusaalahan, 120 jeeg ayaa lagu sameeyaa wakhti ka baxsan 5 ilbiriqsi (guud ahaan 10 daqiiqo soo kabashada) si loo ogaado in feylka signalka la tirtiray (tani waxay la macno tahay in soo kabashada lagu guulaystay):

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

Ka dib soo kabashada guusha leh, ha ilaawin inaad dib u bilowdo dhammaan hababka (pgbouncer/monit, iwm.).

Hubinta xogta ka dib soo kabashada

Waa lagama maarmaan in la hubiyo daacadnimada xogta ka dib dib-u-soo-celinta, si aysan xaalad jaban/qalloocan u soo bixin. Way fiicantahay in tan lagu sameeyo kayd kasta oo la abuuray, laakiin halka iyo sida ay ku xiran tahay kaliya male-awaalkaaga (waxaad kor u qaadi kartaa server-yada gaarka ah saacadiiba ama jeeg ku samee CI). Laakiin ugu yaraan, waa lagama maarmaan in la hubiyo xogta iyo tusmooyinka kaydka.

Si aad u hubiso xogta, waa ku filan tahay in la dhex maro meel qashinka lagu daadiyo, laakiin waxa fiican in marka la abuurayo kaydka xogta aad haysato jeegaga ( checksums)xisaabaadka xogta):

#!/bin/bash

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

Si loo hubiyo tusmooyinka - ayaa jira module amcheck, aan ka soo qaadno weydiinta sql Imtixaanada WAL-G oo wax yar oo macquul ah ka dhis

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

Soo koobid

Waxaan jeclaan lahaa inaan u mahadceliyo Andrey Borodin oo gacan ka geystay diyaarinta daabacaadda iyo mahadnaq gaar ah oo uu ka geysto horumarinta WAL-G!

Tani waxay soo gabagabaynaysaa qoraalkan. Waxaan rajeynayaa in aan awooday in aan soo gudbiyo fududaynta habaynta iyo awoodda weyn ee isticmaalka qalabkan shirkaddaada. Wax badan ayaan ka maqlay WAL-G, laakiin weligay ma helin wakhti ku filan oo aan ku fadhiisto oo aan ogaado. Ka dib markii aan ka hirgeliyay guriga, maqaalkani wuu iga soo baxay.

Dhanka kale, waxaa xusid mudan in WAL-G ay sidoo kale la shaqeyn karto DBMS-yada soo socda:

Source: www.habr.com

Add a comment