WAL-G: PostgreSQL DBMS-nin ehtiyat nüsxələri və bərpaları

SQL zibilliklərinin ehtiyat nüsxəsini çıxarması çoxdan məlumdur ( pg_dump və ya pg_dumpall) yaxşı fikir deyil. PostgreSQL DBMS-nin ehtiyat nüsxəsini çıxarmaq üçün əmrdən istifadə etmək daha yaxşıdır pg_basebackup, WAL qeydlərinin ikili surətini çıxarır. Ancaq bir nüsxənin yaradılması və bərpasının bütün prosesini öyrənməyə başlayanda başa düşəcəksiniz ki, bütün bunların işləməsi və yuxarıdan və aşağıdan ağrıya səbəb olmamaq üçün ən azı bir neçə üç təkər yazmaq lazımdır. Əzabları yüngülləşdirmək üçün WAL-G hazırlanmışdır.

WAL-G PostgreSQL verilənlər bazalarının ehtiyat nüsxəsini çıxarmaq və bərpa etmək üçün Go-da yazılmış bir vasitədir (və daha yaxınlarda MySQL/MariaDB, MongoDB və FoundationDB). O, Amazon S3 anbarları (və analoqları, məsələn, Yandex Object Storage), həmçinin Google Cloud Storage, Azure Storage, Swift Object Storage və sadəcə fayl sistemi ilə işləməyi dəstəkləyir. Bütün quraşdırma sadə addımlara düşür, lakin bu barədə məqalələr İnternetdə səpələnmiş olduğundan, bütün addımları özündə əks etdirən tam bir necə təlimat yoxdur (Habré-də bir neçə yazı var, lakin orada çoxlu məqamlar buraxılıb).

WAL-G: PostgreSQL DBMS-nin ehtiyat nüsxələri və bərpaları

Bu məqalə ilk növbədə biliklərimi sistemləşdirmək üçün yazılmışdır. Mən DBA deyiləm və haradasa layman dilində danışa bilirəm, ona görə də istənilən düzəlişlər qəbul olunur!

Ayrı-ayrılıqda qeyd edirəm ki, aşağıda hər şey aktualdır və Ubuntu 12.3-də PostgreSQL 18.04 üçün sınaqdan keçirilib, bütün əmrlər imtiyazlı istifadəçi kimi yerinə yetirilməlidir.

Quraşdırma

Bu yazı zamanı WAL-G-nin sabit versiyasıdır v0.2.15 (Mart 2020). Biz ondan istifadə edəcəyikancaq onu master filialından özünüz qurmaq istəyirsinizsə, github deposunda bunun üçün bütün təlimatlar var.). Yükləmək və quraşdırmaq üçün işə salmalısınız:

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

Bundan sonra əvvəlcə WAL-G-ni, sonra isə PostgreSQL-in özünü konfiqurasiya etməlisiniz.

WAL-G quraşdırma

Ehtiyat nüsxələrin saxlanması nümunəsi üçün Amazon S3 istifadə olunacaq (çünki mənim serverlərimə daha yaxındır və istifadəsi çox ucuzdur). Onunla işləmək üçün sizə "s3-kova" və giriş düymələri lazımdır.

Bütün əvvəlki WAL-G məqalələri mühit dəyişənləri vasitəsilə konfiqurasiyadan istifadə etmişdir, lakin bu buraxılışdan etibarən parametrlər burada yerləşdirilə bilər. .walg.json faylı postgres istifadəçisinin ev kataloqunda. Onu yaratmaq üçün aşağıdakı bash skriptini işlədin:

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

Hər şeyi bir az izah edim:

  • WALG_S3_PREFIX - ehtiyat nüsxələrin yüklənəcəyi S3 vedrəsinə gedən yol (ya kökə, ya da qovluğa gedə bilərsiniz);
  • AWS_ACCESS_KEY_ID – S3-də giriş düyməsi (test serverində bərpa edildikdə - bu açarların Yalnız Oxunma Siyasəti olmalıdır! Bu, bərpa bölməsində daha ətraflı müzakirə olunur.);
  • AWS_SECRET_ACCESS_KEY – S3 yaddaşında gizli açar;
  • WALG_COMPRESSION_METHOD - sıxılma üsulu, Brotli istifadə etmək daha yaxşıdır (çünki bu, son ölçü ilə sıxılma / dekompressiya sürəti arasındakı qızıl ortadır);
  • WALG_DELTA_MAX_STEPS - tam ehtiyat nüsxəsini yaratmazdan əvvəl "deltaların" sayı (vaxt və yüklənmiş məlumatların ölçüsünə qənaət etməyə imkan verir, lakin bərpa prosesini bir qədər ləngidə bilər, ona görə də böyük dəyərlərdən istifadə etmək məqsədəuyğun deyil);
  • PGDATA – verilənlər bazası məlumatlarınızla qovluğa gedən yol (əmrini işlətməklə tapmaq olar pg_lsclusters);
  • PGHOST - verilənlər bazasına qoşulma, yerli ehtiyat nüsxə ilə, bu nümunədə olduğu kimi, unix-soket vasitəsilə etmək daha yaxşıdır.

Digər seçimləri sənədlərdə tapa bilərsiniz: https://github.com/wal-g/wal-g/blob/v0.2.15/PostgreSQL.md#configuration.

PostgreSQL konfiqurasiyası

Verilənlər bazası içindəki arxivçinin WAL qeydlərini buludlara yükləməsi və onlardan bərpa etməsi üçün (lazım olduqda) konfiqurasiya faylında bir neçə parametr təyin etməlisiniz. /etc/postgresql/12/main/postgresql.conf. Sadəcə yeni başlayanlar üçün əmin olmaq lazımdırkonfiqurasiya yenidən yükləndikdə DBMS düşməməsi üçün aşağıdakı parametrlərdən heç biri başqa dəyərlərə təyin edilməmişdir. Bu seçimləri aşağıdakılarla əlavə edə bilərsiniz:

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

Ayarlanacaq parametrlərin təsviri:

  • wal_level - WAL jurnallarında nə qədər məlumat yazmaq lazımdır, "replika" - hər şeyi yazın;
  • arxiv_rejimi – parametrdən əmrdən istifadə edərək WAL qeydlərinin yüklənməsini aktivləşdirin arxiv_komandası;
  • arxiv_komandası – tamamlanmış WAL jurnalının arxivləşdirilməsi əmri;
  • arxiv_vaxt aşımı - logların arxivləşdirilməsi yalnız tamamlandıqdan sonra həyata keçirilir, lakin serveriniz verilənlər bazasına az məlumat əlavə edirsə/dəyişirsə, burada saniyələr ərzində limit təyin etməyin mənası var, bundan sonra arxivləşdirmə əmri zorla çağırılacaq (Hər saniyə verilənlər bazasına intensiv yazım var, buna görə də istehsalda bu parametri təyin etməkdən imtina etdim);
  • bərpa_komandası – “tam ehtiyat nüsxə” (əsas ehtiyat nüsxə) verilənlər bazasında ən son dəyişikliklərə malik olmadıqda, WAL jurnalını ehtiyat nüsxədən bərpa etmək əmrindən istifadə olunacaq.

Bütün bu parametrlər haqqında daha çox rəsmi sənədlərin tərcüməsində oxuya bilərsiniz: https://postgrespro.ru/docs/postgresql/12/runtime-config-wal.

Yedəkləmə cədvəlinin qurulması

İstər-istəməz, amma onu idarə etməyin ən əlverişli yolu crondur. Bu, ehtiyat nüsxələri yaratmaq üçün konfiqurasiya edəcəyimiz şeydir. Tam ehtiyat nüsxəsini yaratmaq əmri ilə başlayaq: wal-g-də bu işə salma arqumentidir backup-push. Ancaq əvvəlcə hər şeyin qaydasında olduğuna (və giriş xətalarının olmadığına) əmin olmaq üçün bu əmri postgres istifadəçisi kimi əl ilə icra etmək daha yaxşıdır:

#!/bin/bash

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

Başlatma arqumentləri məlumat qovluğuna gedən yolu ehtiva edir - sizə xatırladıram ki, onu işə salmaqla tapa bilərsiniz pg_lsclusters.

Hər şey səhvsiz keçibsə və məlumatlar S3 yaddaşına yüklənibsə, o zaman crontab-da dövri işə salınmanı daha da konfiqurasiya edə bilərsiniz:

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

Bu nümunədə ehtiyat nüsxə prosesi hər gün səhər saat 4:15-də başlayır.

Köhnə ehtiyat nüsxələrin silinməsi

Çox güman ki, Mezozoy dövründən bütün ehtiyat nüsxələri saxlamağa ehtiyac yoxdur, ona görə də yaddaşınızı vaxtaşırı “təmizləmək” (həm “tam ehtiyat nüsxələri”, həm də WAL qeydləri) yaxşı fikirdir. Bütün bunları cron tapşırığı vasitəsilə də edəcəyik:

#!/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 bu tapşırığı hər gün səhər saat 6:30-da yerinə yetirəcək, son 10 gün istisna olmaqla, hər şeyi (tam ehtiyat nüsxələri, deltalar və WAL'ları) siləcək, lakin ən azı bir ehtiyat nüsxəsini buraxacaq. üzrə istənilən nöqtəyə təyin edilmiş tarix sonra tarixlər PITR-ə daxil oldu.

Yedəkdən bərpa edilir

Heç kimə sirr deyil ki, sağlam verilənlər bazasının açarı vaxtaşırı olaraq içindəki məlumatların bütövlüyünü bərpa etmək və yoxlamaqdır. WAL-G istifadə edərək necə bərpa etmək olar - bu bölmədə sizə xəbər verəcəyəm və daha sonra çeklər haqqında danışacağıq.

Ayrı-ayrılıqda qeyd etmək lazımdır test mühitində bərpa etmək üçün (istehsal olmayan hər şey) - ehtiyat nüsxələri təsadüfən üzərinə yazmamaq üçün S3-də Yalnız oxunan hesabdan istifadə etməlisiniz. WAL-G vəziyyətində, S3 istifadəçisinə Qrup Siyasətində aşağıdakı hüquqları təyin etməlisiniz (Effekt: icazə verin): s3: GetObject, s3: ListBucket, s3:GetBucketLocation. Və təbii ki, yazmağı unutmayın arxiv_rejimi=off parametrlər faylında postgresql.conftest bazanızın səssizcə ehtiyat nüsxəsini çıxarmaq istəməməsi üçün.

Bərpa ilə əlin yüngül hərəkəti ilə həyata keçirilir bütün PostgreSQL məlumatlarının silinməsi (istifadəçilər daxil olmaqla), ona görə də aşağıdakı əmrləri yerinə yetirərkən çox diqqətli olun.

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

Bərpa prosesini yoxlamaq istəyənlər üçün aşağıda kiçik bir bash sehri hazırlanmışdır ki, bərpa zamanı problemlər yaranarsa, skript sıfırdan fərqli bir çıxış kodu ilə qəzaya uğrasın. Bu misalda, siqnal faylının silinib silinmədiyini öyrənmək üçün 120 saniyəlik fasilə ilə (bərpa üçün cəmi 5 dəqiqə) 10 yoxlama aparılır (bu, bərpanın uğurlu olduğunu bildirir):

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

Uğurlu bərpa etdikdən sonra bütün prosesləri yenidən başlatmağı unutmayın (pgbouncer / monit və s.).

Bərpa edildikdən sonra məlumatların yoxlanılması

Bərpa edildikdən sonra verilənlər bazasının bütövlüyünü yoxladığınızdan əmin olun ki, qırıq / əyri ehtiyat nüsxəsi ilə bağlı vəziyyət olmasın. Bunu hər yaradılmış arxivlə etmək daha yaxşıdır, ancaq harada və necə təsəvvürünüzə bağlıdır (hər saat ərzində ayrı-ayrı serverlər qaldıra və ya CI-də yoxlama apara bilərsiniz). Amma ən azı verilənlər bazasındakı məlumatları və indeksləri yoxlamaq lazımdır.

Məlumatları yoxlamaq üçün onu zibildən keçirtmək kifayətdir, lakin verilənlər bazası yaratarkən yoxlama məbləğlərini aktivləşdirmək daha yaxşıdır (məlumat yoxlama məbləğləri):

#!/bin/bash

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

İndeksləri yoxlamaq üçün - mövcuddur amcheck modulu, sql-sorğunu ondan alacağıq WAL-G testləri və ətrafında bir az məntiq qurun:

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

Xülasə

Nəşrin hazırlanmasında köməyə görə Andrey Borodinə minnətdarlığımı və WAL-G-nin inkişafına verdiyi töhfəyə görə xüsusi təşəkkürümü bildirirəm!

Bu qeydi yekunlaşdırır. Ümid edirəm ki, fərdiləşdirmənin asanlığını və bu alətdən şirkətinizdə istifadə etmək üçün böyük potensialı çatdıra bildim. WAL-G haqqında çox eşitdim, amma oturub başa düşməyə vaxtım yox idi. Evdə həyata keçirdikdən sonra bu məqalə məndən çıxdı.

Ayrıca, WAL-G-nin aşağıdakı DBMS ilə də işləyə biləcəyini qeyd etmək lazımdır:

Mənbə: www.habr.com

Добавить комментарий