WAL-G: kākoʻo a me ka hoʻihoʻi ʻana o PostgreSQL DBMS
Ua ʻike lōʻihi ʻia ka hana ʻana i nā waihona i loko o SQL dumps (hoʻohana pg_puʻu ai ole ia, pg_dumpall) ʻaʻole maikaʻi ka manaʻo. No ke kākoʻo ʻana i ka PostgreSQL DBMS, ʻoi aku ka maikaʻi o ka hoʻohana ʻana i ke kauoha pg_basebackup, e hana ana i kope binary o nā moʻolelo WAL. Akā ke hoʻomaka ʻoe e aʻo i ke kaʻina holoʻokoʻa o ka hana ʻana i kahi kope a hoʻihoʻi, e hoʻomaopopo ʻoe he pono ʻoe e kākau i ʻelua mau kaʻa kaʻa no kēia hana a ʻaʻole e hōʻeha iā ʻoe ma luna a ma lalo. No ka hoʻohaʻahaʻa ʻana i ka ʻeha, ua kūkulu ʻia ʻo WAL-G.
WAL-G he mea hana i kākau ʻia ma Go no ke kākoʻo ʻana a me ka hoʻihoʻi ʻana i nā ʻikepili PostgreSQL (a me nā mea hou aku MySQL/MariaDB, MongoDB a me FoundationDB). Kākoʻo ia i ka hana ʻana me ka waihona Amazon S3 (a me nā analogues, no ka laʻana, Yandex Object Storage), a me Google Cloud Storage, Azure Storage, Swift Object Storage a me ka ʻōnaehana faila. Ke hele nei ka hoʻonohonoho holoʻokoʻa i nā ʻanuʻu maʻalahi, akā ma muli o ka hoʻopuehu ʻana o nā ʻatikala e pili ana iā ia ma ka Pūnaewele, ʻaʻohe kikoʻī pehea-i ka manual e hoʻokomo i nā ʻanuʻu āpau mai ka hoʻomaka a hiki i ka pau ʻana (he nui nā pou ma Habré, akā nui nā helu i hala ma laila).
Ua kākau mua ʻia kēia ʻatikala e hoʻonohonoho i koʻu ʻike. ʻAʻole wau he DBA a hiki iaʻu ke hōʻike iaʻu iho ma ka ʻōlelo a ka poʻe kamaʻāina ma kekahi wahi, no laila, ʻoluʻolu nā hoʻoponopono!
Ma kahi kaʻawale, ʻike wau e pili ana nā mea āpau ma lalo a hoʻāʻo ʻia no PostgreSQL 12.3 ma Ubuntu 18.04, pono e hoʻokō ʻia nā kauoha āpau ma ke ʻano he mea hoʻohana pono.
Kāu Mau Koho Paʻamau
I ka manawa e kākau ai i kēia ʻatikala, ʻo ka mana paʻa o WAL-G v0.2.15 (Malaki 2020). ʻO kēia kā mākou e hoʻohana ai (akā inā makemake ʻoe e kūkulu iā ʻoe iho mai ka lālā kumu, a laila aia ka waihona github i nā kuhikuhi āpau no kēia). No ka hoʻoiho a hoʻouka ʻana, pono ʻoe e hana:
Ma hope o kēia, pono ʻoe e hoʻonohonoho mua iā WAL-G, a laila PostgreSQL ponoʻī.
Hoʻonohonoho WAL-G
No ka laʻana o ka mālama ʻana i nā waihona, e hoʻohana ʻia ʻo Amazon S3 (no ka mea, ua kokoke loa ia i kaʻu mau kikowaena a ʻoi aku ka liʻiliʻi o kāna hoʻohana). No ka hana pū me ia, pono ʻoe i kahi "s3 bucket" a me nā kī komo.
Ua hoʻohana nā ʻatikala a pau e pili ana iā WAL-G i ka hoʻonohonoho ʻana me ka hoʻohana ʻana i nā ʻano hoʻololi kaiapuni, akā me kēia hoʻokuʻu ʻana hiki ke loaʻa nā hoʻonohonoho waihona .walg.json ma ka papa kuhikuhi home o ka mea hoʻohana postgres. No ka hana ʻana, e holo i kēia ʻatikala bash:
WALG_S3_PREFIX - ke ala i kāu bakeke S3 kahi e hoʻouka ʻia ai nā mea hoʻihoʻi (hiki iā ʻoe i ke kumu a i ʻole i kahi waihona);
AWS_ACCESS_KEY_ID - kī komo ma S3 (i ka hihia o ka hoʻihoʻi ʻana ma kahi kikowaena hoʻāʻo, pono e loaʻa i kēia mau kī ke kulekele ReadOnly! Ua wehewehe ʻia kēia ma ka ʻāpana o ka hoʻihoʻi.);
AWS_SECRET_ACCESS_KEY - kī huna i ka waihona S3;
WALG_COMPRESSION_METHOD - ʻoi aku ka maikaʻi o ka hoʻohana ʻana iā Brotli (no ka mea, ʻo ia ke kumu gula ma waena o ka nui hope a me ka wikiwiki o ka hoʻopiʻi / decompression);
WALG_DELTA_MAX_STEPS - ka helu o nā "deltas" ma mua o ka hana ʻana i kahi hoʻihoʻi piha (e mālama lākou i ka manawa a me ka nui o ka ʻikepili i hoʻoiho ʻia, akā hiki ke lohi iki i ke kaʻina hana hou, no laila ʻaʻole pono e hoʻohana i nā waiwai nui);
PGDATA - ala i ka papa kuhikuhi me kāu ʻikepili waihona (hiki iā ʻoe ke ʻike ma ka holo ʻana i ke kauoha pg_lsclusters);
PGHOST - e pili ana i ka waihona, me kahi waihona kūloko ʻoi aku ka maikaʻi o ka hana ʻana ma o kahi unix-socket e like me kēia hiʻohiʻona.
I mea e hoʻouka ai ka waihona i loko o ka waihona i nā logs WAL i ke ao a hoʻihoʻi iā lākou mai ia mau mea (inā pono), pono ʻoe e hoʻonohonoho i nā ʻāpana he nui i ka faila hoʻonohonoho. /etc/postgresql/12/main/postgresql.conf. No ka hoʻomaka wale nō pono ʻoe e hōʻoiaʻaʻole i hoʻonohonoho ʻia kekahi o nā hoʻonohonoho ma lalo nei i nā waiwai ʻē aʻe, no laila ke hoʻouka hou ʻia ka hoʻonohonoho ʻana, ʻaʻole e hāʻule ka DBMS. Hiki iā ʻoe ke hoʻohui i kēia mau ʻāpana me ka hoʻohana ʻana i:
ʻO ka wehewehe ʻana i nā ʻāpana e hoʻonohonoho ʻia:
wal_level - pehea ka nui o ka ʻike e kākau ai ma nā moʻolelo WAL, "replica" - kākau i nā mea āpau;
archive_mode - hiki iā ʻoe ke hoʻoiho i nā log WAL me ka hoʻohana ʻana i ke kauoha mai ka ʻāpana waihona_kauoha;
waihona_kauoha - kauoha no ka mālama ʻana i kahi log WAL i hoʻopau ʻia;
archive_timeout - hoʻopaʻa ʻia nā lāʻau i ka wā i hoʻopau ʻia ai, akā inā hoʻololi kāu kikowaena / hoʻohui i nā ʻikepili liʻiliʻi i ka waihona, a laila kūpono ke kau ʻana i kahi palena ma ʻaneʻi i kekona, a laila e kāhea ʻia ke kauoha archiving me ka ikaika (Ke kākau ikaika nei au i ka waihona i kēlā me kēia kekona, no laila ua hoʻoholo wau ʻaʻole e hoʻonohonoho i kēia ʻāpana i ka hana);
hoʻihoʻi_kauoha - e hoʻohana ʻia ke kauoha e hoʻihoʻi i ka log WAL mai kahi hoʻihoʻi inā loaʻa ka "backup piha" (base backup) i nā loli hou loa i ka waihona.
ʻO nā mea a pau e ʻōlelo ai, ʻo ke ala kūpono loa e holo ai ʻo cron. ʻO kēia ka mea a mākou e hoʻonohonoho ai e hana i nā backup. E hoʻomaka kākou me ke kauoha e hoʻokumu i kahi kākoʻo piha: ma wal-g kēia ka hoʻopaʻapaʻa hoʻomaka kākoʻo-paʻi. Akā ʻo ka mea mua, ʻoi aku ka maikaʻi o ka holo lima ʻana i kēia kauoha mai ka mea hoʻohana postgres e hōʻoia i ka maikaʻi o nā mea āpau (a ʻaʻohe hewa komo):
#!/bin/bash
su - postgres -c '/usr/local/bin/wal-g backup-push /var/lib/postgresql/12/main'
Hōʻike nā manaʻo hoʻomaka i ke ala i ka papa kuhikuhi data - Ke hoʻomanaʻo nei au iā ʻoe e hiki ke loaʻa iā ʻoe ma ka holo ʻana pg_lsclusters.
Inā hele nā mea āpau me ka hala ʻole a ua hoʻouka ʻia ka ʻikepili i ka waihona S3, a laila hiki iā ʻoe ke hoʻonohonoho i ka hoʻomaka ʻana i ka manawa ma crontab:
Ma kēia laʻana, hoʻomaka ke kaʻina hana hoʻihoʻi i kēlā me kēia lā ma 4:15 am.
Holoi i nā waihona kope kahiko
ʻO ka mea maʻamau, ʻaʻole pono ʻoe e mālama pono i nā backup āpau mai ka wā Mesozoic, no laila e pono ke "hoʻomaʻemaʻe" i kēlā me kēia manawa i kāu waihona (ʻo "nā waihona piha" a me nā log WAL). E hana mākou i kēia ma o kahi hana 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
E holo ʻo Cron i kēia hana i kēlā me kēia lā i ka hola 6:30 am, e holoi ana i nā mea āpau (nā waihona piha, nā deltas a me nā WAL) koe wale nā kope no nā lā 10 i hala, akā e waiho ana i hoʻokahi waihona. i luna lā i ʻōlelo ʻia i kēlā me kēia wahi mahope ua hoʻokomo ʻia nā lā ma PITR.
Hoʻihoʻi ʻia mai kahi waihona
ʻAʻole ia he mea huna ʻo ke kī i kahi waihona ʻikepili olakino ka hoʻihoʻi manawa a me ka hōʻoia ʻana i ka pono o ka ʻikepili i loko. E haʻi aku wau iā ʻoe pehea e hoʻōla ai me ka hoʻohana ʻana iā WAL-G i kēia ʻāpana, a e kamaʻilio mākou e pili ana i nā loiloi ma hope.
Pono e hoʻomaopopo pono e hoʻihoʻi i kahi ʻano hoʻāʻo (nā mea a pau ʻaʻole i hana ʻia) pono ʻoe e hoʻohana i kahi moʻohelu Heluhelu wale nō ma S3 i ʻole e hoʻopaʻa hewa i nā kope. Ma ka hihia o WAL-G, pono ʻoe e hoʻonohonoho i nā kuleana aʻe no ka mea hoʻohana S3 ma ka Group Policy (Ka hopena: ʻAe): s3:GetObject, s3:ListBucket, s3:GetBucketLocation. A, ʻoiaʻiʻo, mai poina e hoʻonohonoho archive_mode=off ma ka waihona hoʻonohonoho postgresql.conf, no laila ʻaʻole makemake kāu waihona hoʻāʻo e kākoʻo mālie ʻia.
Hana ʻia ka hoʻihoʻi ʻana me ka neʻe iki o ka lima e holoi ana i ka ʻikepili PostgreSQL (me nā mea hoʻohana), no laila e ʻoluʻolu e makaʻala loa ke holo ʻoe i kēia mau kauoha.
#!/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
No ka poʻe makemake e nānā i ke kaʻina hana hoʻihoʻi, ua hoʻomākaukau ʻia kahi ʻāpana liʻiliʻi o ka bash magic ma lalo nei, i mea e pilikia ai ka hoʻihoʻi ʻana, e hāʻule ka palapala me kahi code exit non-zero. Ma kēia hiʻohiʻona, hana ʻia nā māka 120 me ka manawa o 5 kekona (he 10 mau minuke no ka hoʻihoʻi ʻana) e ʻike ai inā ua holoi ʻia ka faila hōʻailona (ʻo ia ke ʻano o ka hoʻōla ʻana):
#!/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
Ma hope o ka hoʻihoʻi maikaʻi ʻana, mai poina e hoʻomaka i nā kaʻina hana āpau (pgbouncer/monit, etc.).
Ke nānā nei i ka ʻikepili ma hope o ka hoʻihoʻi ʻana
He mea nui e nānā i ka pono o ka waihona ma hope o ka hoʻihoʻi ʻana, i ʻole e kū mai kahi kūlana me kahi waihona haʻihaʻi / kekee. A ʻoi aku ka maikaʻi o ka hana ʻana i kēia me kēlā me kēia waihona i hana ʻia, akā ma hea a pehea e hilinaʻi wale ai i kou noʻonoʻo (hiki iā ʻoe ke hoʻokiʻekiʻe i nā kikowaena pākahi i kēlā me kēia hola a i ʻole e holo i kahi loiloi ma CI). Akā ma ka liʻiliʻi, pono e nānā i nā ʻikepili a me nā kuhikuhi i ka waihona.
No ka nānā ʻana i ka ʻikepili, lawa ka holo ʻana iā ia ma kahi dump, akā ʻoi aku ka maikaʻi i ka wā e hana ai i ka waihona ʻikepili i hoʻohana ʻia nā checksums (helu helu helu):
#!/bin/bash
if ! su - postgres -c 'pg_dumpall > /dev/null'
then
echo 'pg_dumpall failed'
exit 125
fi
No ka nānā 'ana i nā indexes - aia module amcheck, e lawe kāua i ka nīnau sql no ia mai Nā hoʻāʻo WAL-G a kūkulu i kahi loina liʻiliʻi a puni:
#!/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
E hōʻuluʻulu manaʻo
Makemake wau e haʻi aku i koʻu mahalo iā Andrey Borodin no kāna kōkua i ka hoʻomākaukau ʻana i ka hoʻolaha a me ka mahalo kūikawā no kāna kōkua i ka hoʻomohala ʻana o WAL-G!
Hoʻopau kēia i kēia memo. Manaʻo wau ua hiki iaʻu ke haʻi i ka maʻalahi o ka hoʻonohonoho ʻana a me ka mana nui no ka hoʻohana ʻana i kēia mea hana i kāu hui. Ua lohe au i nā mea he nui e pili ana i ka WAL-G, akā ʻaʻole lawa ka manawa e noho ai a noʻonoʻo. A ma hope o koʻu hoʻokō ʻana ma ka home, ua puka mai kēia ʻatikala mai oʻu aku.
Ma kahi kaʻawale, pono e hoʻomaopopo ʻia hiki iā WAL-G ke hana pū me kēia DBMS: