WAL-G: zosunga zobwezeretsera ndi kubwezeretsa kwa PostgreSQL DBMS

Zadziwika kale kuti kupanga zosunga zobwezeretsera kukhala zotayira za SQL (kugwiritsa ntchito pg_kuta kapena pg_dumpa) si lingaliro labwino. Kuti musunge DBMS ya PostgreSQL, ndibwino kugwiritsa ntchito lamulo pg_basebackup, zomwe zimapanga zolemba za binary za WAL logs. Koma mukayamba kuphunzira njira yonse yopangira kope ndikubwezeretsanso, mudzamvetsetsa kuti muyenera kulemba ma tricycles angapo kuti zonse zigwire ntchito komanso kuti musamapweteketse pamwamba ndi pansi. Kuti achepetse kuvutika, WAL-G idapangidwa.

WAL-G ndi chida cholembedwa mu Go pothandizira ndikubwezeretsanso ma database a PostgreSQL (ndi posachedwa MySQL/MariaDB, MongoDB ndi FoundationDB). Imathandizira kugwira ntchito ndi malo osungira a Amazon S3 (ndi ma analogue, mwachitsanzo, Yandex Object Storage), komanso Google Cloud Storage, Azure Storage, Swift Object Storage komanso ndi mafayilo amafayilo. Kukonzekera konseko kumabwera pamasitepe osavuta, koma chifukwa chakuti zolemba za izo zabalalika pa intaneti, palibe buku lathunthu la momwe lingaphatikizire masitepe onse kuyambira koyambira mpaka kumapeto (pali zolemba zingapo pa Habré, koma mfundo zambiri zaphonya pamenepo).

WAL-G: zosunga zobwezeretsera ndi kubwezeretsa kwa PostgreSQL DBMS

Nkhaniyi idalembedwa makamaka kuti ipange chidziwitso changa. Sindine wa DBA ndipo ndimatha kudzifotokozera m'chinenero cha anthu wamba kwinakwake, kotero kuwongolera kulikonse ndikololedwa!

Payokha, ndikuwona kuti zonse zomwe zili pansipa ndizofunika ndikuyesedwa kwa PostgreSQL 12.3 pa Ubuntu 18.04, malamulo onse ayenera kuchitidwa ngati wogwiritsa ntchito mwayi.

kolowera

Panthawi yolemba nkhaniyi, mtundu wokhazikika wa WAL-G uli v0.2.15 (Marichi 2020). Izi ndi zomwe tidzagwiritse ntchito (koma ngati mukufuna kumanga nokha kuchokera ku master nthambi, ndiye kuti github repository ili ndi malangizo onse a izi.). Kutsitsa ndi kukhazikitsa muyenera kuchita:

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

Pambuyo pake, muyenera kukonza WAL-G poyamba, ndiyeno PostgreSQL yokha.

Kupanga WAL-G

Chitsanzo cha kusunga zosunga zobwezeretsera, Amazon S3 idzagwiritsidwa ntchito (chifukwa ili pafupi ndi ma seva anga ndipo kugwiritsa ntchito kwake ndikotsika mtengo kwambiri). Kuti mugwiritse ntchito, muyenera "s3 chidebe" ndi makiyi olowera.

Zolemba zonse zam'mbuyomu zokhudzana ndi WAL-G zomwe zidagwiritsidwa ntchito pogwiritsa ntchito zosintha zachilengedwe, koma ndikumasulidwa uku zosintha zitha kupezeka .walg.json wapamwamba m'buku lanyumba la wogwiritsa ntchito postgres. Kuti mupange, yendetsani bash script:

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

Ndiloleni ndifotokoze pang'ono za magawo onse:

  • WALG_S3_PREFIX - njira yopita ku chidebe chanu cha S3 komwe zosunga zobwezeretsera zidzakwezedwa (mutha kupita ku mizu kapena chikwatu);
  • AWS_ACCESS_KEY_ID - kiyi yolowera mu S3 (ngati mutachira pa seva yoyesera, makiyi awa ayenera kukhala ndi Ndondomeko ya ReadOnly! Izi zafotokozedwa mwatsatanetsatane mu gawo la kuchira.);
  • AWS_SECRET_ACCESS_KEY - kiyi yachinsinsi mu yosungirako S3;
  • WALG_COMPRESSION_METHOD - njira yopondereza, ndi bwino kugwiritsa ntchito Brotli (popeza izi ndizomwe zimatanthawuza golide pakati pa kukula komaliza ndi kuthamanga / kuthamanga);
  • WALG_DELTA_MAX_STEPS - chiwerengero cha "deltas" musanapange zosunga zobwezeretsera zonse (amasunga nthawi ndi kukula kwa deta yotsitsidwa, koma akhoza kuchepetsa pang'ono kuchira, kotero sikoyenera kugwiritsa ntchito zikhalidwe zazikulu);
  • PGDATA - njira yopita ku chikwatu ndi deta yanu ya database (mukhoza kuzipeza poyendetsa lamulo pg_lsgulu);
  • PHOST - kulumikiza ku database, ndi zosunga zobwezeretsera zakomweko ndi bwino kuchita izi kudzera pa soketi ya unix monga momwe zilili mu chitsanzo ichi.

Zosintha zina zitha kupezeka muzolemba: https://github.com/wal-g/wal-g/blob/v0.2.15/PostgreSQL.md#configuration.

Kupanga PostgreSQL

Kuti osungira mkati mwa database akweze zipika za WAL pamtambo ndikuzibwezeretsa kuchokera kwa iwo (ngati kuli kofunikira), muyenera kukhazikitsa magawo angapo mufayilo yosinthira. /etc/postgresql/12/main/postgresql.conf. Zongoyamba kumene muyenera kutsimikizakuti palibe zomwe zili m'munsimu zomwe zimayikidwa kuzinthu zina zilizonse, kotero kuti pamene kukonzanso kumatsitsimutsidwa, DBMS sichitha. Mutha kuwonjezera magawo awa pogwiritsa ntchito:

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

Kufotokozera kwa magawo omwe akhazikitsidwa:

  • wal_level - kuchuluka kwa zidziwitso zolembedwa mu zipika za WAL, "replica" - lembani chilichonse;
  • archive_mode - Yambitsani kutsitsa kwa zipika za WAL pogwiritsa ntchito lamulo la parameter archive_command;
  • archive_command - Lamulo losunga chipika chomalizidwa cha WAL;
  • archive_timeout - kusungidwa kwa zipika kumangochitika pamene kutsirizidwa, koma ngati seva yanu ikusintha / kuwonjezera deta yaying'ono ku database, ndiye kuti n'zomveka kukhazikitsa malire apa masekondi, pambuyo pake lamulo losungirako lidzatchedwa mokakamiza (Ndimalemba mozama ku database sekondi iliyonse, kotero ndidaganiza kuti ndisakhazikitse izi popanga);
  • bwezeretsa_command - lamulo lobwezeretsa chipika cha WAL kuchokera ku zosunga zobwezeretsera lidzagwiritsidwa ntchito ngati "zosunga zobwezeretsera" (zosunga zoyambira) zilibe zosintha zaposachedwa.

Mutha kuwerenga zambiri za magawo onsewa pomasulira zolembedwa zovomerezeka: https://postgrespro.ru/docs/postgresql/12/runtime-config-wal.

Kupanga dongosolo losunga zobwezeretsera

Chilichonse chomwe anganene, njira yabwino kwambiri yoyendetsera ndi cron. Izi ndi zomwe tidzakonza kuti tipange ma backups. Tiyeni tiyambe ndi lamulo loti tipange zosunga zobwezeretsera zonse: mu wal-g uwu ndiye mkangano woyambitsa backup-kankha. Koma choyamba, ndibwino kuyendetsa lamuloli pamanja kuchokera kwa wogwiritsa ntchito postgres kuti muwonetsetse kuti zonse zili bwino (ndipo palibe zolakwika):

#!/bin/bash

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

Zotsutsana zoyambitsa zikuwonetsa njira yopita ku chikwatu cha data - ndikukumbutsani kuti mutha kuzipeza pothamanga pg_lsgulu.

Ngati zonse zidapita popanda zolakwika ndipo deta idakwezedwa mu yosungirako S3, ndiye mutha kukonza nthawi ndi nthawi mu 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

Muchitsanzo ichi, zosunga zobwezeretsera zimayamba tsiku lililonse nthawi ya 4:15 am.

Kuchotsa zosunga zobwezeretsera zakale

Mwachidziwikire, simuyenera kusunga zosunga zobwezeretsera zanthawi ya Mesozoic, chifukwa chake zidzakhala zothandiza nthawi ndi nthawi "kuyeretsa" zosungira zanu (zonse "zosunga zobwezeretsera" ndi zipika za WAL). Tidzachita zonsezi kudzera mu ntchito 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 azigwira ntchitoyi tsiku lililonse ku 6:30 am, ndikuchotsa zonse (zosunga zobwezeretsera, deltas ndi WALs) kupatula makope amasiku 10 apitawa, koma kusiya zosunga zobwezeretsera kamodzi. mpaka tsiku lotchulidwa kuti mfundo iliyonse после masiku adaphatikizidwa mu PITR.

Kubwezeretsa kuchokera ku zosunga zobwezeretsera

Si chinsinsi kuti chinsinsi cha database yathanzi ndikubwezeretsa nthawi ndi nthawi ndikutsimikizira kukhulupirika kwa data mkati. Ndikuuzani momwe mungabwezeretsere pogwiritsa ntchito WAL-G mu gawoli, ndipo tidzakambirana za macheke pambuyo pake.

Ndikoyenera kuzindikira mosiyana kuti kubwezeretsanso pamalo oyesera (chilichonse chomwe sichikupanga) muyenera kugwiritsa ntchito akaunti ya Read Only mu S3 kuti musalembe mwangozi zosunga zobwezeretsera. Pankhani ya WAL-G, muyenera kukhazikitsa maufulu otsatirawa kwa wogwiritsa ntchito S3 mu Gulu Policy (Zotsatira: Lolani): s3:GetObject, s3: ListBucket, s3:GetBucketLocation. Ndipo, ndithudi, musaiwale kukhazikitsa archive_mode=kuchotsa mu zoikamo file postgresql.conf, kotero kuti nkhokwe yanu yoyeserera sikufuna kusungidwa mwakachetechete.

Kubwezeretsa kumachitika ndi kuyenda pang'ono kwa dzanja Kuchotsa deta yonse ya PostgreSQL (kuphatikiza ogwiritsa), ndiye chonde samalani kwambiri mukamayendetsa malamulo otsatirawa.

#!/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 iwo omwe akufuna kuyang'ana ndondomeko yobwezeretsa, kachidutswa kakang'ono ka bash magic kakonzedwa pansipa, kotero kuti pakakhala mavuto pakuchira, script idzaphwanyidwa ndi code yotuluka yopanda zero. Muchitsanzo ichi, macheke 120 amapangidwa ndi kutha kwa masekondi 5 (okwana mphindi 10 kuti achire) kuti adziwe ngati fayilo ya siginecha idachotsedwa (izi zikutanthauza kuti kuchira kudachitika bwino):

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

Mukachira bwino, musaiwale kuyambitsanso njira zonse (pgbouncer/monit, etc.).

Kuyang'ana deta pambuyo kuchira

Ndikofunikira kuyang'ana kukhulupirika kwa nkhokwe pambuyo pa kubwezeretsedwa, kuti mkhalidwe wokhala ndi zosunga zobwezeretsera / zokhotakhota zisabwere. Ndipo ndi bwino kuchita izi ndi zolemba zonse zomwe zidapangidwa, koma kuti ndi momwe zimatengera malingaliro anu (mutha kukweza ma seva pa ola limodzi kapena kuyendetsa cheke mu CI). Koma osachepera, ndikofunikira kuyang'ana ma data ndi ma index omwe ali mu database.

Kuti muwone zambiri, ndikwanira kuyiyendetsa potaya, koma ndibwino kuti popanga database muli ndi ma checksums (macheke a data):

#!/bin/bash

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

Kuti muwone ma index - alipo amcheck module, tiyeni titengeko funso la sql kuchokera Mayeso a WAL-G ndi kupanga malingaliro pang'ono mozungulira:

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

Kufotokozera mwachidule

Ndikufuna kuthokoza kwa Andrey Borodin chifukwa cha thandizo lake pokonzekera kufalitsa ndi kuyamika kwapadera chifukwa cha thandizo lake pa chitukuko cha WAL-G!

Izi zikumaliza cholemba ichi. Ndikukhulupirira kuti ndatha kukuwonetsani kumasuka kwa kukhazikitsa komanso kuthekera kwakukulu kogwiritsa ntchito chida ichi pakampani yanu. Ndinamva zambiri za WAL-G, koma ndinalibe nthawi yokwanira yokhala pansi ndikuzilingalira. Ndipo nditakhazikitsa kunyumba, nkhaniyi idandituluka.

Payokha, ndikofunikira kudziwa kuti WAL-G imathanso kugwira ntchito ndi DBMS zotsatirazi:

Source: www.habr.com

Kuwonjezera ndemanga