WAL-G: awọn afẹyinti ati imularada PostgreSQL DBMS

O ti pẹ ti mọ pe ṣiṣe awọn afẹyinti sinu awọn idalẹnu SQL (lilo pg_idasonu tabi pg_dumpall) kii ṣe imọran to dara. Lati ṣe afẹyinti PostgreSQL DBMS, o dara lati lo aṣẹ naa pg_basebackup, eyi ti o ṣe ẹda alakomeji ti WAL logs. Ṣugbọn nigbati o ba bẹrẹ ikẹkọ gbogbo ilana ti ṣiṣẹda ẹda kan ati mimu-pada sipo, iwọ yoo loye pe o nilo lati kọ o kere ju awọn kẹkẹ-mẹta meji fun eyi lati ṣiṣẹ ati pe ko fa ọ ni irora mejeeji loke ati ni isalẹ. Lati din ijiya, WAL-G ti ni idagbasoke.

WAL-G jẹ ọpa ti a kọ ni Go fun n ṣe afẹyinti ati mimu-pada sipo awọn apoti isura data PostgreSQL (ati diẹ sii laipe MySQL/MariaDB, MongoDB ati FoundationDB). O ṣe atilẹyin ṣiṣẹ pẹlu ibi ipamọ Amazon S3 (ati awọn analogues, fun apẹẹrẹ, Ibi ipamọ Nkan Yandex), bakanna bi Ibi ipamọ awọsanma Google, Ibi ipamọ Azure, Ibi ipamọ Nkan Swift ati irọrun pẹlu eto faili. Gbogbo iṣeto ni o wa si isalẹ si awọn igbesẹ ti o rọrun, ṣugbọn nitori otitọ pe awọn nkan nipa rẹ ti tuka kaakiri Intanẹẹti, ko si ni pipe bi-si Afowoyi ti yoo pẹlu gbogbo awọn igbesẹ lati ibẹrẹ si ipari (awọn ifiweranṣẹ lọpọlọpọ wa lori Habré, sugbon opolopo ojuami ti wa ni padanu nibẹ).

WAL-G: awọn afẹyinti ati imularada PostgreSQL DBMS

Yi article a ti kọ nipataki lati systematize mi imo. Emi kii ṣe DBA ati pe MO le sọ ara mi han ni ede layman ni ibikan, nitorinaa eyikeyi awọn atunṣe jẹ itẹwọgba!

Lọtọ, Mo ṣe akiyesi pe ohun gbogbo ti o wa ni isalẹ jẹ pataki ati idanwo fun PostgreSQL 12.3 lori Ubuntu 18.04, gbogbo awọn aṣẹ gbọdọ wa ni ṣiṣe bi olumulo ti o ni anfani.

eto

Ni akoko kikọ nkan yii, ẹya iduroṣinṣin ti WAL-G jẹ v0.2.15 (Oṣu Kẹta ọdun 2020). Eyi ni ohun ti a yoo lo (ṣugbọn ti o ba fẹ kọ funrararẹ lati ẹka titunto si, lẹhinna ibi ipamọ github ni gbogbo awọn ilana fun eyi). Lati ṣe igbasilẹ ati fi sori ẹrọ o nilo lati ṣe:

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

Lẹhin eyi, o nilo lati tunto WAL-G ni akọkọ, ati lẹhinna PostgreSQL funrararẹ.

Ṣiṣeto WAL-G

Fun apẹẹrẹ ti ipamọ awọn afẹyinti, Amazon S3 yoo ṣee lo (nitori pe o sunmọ awọn olupin mi ati lilo rẹ jẹ olowo poku). Lati ṣiṣẹ pẹlu rẹ, o nilo “garawa s3” ati awọn bọtini iwọle.

Gbogbo awọn nkan ti tẹlẹ nipa WAL-G lo iṣeto ni lilo awọn oniyipada ayika, ṣugbọn pẹlu itusilẹ yii awọn eto le wa ninu .walg.json faili ninu ilana ile ti olumulo postgres. Lati ṣẹda rẹ, ṣiṣe iwe afọwọkọ bash wọnyi:

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

Jẹ ki n ṣe alaye diẹ nipa gbogbo awọn paramita:

  • WALG_S3_PREFIX - ọna si garawa S3 rẹ nibiti awọn afẹyinti yoo gbejade (o le boya si gbongbo tabi si folda kan);
  • AWS_ACCESS_KEY_ID - bọtini wiwọle ni S3 (ni ọran ti imularada lori olupin idanwo kan, awọn bọtini wọnyi gbọdọ ni Afihan ReadOnly! Eyi ni apejuwe diẹ sii ni apakan lori imularada.);
  • AWS_SECRET_ACCESS_KEY - bọtini ikoko ni ibi ipamọ S3;
  • WALG_COMPRESSION_METHOD - ọna funmorawon, o jẹ dara lati lo Brotli (niwon yi ni goolu tumosi laarin awọn ik iwọn ati ki o funmorawon / decompressing iyara);
  • WALG_DELTA_MAX_STEPS - nọmba ti "deltas" ṣaaju ki o to ṣẹda afẹyinti ni kikun (wọn fi akoko pamọ ati iwọn data ti a gba lati ayelujara, ṣugbọn o le fa fifalẹ ilana imularada, nitorina ko ni imọran lati lo awọn iye nla);
  • PGDATA - ọna si itọsọna pẹlu data data data rẹ (o le rii nipa ṣiṣe pipaṣẹ naa pg_lsclusters);
  • PGHOST - sisopọ si ibi ipamọ data, pẹlu afẹyinti agbegbe o dara lati ṣe nipasẹ iho-unix bi ninu apẹẹrẹ yii.

Awọn paramita miiran ni a le rii ninu iwe: https://github.com/wal-g/wal-g/blob/v0.2.15/PostgreSQL.md#configuration.

Ṣiṣeto PostgreSQL

Ni ibere fun iwe ipamọ inu ibi ipamọ data lati gbe awọn iwe WAL si awọsanma ki o mu wọn pada lati ọdọ wọn (ti o ba jẹ dandan), o nilo lati ṣeto awọn ipele pupọ ninu faili iṣeto ni /etc/postgresql/12/main/postgresql.conf. Kan fun awọn ibẹrẹ o nilo lati rii dajupe ko si ọkan ninu awọn eto ti o wa ni isalẹ ti ṣeto si awọn iye miiran, nitorinaa nigbati atunto ba tun gbejade, DBMS ko jamba. O le fi awọn paramita wọnyi kun nipa lilo:

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

Apejuwe ti awọn paramita lati ṣeto:

  • ipele_ipele Elo alaye lati kọ ni WAL logs, "ajọra" - kọ ohun gbogbo;
  • pamosi_mode - mu igbasilẹ ti awọn iwe WAL ṣiṣẹ ni lilo aṣẹ lati paramita naa pamosi_aṣẹ;
  • pamosi_aṣẹ - aṣẹ fun fifipamọ iwe-ipamọ WAL ti o pari;
  • pamosi_timeout - Ifipamọ awọn igbasilẹ ni a ṣe nikan nigbati o ba ti pari, ṣugbọn ti olupin rẹ ba yipada / ṣafikun data kekere si ibi ipamọ data, lẹhinna o jẹ oye lati ṣeto opin kan nibi ni iṣẹju-aaya, lẹhin eyiti aṣẹ fifipamọ yoo pe ni tipatipa (Mo kọ lekoko si data ni gbogbo iṣẹju-aaya, nitorinaa Mo pinnu lati ma ṣeto paramita yii ni iṣelọpọ);
  • mu pada_aṣẹ - aṣẹ lati mu pada WAL log lati afẹyinti yoo ṣee lo ti “afẹyinti ni kikun” (afẹyinti ipilẹ) ko ni awọn ayipada tuntun ninu aaye data.

O le ka diẹ sii nipa gbogbo awọn paramita wọnyi ni itumọ ti iwe aṣẹ osise: https://postgrespro.ru/docs/postgresql/12/runtime-config-wal.

Ṣiṣeto iṣeto afẹyinti

Ohunkohun ti ẹnikan le sọ, ọna ti o rọrun julọ lati ṣiṣe ni cron. Eyi ni ohun ti a yoo tunto lati ṣẹda awọn afẹyinti. Jẹ ki a bẹrẹ pẹlu aṣẹ lati ṣẹda afẹyinti ni kikun: ni wal-g eyi ni ariyanjiyan ifilọlẹ afẹyinti-titari. Ṣugbọn akọkọ, o dara lati ṣiṣẹ aṣẹ yii pẹlu ọwọ lati ọdọ olumulo postgres lati rii daju pe ohun gbogbo dara (ati pe ko si awọn aṣiṣe iwọle):

#!/bin/bash

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

Awọn ariyanjiyan ifilọlẹ tọka ọna si itọsọna data - Mo leti pe o le rii nipasẹ ṣiṣe pg_lsclusters.

Ti ohun gbogbo ba lọ laisi awọn aṣiṣe ati pe o ti gbe data sinu ibi ipamọ S3, lẹhinna o le tunto ifilọlẹ igbakọọkan ni 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

Ni apẹẹrẹ yii, ilana afẹyinti bẹrẹ ni gbogbo ọjọ ni 4:15 owurọ.

Npa awọn afẹyinti atijọ kuro

O ṣeese julọ, iwọ ko nilo lati tọju gbogbo awọn afẹyinti patapata lati akoko Mesozoic, nitorinaa yoo wulo lati “sọ di mimọ” ibi ipamọ rẹ nigbagbogbo (mejeeji “awọn afẹyinti kikun” ati awọn akọọlẹ WAL). A yoo ṣe gbogbo eyi nipasẹ iṣẹ-ṣiṣe 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 yoo ṣiṣẹ iṣẹ yii ni gbogbo ọjọ ni 6:30 owurọ, piparẹ ohun gbogbo (awọn afẹyinti kikun, deltas ati WALs) ayafi awọn ẹda fun awọn ọjọ 10 to kọja, ṣugbọn nlọ o kere ju afẹyinti kan. si pàtó kan ọjọ ki eyikeyi ojuami после awọn ọjọ ti o wa ninu PITR.

Pada sipo lati afẹyinti

Kii ṣe aṣiri pe bọtini si aaye data ilera jẹ imupadabọ igbakọọkan ati ijẹrisi ti iduroṣinṣin data inu. Emi yoo sọ fun ọ bi o ṣe le gba pada nipa lilo WAL-G ni apakan yii, ati pe a yoo sọrọ nipa awọn sọwedowo nigbamii.

O tọ lati ṣe akiyesi lọtọ pe lati mu pada ni agbegbe idanwo (ohun gbogbo ti kii ṣe iṣelọpọ) o nilo lati lo akọọlẹ Ka nikan ni S3 ki o má ba ṣe atunkọ awọn afẹyinti lairotẹlẹ. Ninu ọran ti WAL-G, o nilo lati ṣeto awọn ẹtọ wọnyi fun olumulo S3 ni Ilana Ẹgbẹ (Ipa: Gba laaye): s3:Gba Nkan, s3: AkojọBucket, s3:GetBucketLocation. Ati, dajudaju, maṣe gbagbe lati ṣeto archive_mode = pipa ninu faili eto postgresql.conf, ki aaye data idanwo rẹ ko fẹ lati ṣe afẹyinti ni idakẹjẹ.

Atunṣe ni a ṣe pẹlu gbigbe diẹ ti ọwọ piparẹ gbogbo data PostgreSQL (pẹlu awọn olumulo), nitorina jọwọ ṣọra gidigidi nigbati o ba nṣiṣẹ awọn aṣẹ wọnyi.

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

Fun awọn ti o fẹ lati ṣayẹwo ilana imularada, a ti pese nkan kekere ti idan bash ni isalẹ, ki o jẹ pe ninu awọn iṣoro ni imularada, iwe afọwọkọ yoo kọlu pẹlu koodu ijade ti kii-odo. Ni apẹẹrẹ yii, awọn sọwedowo 120 ni a ṣe pẹlu akoko iṣẹju-aaya 5 (apapọ iṣẹju mẹwa 10 fun imularada) lati rii boya o ti paarẹ faili ifihan agbara (eyi yoo tumọ si pe imularada ti ṣaṣeyọri):

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

Lẹhin imularada aṣeyọri, maṣe gbagbe lati bẹrẹ gbogbo awọn ilana pada (pgbouncer/monit, bbl).

Ṣiṣayẹwo data lẹhin imularada

O jẹ dandan lati ṣayẹwo otitọ ti data lẹhin imupadabọ, ki ipo kan pẹlu afẹyinti fifọ / wiwọ ko dide. Ati pe o dara lati ṣe eyi pẹlu iwe-ipamọ kọọkan ti a ṣẹda, ṣugbọn nibo ati bii da lori oju inu rẹ nikan (o le gbe awọn olupin kọọkan dide ni ipilẹ wakati tabi ṣiṣe ayẹwo ni CI). Ṣugbọn ni o kere ju, o jẹ dandan lati ṣayẹwo awọn data ati awọn atọka ninu database.

Lati ṣayẹwo data naa, o to lati ṣiṣẹ nipasẹ idalẹnu kan, ṣugbọn o dara julọ pe nigba ṣiṣẹda ibi ipamọ data o ti ṣiṣẹ awọn ayẹwo ayẹwo (data checksums):

#!/bin/bash

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

Lati ṣayẹwo awọn atọka - wa amcheck module, jẹ ki a mu ibeere sql fun lati Awọn idanwo WAL-G ki o si kọ ọgbọn diẹ ni ayika rẹ:

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

Akopọ

Emi yoo fẹ lati fi idupẹ mi han si Andrey Borodin fun iranlọwọ rẹ ni ṣiṣeradi atẹjade naa ati ọpẹ pataki fun ilowosi rẹ si idagbasoke WAL-G!

Eyi pari akọsilẹ yii. Mo nireti pe MO ni anfani lati ṣafihan irọrun ti iṣeto ati agbara nla fun lilo ọpa yii ni ile-iṣẹ rẹ. Mo ti gbọ kan pupo nipa WAL-G, sugbon ko ni to akoko lati a joko si isalẹ ki o ro ero o jade. Ati lẹhin ti Mo ṣe imuse rẹ ni ile, nkan yii ti jade ninu mi.

Lọtọ, o tọ lati ṣe akiyesi pe WAL-G tun le ṣiṣẹ pẹlu DBMS wọnyi:

orisun: www.habr.com

Fi ọrọìwòye kun