WAL-G: cadangan sareng pamulihan PostgreSQL DBMS

Geus lila dipikanyaho yén nyieun cadangan kana dumps SQL (ngagunakeun pg_dump atawa pg_dumpall) sanes ide nu sae. Pikeun nyadangkeun DBMS PostgreSQL, langkung saé nganggo paréntah pg_basebackup, nu nyieun salinan binér tina log WAL. Tapi nalika anjeun mimiti diajar sadayana prosés nyiptakeun salinan sareng malikkeun, anjeun bakal ngartos yén anjeun kedah nyerat sahenteuna sababaraha beca pikeun ieu jalan sareng henteu nyababkeun nyeri anjeun di luhur sareng di handap. Pikeun ngirangan kasangsaraan, WAL-G dikembangkeun.

WAL-G mangrupikeun alat anu ditulis dina Go pikeun nyadangkeun sareng malikkeun database PostgreSQL (sareng langkung énggal MySQL / MariaDB, MongoDB sareng FoundationDB). Éta ngadukung damel sareng panyimpenan Amazon S3 (sareng analog, contona, Panyimpenan Objék Yandex), ogé Panyimpenan Awan Google, Panyimpenan Azure, Panyimpen Obyék Swift sareng ngan ukur nganggo sistem file. Sakabeh setelan asalna handap pikeun léngkah basajan, tapi alatan kanyataan yén artikel ngeunaan eta sumebar ka sakuliah Internet, teu aya lengkep kumaha-cara manual nu bakal ngawengku sagala léngkah ti mimiti nepi ka rengse (aya sababaraha tulisan dina Habré, tapi seueur titik anu sono di dinya).

WAL-G: cadangan sareng pamulihan PostgreSQL DBMS

Artikel ieu ditulis utamana pikeun systematize pangaweruh kuring. Abdi sanés DBA sareng abdi tiasa nganyatakeun diri dina basa awam dimana waé, janten koréksi naon waé ditampi!

Kapisah, kuring perhatikeun yén sadayana di handap ieu relevan sareng diuji pikeun PostgreSQL 12.3 dina Ubuntu 18.04, sadaya paréntah kedah dieksekusi salaku pangguna anu ngagaduhan hak istimewa.

setting

Dina waktos nyerat tulisan ieu, versi stabil tina WAL-G nyaéta v0.2.15 (Maret 2020). Ieu naon urang bakal ngagunakeun (tapi upami anjeun hoyong ngawangun éta nyalira tina cabang master, maka gudang github gaduh sadayana petunjuk pikeun ieu). Pikeun ngundeur sareng masang anjeun kedah ngalakukeun:

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

Saatos ieu, anjeun kedah ngonpigurasikeun WAL-G heula, teras PostgreSQL nyalira.

Nyetél WAL-G

Pikeun conto nyimpen cadangan, Amazon S3 bakal dianggo (sabab leuwih deukeut ka server kuring jeung pamakéan na pisan mirah). Pikeun digawekeun ku eta, anjeun peryogi "ember s3" jeung kenop aksés.

Sadaya tulisan sateuacana ngeunaan WAL-G nganggo konfigurasi nganggo variabel lingkungan, tapi kalayan sékrési ieu setélan tiasa ditempatkeun di .walg.json file dina diréktori imah pangguna postgres. Pikeun nyiptakeunana, jalankeun skrip bash ieu:

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

Hayu atuh ngajelaskeun saeutik ngeunaan sakabéh parameter:

  • WALG_S3_PREFIX - jalur ka ember S3 anjeun dimana cadangan bakal diunggah (anjeun tiasa ka akar atanapi ka folder);
  • AWS_ACCESS_KEY_ID - konci aksés dina S3 (bisi recovery on server test, konci ieu kudu boga ReadOnly Sarat jeung Kaayaan! Ieu dijelaskeun dina leuwih jéntré dina bagian on recovery.);
  • AWS_SECRET_ACCESS_KEY - konci rusiah dina gudang S3;
  • WALG_COMPRESSION_METHOD - métode komprési, eta leuwih hade migunakeun Brotli (sabab ieu teh mean emas antara ukuran final sarta laju komprési / decompression);
  • WALG_DELTA_MAX_STEPS - jumlah "delta" sateuacan nyieun cadangan pinuh (aranjeunna ngahemat waktos sareng ukuran data anu diunduh, tapi tiasa rada ngalambatkeun prosés pamulihan, janten henteu disarankeun ngagunakeun nilai anu ageung);
  • PGDATA - jalur ka diréktori sareng data database anjeun (anjeun tiasa mendakan ku ngajalankeun paréntah pg_lsclusters);
  • GHOST - nyambungkeun kana databés, jeung cadangan lokal leuwih hade ngalakukeun eta via unix-stop kontak saperti dina conto ieu.

Parameter sanésna tiasa dipendakan dina dokuméntasi: https://github.com/wal-g/wal-g/blob/v0.2.15/PostgreSQL.md#configuration.

Nyetél PostgreSQL

Supados arsip di jero pangkalan data tiasa unggah log WAL kana méga sareng malikkeunana ti aranjeunna (upami diperyogikeun), anjeun kedah nyetél sababaraha parameter dina file konfigurasi. /etc/postgresql/12/main/postgresql.conf. Ngan pikeun ngamimitian anjeun kudu mastikeunyén euweuh setélan handap disetel ka sagala nilai séjén, ku kituna lamun konfigurasi ieu reloaded, DBMS teu ngadat. Anjeun tiasa nambihan parameter ieu nganggo:

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

Katerangan ngeunaan parameter anu bakal disetél:

  • wal_level - sabaraha inpormasi anu kedah ditulis dina log WAL, "replika" - nyerat sadayana;
  • arsip_mode - Aktipkeun undeuran log WAL nganggo paréntah tina parameter archive_command;
  • archive_command - paréntah pikeun ngarsipkeun log WAL anu réngsé;
  • archive_timeout - arsip log dilaksanakeun ngan nalika réngsé, tapi upami server anjeun robih / nambihan sakedik data kana pangkalan data, maka masuk akal pikeun netepkeun wates di dieu dina sababaraha detik, saatos éta paréntah arsip bakal disebat sacara paksa (Kuring nulis sacara intensif kana pangkalan data unggal detik, janten kuring mutuskeun henteu nyetél parameter ieu dina produksi);
  • restore_command - Paréntah pikeun mulangkeun log WAL tina cadangan bakal dianggo upami "cadangan lengkep" (cadangan dasar) teu aya parobihan pangénggalna dina pangkalan data.

Anjeun tiasa maca langkung seueur ngeunaan sadaya parameter ieu dina tarjamahan dokuméntasi resmi: https://postgrespro.ru/docs/postgresql/12/runtime-config-wal.

Nyetél jadwal cadangan

Naon waé anu dicarioskeun, cara anu paling merenah pikeun ngajalankeun éta nyaéta cron. Ieu naon urang bakal ngonpigurasikeun pikeun nyieun cadangan. Hayu urang mimitian ku paréntah pikeun nyieun cadangan pinuh: di wal-g ieu argumen peluncuran cadangan-nyorong. Tapi mimitina, éta langkung saé pikeun ngajalankeun paréntah ieu sacara manual ti pangguna postgres pikeun mastikeun sadayana henteu kunanaon (sareng teu aya kasalahan aksés):

#!/bin/bash

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

Argumen peluncuran nunjukkeun jalur ka diréktori data - Kuring ngingetan yén anjeun tiasa mendakanana ku jalan pg_lsclusters.

Upami sadayana henteu aya kasalahan sareng data dimuat kana panyimpenan S3, teras anjeun tiasa ngonpigurasikeun peluncuran périodik dina 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

Dina conto ieu, prosés cadangan dimimitian unggal dinten di 4:15 am.

Mupus cadangan heubeul

Paling dipikaresep, anjeun teu kedah nyimpen pancen sadaya cadangan ti jaman Mesozoic, jadi bakal mangpaat pikeun périodik "ngabersihan" gudang Anjeun (duanana "cadangan pinuh" na WAL log). Urang bakal ngalakukeun ieu sadayana ngaliwatan tugas 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 bakal ngajalankeun tugas ieu unggal dinten jam 6:30 am, mupus sadayana (cadangan lengkep, delta sareng WAL) kecuali salinan salami 10 dinten terakhir, tapi nyésakeun sahenteuna hiji cadangan. ka tanggal dieusian ku kituna sagala titik после tanggal anu kaasup dina PITR.

Malikkeun tina cadangan

Henteu aya rahasia yén konci pikeun pangkalan data anu séhat nyaéta restorasi périodik sareng verifikasi integritas data di jero. Kuring gé ngabejaan Anjeun kumaha cageur maké WAL-G dina bagian ieu, sarta kami bakal ngobrol ngeunaan cék engké.

Eta sia noting misah yén pikeun malikkeun dina lingkungan test (sagalana nu teu produksi) Anjeun kudu make hiji Read Only akun di S3 ku kituna teu ngahaja nimpa cadangan. Dina kasus WAL-G, anjeun kedah nyetél hak di handap ieu pikeun pangguna S3 dina Kabijakan Grup (Pangaruh: Ngidinan): s3: GetObject, s3: ListBucket, s3: GetBucketLocation. Sareng, tangtosna, ulah hilap nyetél archive_mode=pareum dina file setélan postgresql.conf, ku kituna database test anjeun teu hayang dicadangkeun quietly.

Restorasi dilumangsungkeun ku gerakan slight leungeun mupus sadaya data PostgreSQL (kaasup pangguna), janten punten ati-ati pisan nalika anjeun ngajalankeun paréntah di handap ieu.

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

Pikeun anu hoyong pariksa prosés pamulihan, sapotong leutik sihir bash parantos disiapkeun di handap, supados upami aya masalah dina pamulihan, naskah bakal nabrak sareng kode kaluar non-enol. Dina conto ieu, 120 cék dilakukeun kalayan waktos béakna 5 detik (jumlahna 10 menit kanggo pamulihan) pikeun terang naha file sinyalna dihapus (ieu hartosna pamulihan suksés):

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

Saatos recovery suksés, ulah poho pikeun ngamimitian sagala prosés deui (pgbouncer / monit, jsb).

Mariksa data sanggeus recovery

Penting pikeun pariksa integritas pangkalan data saatos restorasi, supados kaayaan anu rusak / cadangan bengkok henteu timbul. Sareng éta langkung saé pikeun ngalakukeun ieu sareng unggal arsip anu didamel, tapi dimana sareng kumaha ngan ukur gumantung kana imajinasi anjeun (anjeun tiasa ngangkat server individu dina unggal jam atanapi ngajalankeun cek di CI). Tapi sahenteuna, perlu pariksa data sareng indéks dina pangkalan data.

Pikeun mariksa data, cukup pikeun ngajalankeun éta ngaliwatan dump, tapi langkung saé nalika nyiptakeun pangkalan data anjeun parantos ngaktipkeun checksums (data checksums):

#!/bin/bash

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

Pikeun pariksa indéks - aya modul amcheck, hayu urang nyandak pamundut sql pikeun éta Tes WAL-G sareng ngawangun logika sakedik di sabudeureun éta:

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

Pikeun nyimpulkeun

Abdi hoyong nganyatakeun syukur ka Andrey Borodin pikeun pitulung na dina Nyiapkeun publikasi sarta hatur nuhun husus pikeun kontribusina pikeun ngembangkeun WAL-G!

Ieu menyimpulkan catetan ieu. Abdi ngarepkeun yén kuring tiasa ngémutan betah pangaturan sareng poténsi anu ageung pikeun ngagunakeun alat ieu di perusahaan anjeun. Kuring ngadéngé loba ngeunaan WAL-G, tapi teu kungsi cukup waktu pikeun diuk turun jeung angka eta kaluar. Sareng saatos kuring dilaksanakeun di bumi, tulisan ieu kaluar tina kuring.

Kapisah, éta patut dicatet yén WAL-G ogé tiasa dianggo sareng DBMS ieu:

sumber: www.habr.com

Tambahkeun komentar