ProHoster > Blog > Идораи > WAL-G: нусхабардорӣ ва барқарорсозии DBMS PostgreSQL
WAL-G: нусхабардорӣ ва барқарорсозии DBMS PostgreSQL
Кайҳо боз маълум аст, ки нусхабардорӣ ба партовҳои SQL (бо истифода аз pg_dump ё pg_dumpall) фикри хуб нест. Барои нусхабардории DBMS PostgreSQL, беҳтар аст, ки фармонро истифода баред pg_basebackup, ки нусхаи бинарии гузоришҳои WAL-ро месозад. Аммо вақте ки шумо ба омӯзиши тамоми раванди эҷоди нусхабардорӣ ва барқарорсозӣ шурӯъ мекунед, шумо хоҳед фаҳмид, ки шумо бояд ҳадди аққал як ду велосипедҳои сечархаро нависед, то ин кор кунад ва ҳам дар боло ва ҳам дар поён шуморо дард надиҳад. Барои сабук кардани ранҷу азоб, WAL-G таҳия карда шуд.
ВАЛ-Г асбобест, ки дар Go барои нусхабардорӣ ва барқарорсозии пойгоҳи додаҳои PostgreSQL навишта шудааст (ва ба наздикӣ MySQL/MariaDB, MongoDB ва FoundationDB). Он кор бо нигаҳдории Amazon S3 (ва аналогҳо, масалан, Yandex Object Storage), инчунин Google Cloud Storage, Azure Storage, Swift Object Storage ва танҳо бо системаи файлиро дастгирӣ мекунад. Тамоми танзимот ба қадамҳои оддӣ рост меояд, аммо аз сабаби он, ки мақолаҳо дар бораи он дар Интернет парокандаанд, дастури мукаммали тарзи кор вуҷуд надорад, ки тамоми қадамҳоро аз аввал то ба охир дар бар гирад (якчанд паёмҳо дар Habre, вале дар он чо бисьёр нуктахо аз даст дода шудаанд).
Ин мақола пеш аз ҳама барои ба низом даровардани донишҳои ман навишта шудааст. Ман DBA нестам ва ман метавонам худро дар ҷое бо забони оддӣ баён кунам, аз ин рӯ ҳама гуна ислоҳҳо хуш омадед!
#!/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 иҷро мекунад ва ҳама чизро (нусхаҳои пурра, делтаҳо ва WAL) нест мекунад, ба истиснои нусхаҳо дар 10 рӯзи охир, аммо ҳадди аққал як нусхаи эҳтиётӣ боқӣ мемонад. ба санаи муайян, то ки ягон нуқтаи после санаҳо ба PITR дохил карда шуданд.
Барқароркунӣ аз нусхабардорӣ
Ба касе пӯшида нест, ки калиди базаи солим ин барқарорсозии давравӣ ва тафтиши якпорчагии маълумот дар дохили он мебошад. Ман ба шумо мегӯям, ки чӣ тавр бо истифода аз WAL-G дар ин бахш барқарор карда шавад ва мо дар бораи чекҳо баъдтар сӯҳбат хоҳем кард.
#!/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
#!/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-ро барои он гирем Санҷишҳои 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 бисёр шунидам, аммо ҳеҷ гоҳ барои нишастан ва фаҳмидани он вақт надоштам. Ва пас аз он ки ман онро дар хона амалӣ кардам, ин мақола аз ман берун омад.