WAL-G: thaub qab thiab rov qab ntawm PostgreSQL DBMS
Nws tau ntev tau paub tias ua backups rau hauv SQL dumps (siv pg_dub los yog pg_dub) tsis yog ib lub tswv yim zoo. Txhawm rau thaub qab PostgreSQL DBMS, nws yog qhov zoo dua los siv cov lus txib pg_basebackup, uas ua rau binary luam ntawm WAL cav. Tab sis thaum koj pib kawm tag nrho cov txheej txheem ntawm kev tsim ib daim ntawv theej thiab rov kho dua, koj yuav nkag siab tias koj yuav tsum tau sau tsawg kawg ob peb lub tsheb kauj vab rau qhov no ua haujlwm thiab tsis ua rau koj mob ob sab saum toj thiab hauv qab. Txhawm rau txo kev txom nyem, WAL-G tau tsim.
WAL-G yog ib lub cuab yeej sau rau hauv Go rau thaub qab thiab rov kho PostgreSQL databases (thiab tsis ntev los no MySQL/MariaDB, MongoDB thiab FoundationDB). Nws txhawb kev ua haujlwm nrog Amazon S3 cia (thiab analogues, piv txwv li, Yandex Object Storage), nrog rau Google Cloud Storage, Azure Storage, Swift Object Storage thiab yooj yim nrog cov ntaub ntawv kaw lus. Tag nrho cov teeb tsa los mus rau cov kauj ruam yooj yim, tab sis vim qhov tseeb tias cov ntawv hais txog nws tau tawg thoob plaws hauv Is Taws Nem, tsis muaj qhov ua tiav phau ntawv qhia yuav ua li cas suav nrog tag nrho cov kauj ruam txij thaum pib mus txog qhov kawg (muaj ob peb nqe lus ntawm Habré, tab sis ntau lub ntsiab lus tsis nco qab lawm).
Kab lus no tau sau feem ntau los ua kom kuv txoj kev paub. Kuv tsis yog DBA thiab kuv tuaj yeem qhia kuv tus kheej hauv cov lus layman qhov chaw, yog li txais tos txhua qhov kev kho!
Cais, kuv nco ntsoov tias txhua yam hauv qab no yog qhov cuam tshuam thiab sim rau PostgreSQL 12.3 ntawm Ubuntu 18.04, tag nrho cov lus txib yuav tsum tau ua raws li tus neeg siv muaj cai.
chaw
Thaum lub sijhawm sau tsab xov xwm no, qhov ruaj khov version ntawm WAL-G yog v 0.2.15 (Lub Peb Hlis 2020). Nov yog qhov peb yuav siv (tab sis yog tias koj xav tsim nws tus kheej los ntawm tus tswv ceg, ces github repository muaj tag nrho cov lus qhia rau qhov no). Txhawm rau rub tawm thiab nruab koj yuav tsum ua:
archive_command - hais kom ua archiving ua tiav WAL cav;
archive_timeout - archiving ntawm cav yog ua tsuas yog thaum nws ua tiav, tab sis yog tias koj lub server hloov / ntxiv cov ntaub ntawv me me rau hauv cov ntaub ntawv, ces nws ua rau kev txiav txim siab los teeb tsa qhov kev txwv ntawm no hauv vib nas this, tom qab ntawd cov lus txib archiving yuav raug hu ua quab yuam (Kuv sau ntau heev rau cov ntaub ntawv txhua ob, yog li kuv txiav txim siab tsis teeb qhov ntsuas no hauv kev tsim khoom);
restore_command - cov lus txib kom rov qab WAL log los ntawm kev thaub qab yuav raug siv yog tias "tag nrho thaub qab" (piv txwv li thaub qab) tsis muaj qhov hloov pauv tshiab hauv cov ntaub ntawv.
Hauv qhov piv txwv no, cov txheej txheem thaub qab pib txhua hnub thaum 4:15 teev sawv ntxov.
Rho tawm cov thaub qab qub
Feem ntau, koj tsis tas yuav khaws tag nrho cov ntaub ntawv thaub qab los ntawm Mesozoic era, yog li nws yuav muaj txiaj ntsig zoo rau "ntxuav" koj qhov chaw cia (ob qho tib si "tag nrho thaub qab" thiab WAL cav). Peb yuav ua qhov no los ntawm kev ua haujlwm 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 yuav khiav txoj haujlwm no txhua hnub thaum 6:30 teev sawv ntxov, tshem tawm txhua yam (tag nrho cov thaub qab, deltas thiab WALs) tshwj tsis yog cov ntawv luam rau 10 hnub kawg, tab sis tawm tsawg kawg ib qho thaub qab rau tau teev hnub kom muaj qhov taw tes tom qab cov hnub tau suav nrog PITR.
Rov qab los ntawm thaub qab
Nws tsis pub leejtwg paub tias tus yuam sij rau cov ntaub ntawv noj qab haus huv yog kev kho dua tshiab thiab kev txheeb xyuas qhov tseeb ntawm cov ntaub ntawv sab hauv. Kuv yuav qhia koj yuav ua li cas rov qab siv WAL-G hauv ntu no, thiab peb yuav tham txog cov tshev tom qab.
Nws yog tsim nyog sau cia nyias uas yuav rov qab los rau hauv ib puag ncig kev sim (txhua yam uas tsis yog ntau lawm) koj yuav tsum siv tus lej nyeem nkaus xwb hauv S3 thiaj li tsis txhob yuam kev overwrite thaub qab. Nyob rau hauv rooj plaub ntawm WAL-G, koj yuav tsum tau teeb tsa cov cai hauv qab no rau tus neeg siv S3 hauv Pawg Txoj Cai (Cov nyhuv: Tso cai): s 3:twb, s3: lis, s3: GetBucketLocation. Thiab, ntawm chav kawm, tsis txhob hnov qab teeb archive_mode = tawm hauv cov ntaub ntawv teeb tsa postgresql.conf, kom koj cov ntaub ntawv xeem tsis xav tau thaub qab ntsiag to.
Kev kho dua tshiab yog ua nrog me ntsis txav ntawm tes tshem tag nrho PostgreSQL cov ntaub ntawv (nrog rau cov neeg siv), yog li thov ceev faj heev thaum koj khiav cov lus txib hauv qab no.
#!/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
Rau cov neeg uas xav mus xyuas cov txheej txheem rov qab, ib qho me me ntawm bash khawv koob tau npaj hauv qab no, yog li ntawd, yog tias muaj teeb meem hauv kev rov qab los, tsab ntawv yuav tsoo nrog qhov tsis yog xoom tawm code. Hauv qhov piv txwv no, 120 daim tshev raug ua nrog lub sijhawm ntawm 5 vib nas this (tag nrho ntawm 10 feeb rau kev rov qab) kom paub seb cov ntaub ntawv teeb liab puas raug tshem tawm (qhov no yuav txhais tau tias qhov kev rov qab ua tiav):
#!/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
Tom qab ua tiav rov qab zoo, tsis txhob hnov qab pib tag nrho cov txheej txheem rov qab (pgbouncer/monit, thiab lwm yam).
Xyuas cov ntaub ntawv tom qab rov qab
Nws yog ib qho tseem ceeb los xyuas qhov kev ncaj ncees ntawm cov ntaub ntawv tom qab kev kho dua tshiab, kom tsis txhob muaj qhov xwm txheej nrog cov thaub qab tawg / crooked tsis tshwm sim. Thiab nws yog qhov zoo dua los ua qhov no nrog txhua qhov tsim cov ntaub ntawv, tab sis qhov twg thiab yuav ua li cas nyob ntawm koj lub tswv yim nkaus xwb (koj tuaj yeem tsa tus neeg rau zaub mov hauv ib teev lossis khiav daim tshev hauv CI). Tab sis qhov tsawg kawg nkaus, nws yog ib qho tsim nyog los xyuas cov ntaub ntawv thiab cov indexes hauv cov ntaub ntawv.
#!/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