WAL-G: PostgreSQL DBMS-ийн нөөцлөлт ба сэргээх

SQL дамп руу нөөцлөлт хийх нь эрт дээр үеэс мэдэгдэж байсан ( pg_dump буюу pg_dumpall) тийм ч сайн санаа биш. PostgreSQL DBMS-ийг нөөцлөхийн тулд командыг ашиглах нь дээр pg_basebackup, энэ нь WAL бүртгэлийн хоёртын хуулбарыг хийдэг. Гэхдээ хуулбарыг бүтээх, сэргээх үйл явцыг бүхэлд нь судалж эхлэхэд та үүнийг ажиллахын тулд дор хаяж хоёр гурван дугуй бичих хэрэгтэй бөгөөд дээрээс болон доороо өвдөхгүй байх хэрэгтэй гэдгийг ойлгох болно. Зовлонг арилгахын тулд WAL-G боловсруулсан.

WAL-G PostgreSQL өгөгдлийн санг нөөцлөх, сэргээх зориулалттай Go программ дээр бичигдсэн хэрэгсэл юм (болон сүүлийн үед MySQL/MariaDB, MongoDB болон FoundationDB). Энэ нь Amazon S3 санах ойтой (мөн аналогууд, жишээлбэл, Yandex Object Storage), Google Cloud Storage, Azure Storage, Swift Object Storage болон зүгээр л файлын системтэй ажиллахыг дэмждэг. Бүхэл бүтэн тохиргоо нь энгийн алхамуудаас бүрддэг боловч энэ тухай нийтлэлүүд интернетээр тархсан тул эхнээс нь дуустал бүх алхмуудыг багтаасан бүрэн гарын авлага байхгүй байна (Habré дээр хэд хэдэн нийтлэл байдаг, гэхдээ тэнд олон оноо алдсан байна).

WAL-G: PostgreSQL DBMS-ийн нөөцлөлт ба сэргээх

Энэ нийтлэлийг миний мэдлэгийг системчлэх зорилгоор бичсэн. Би DBA биш бөгөөд хаа нэгтээ энгийн хүний ​​хэлээр өөрийгөө илэрхийлж чаддаг тул аливаа засварыг хийх боломжтой!

Доорх бүх зүйл хамааралтай бөгөөд Ubuntu 12.3 дээрх PostgreSQL 18.04-д туршиж үзсэн тул бүх тушаалуудыг давуу эрхтэй хэрэглэгчийн хувьд гүйцэтгэх ёстой гэдгийг тус тусад нь тэмдэглэж байна.

тохиргоо

Энэ нийтлэлийг бичиж байх үед WAL-G-ийн тогтвортой хувилбар нь юм v0.2.15 (2020 оны XNUMX-р сар). Үүнийг бид ашиглах болно (гэхдээ хэрэв та үүнийг мастер салбараас өөрөө бүтээхийг хүсвэл github репозитор нь үүнд зориулсан бүх зааварчилгаатай байна.). Татаж авах, суулгахын тулд та дараах зүйлийг хийх хэрэгтэй.

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

Үүний дараа та эхлээд WAL-G, дараа нь PostgreSQL-г өөрөө тохируулах хэрэгтэй.

WAL-G-г тохируулж байна

Нөөцлөлтийг хадгалах жишээнд Amazon S3 ашиглах болно (Учир нь энэ нь миний серверүүдтэй ойр, хэрэглээ нь маш хямд байдаг). Үүнтэй ажиллахын тулд танд "s3 хувин" болон нэвтрэх түлхүүр хэрэгтэй.

WAL-G-ийн талаарх өмнөх бүх нийтлэлүүд нь орчны хувьсагчдыг ашиглан тохиргоог ашигласан боловч энэ хувилбарт тохиргоог дараах хэсэгт байрлуулж болно. .walg.json файл postgres хэрэглэгчийн гэрийн лавлахад. Үүнийг үүсгэхийн тулд дараах bash скриптийг ажиллуулна уу:

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

Бүх параметрийн талаар бага зэрэг тайлбарлая:

  • WALG_S3_PREFIX – нөөцлөлтүүдийг байршуулах таны S3 хувин руу хүрэх зам (та үндсэн эсвэл хавтас руу орж болно);
  • AWS_ACCESS_KEY_ID - S3 дахь хандалтын түлхүүр (Туршилтын сервер дээр сэргээх тохиолдолд эдгээр түлхүүрүүд зөвхөн унших бодлоготой байх ёстой! Үүнийг сэргээх хэсэгт илүү дэлгэрэнгүй тайлбарласан болно.);
  • AWS_SECRET_ACCESS_KEY - S3 санах ойн нууц түлхүүр;
  • WALG_COMPRESSION_METHOD – шахалтын арга, Brotli ашиглах нь илүү дээр юм (энэ нь эцсийн хэмжээ болон шахалт / задлах хурдны хоорондох алтан дундаж юм);
  • WALG_DELTA_MAX_STEPS - бүрэн нөөцлөлт үүсгэхээс өмнө "дельта" -ын тоо (тэдгээр нь цаг хугацаа, татаж авсан өгөгдлийн хэмжээг хэмнэдэг боловч сэргээх үйл явцыг бага зэрэг удаашруулдаг тул их хэмжээний утгыг ашиглахыг зөвлөдөггүй);
  • PGDATA – өгөгдлийн сангийн өгөгдөл бүхий лавлах руу очих зам (командыг ажиллуулснаар олж мэдэх боломжтой pg_lsclusters);
  • PGHOST – өгөгдлийн сантай холбогдож, дотоод нөөцлөлттэй бол энэ жишээн дээрх шиг unix-сокетоор дамжуулан хийх нь дээр.

Бусад параметрүүдийг баримтаас олж болно: https://github.com/wal-g/wal-g/blob/v0.2.15/PostgreSQL.md#configuration.

PostgreSQL-г тохируулж байна

Өгөгдлийн сангийн архивлагч нь WAL бүртгэлийг үүлэн дээр байршуулж, тэдгээрээс сэргээхийн тулд (шаардлагатай бол) тохиргооны файлд хэд хэдэн параметрүүдийг тохируулах шаардлагатай. /etc/postgresql/12/main/postgresql.conf. Зөвхөн эхлэгчдэд зориулсан та баталгаажуулах хэрэгтэйДоорх тохиргоонуудын аль нь ч өөр утгад тохируулагдаагүй тул тохиргоог дахин ачаалах үед DBMS гацахгүй. Та эдгээр параметрүүдийг ашиглан нэмж болно:

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

Тохируулах параметрүүдийн тайлбар:

  • wal_level – WAL бүртгэлд хэр их мэдээлэл бичих, “хуулбарлах” – бүгдийг бичих;
  • архивын_горим – параметрийн командыг ашиглан WAL бүртгэлийг татаж авахыг идэвхжүүлнэ архивлах_команд;
  • архивлах_команд – дууссан WAL бүртгэлийг архивлах команд;
  • архивын_хугацаа – Бүртгэлийг архивлаж дууссаны дараа л хийгдэнэ, гэхдээ хэрэв таны сервер өгөгдлийн санд бага зэрэг өгөгдөл нэмбэл/өөрчлүүлбэл энд хэдхэн секундын дотор хязгаар тогтоох нь зүйтэй бөгөөд үүний дараа архивлах командыг албадан дуудах болно (Би мэдээллийн санд секунд тутамд эрчимтэй бичдэг тул энэ параметрийг үйлдвэрлэлд тохируулахгүй байхаар шийдсэн);
  • сэргээх_команд – “Бүрэн нөөцлөлт” (үндсэн нөөц)-д мэдээллийн санд хамгийн сүүлийн өөрчлөлт байхгүй тохиолдолд WAL бүртгэлийг нөөцөөс сэргээх командыг ашиглана.

Та эдгээр бүх параметрүүдийн талаар албан ёсны баримт бичгийн орчуулгаас уншиж болно. https://postgrespro.ru/docs/postgresql/12/runtime-config-wal.

Нөөц хуваарийг тохируулж байна

Юу ч хэлж байсан, үүнийг ажиллуулах хамгийн тохиромжтой арга бол cron юм. Үүнийг бид нөөцлөлт үүсгэхийн тулд тохируулах болно. Бүрэн нөөцлөлт үүсгэх командаас эхэлцгээе: wal-g-д энэ нь эхлүүлэх аргумент юм нөөцлөх-түлхэх. Гэхдээ эхлээд бүх зүйл хэвийн байгаа эсэхийг шалгахын тулд postgres хэрэглэгчээс энэ тушаалыг гараар ажиллуулах нь дээр (мөн хандалтын алдаа байхгүй):

#!/bin/bash

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

Эхлэх аргументууд нь өгөгдлийн лавлах замыг зааж өгдөг - та үүнийг ажиллуулснаар олж мэдэх боломжтой гэдгийг би танд сануулж байна pg_lsclusters.

Хэрэв бүх зүйл алдаагүй болж, өгөгдлийг S3 санах ойд ачаалсан бол 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

Энэ жишээнд нөөцлөх үйл явц өдөр бүр өглөөний 4:15 цагт эхэлдэг.

Хуучин нөөцлөлтүүдийг устгаж байна

Магадгүй та мезозойн эрин үеийн бүх нөөц хуулбарыг хадгалах шаардлагагүй тул хадгалах санг үе үе "цэвэрлэх" нь ашигтай байх болно ("бүрэн нөөцлөлт" болон WAL бүртгэлүүд). Бид үүнийг 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 энэ ажлыг өдөр бүр өглөөний 6:30 цагт гүйцэтгэх бөгөөд сүүлийн 10 хоногийн хуулбараас бусад бүх зүйлийг (бүрэн нөөцлөлт, дельта болон WAL) устгах боловч дор хаяж нэг нөөцлөлт үлдээх болно. нь тодорхой огноо, ингэснээр ямар ч цэг после огноог PITR-д оруулсан болно.

Нөөцлөлтөөс сэргээж байна

Эрүүл мэдээллийн сангийн гол түлхүүр нь доторх мэдээллийн бүрэн бүтэн байдлыг үе үе сэргээж, баталгаажуулах явдал байдаг нь нууц биш. Би энэ хэсэгт WAL-G ашиглан хэрхэн сэргээх талаар танд хэлэх бөгөөд дараа нь шалгалтын талаар ярих болно.

Үүнийг тусад нь тэмдэглэх хэрэгтэй Туршилтын орчинд (үйлдвэрлэлгүй бүх зүйлийг) сэргээхийн тулд нөөцлөлтийг санамсаргүйгээр дарж бичихгүйн тулд S3-д Зөвхөн унших бүртгэлийг ашиглах хэрэгтэй. WAL-G-ийн хувьд та S3 хэрэглэгчдэд дараах эрхийг Бүлгийн бодлогод тохируулах хэрэгтэй (Үр нөлөө: Зөвшөөрөх): s3: GetObject, s3: ListBucket, s3: GetBucketLocation. Мэдээжийн хэрэг, тохируулахаа бүү мартаарай архивын_горим=унтраах тохиргооны файлд postgresql.conf, ингэснээр таны тестийн мэдээллийн сан чимээгүйхэн нөөцлөхийг хүсэхгүй байна.

Сэргээх ажлыг гарны бага зэрэг хөдөлгөөнөөр хийдэг бүх PostgreSQL өгөгдлийг устгах (хэрэглэгчдийг оруулаад) тул дараах тушаалуудыг ажиллуулахдаа маш болгоомжтой байгаарай.

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

Сэргээх үйл явцыг шалгахыг хүссэн хүмүүст зориулж bash ид шидийн жижиг хэсгийг доороос бэлтгэсэн бөгөөд ингэснээр сэргээхэд асуудал гарсан тохиолдолд скрипт нь тэгээс өөр гарах кодоор гацах болно. Энэ жишээнд дохионы файл устгагдсан эсэхийг мэдэхийн тулд 120 секундын хугацаатай (нөхөн сэргээхэд нийт 5 минут) 10 шалгалт хийсэн (энэ нь сэргээх амжилттай болсон гэсэн үг юм):

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

Амжилттай сэргэсний дараа бүх процессыг буцааж эхлүүлэхээ бүү мартаарай (pgbouncer/monit гэх мэт).

Сэргээх дараа өгөгдлийг шалгаж байна

Сэргээгдсэний дараа мэдээллийн сангийн бүрэн бүтэн байдлыг шалгах нь зайлшгүй шаардлагатай бөгөөд ингэснээр эвдэрсэн/тахир нөөцтэй нөхцөл байдал үүсэхгүй. Үүнийг үүсгэсэн архив бүрээр хийх нь илүү дээр юм, гэхдээ хаана, хэрхэн хийх нь зөвхөн таны төсөөллөөс хамаарна (та тусдаа серверүүдийг цаг тутамд өсгөх эсвэл CI-д шалгалт хийх боломжтой). Гэхдээ хамгийн багадаа мэдээллийн сан дахь өгөгдөл, индексийг шалгах шаардлагатай.

Өгөгдлийг шалгахын тулд үүнийг дампаар ажиллуулахад хангалттай, гэхдээ мэдээллийн бааз үүсгэхдээ шалгах нийлбэрийг идэвхжүүлсэн нь дээр.өгөгдлийн хяналтын нийлбэр):

#!/bin/bash

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

Индекс шалгахын тулд - байгаа amcheck модуль, үүний sql query-г авч үзье WAL-G тестүүд мөн түүний эргэн тойронд бага зэрэг логик бий болго:

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

Нэгтгэн дүгнэхэд

Би хэвлэлийг бэлтгэхэд тусалсан Андрей Бородинд талархал илэрхийлж, WAL-G-ийг хөгжүүлэхэд оруулсан хувь нэмэрт онцгой талархал илэрхийлье!

Энэ тэмдэглэлийг дуусгаж байна. Танай компанид энэ хэрэгслийг ашиглахад хялбар, ашиглах боломжийн талаар би хэлж чадсан гэж найдаж байна. Би WAL-G-ийн талаар зөндөө сонссон ч үүнийг олж мэдэхэд хангалттай цаг байгаагүй. Тэгээд гэртээ хэрэгжүүлсний дараа энэ нийтлэл надаас гарсан.

WAL-G нь дараахь DBMS-тэй ажиллах боломжтой гэдгийг тусад нь тэмдэглэх нь зүйтэй.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх