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).

WAL-G: kākoʻo a me ka hoʻihoʻi ʻana o PostgreSQL DBMS

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:

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

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:

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

E wehewehe iki wau e pili ana i nā ʻāpana āpau:

  • 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.

Hiki ke loaʻa nā ʻāpana ʻē aʻe ma ka palapala: https://github.com/wal-g/wal-g/blob/v0.2.15/PostgreSQL.md#configuration.

Hoʻonohonoho i ka PostgreSQL

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:

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

ʻ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.

Hiki iā ʻoe ke heluhelu hou aʻe e pili ana i kēia mau ʻāpana āpau ma ka unuhi ʻana o ka palapala kūhelu: https://postgrespro.ru/docs/postgresql/12/runtime-config-wal.

Hoʻonohonoho i kahi papa hana hoʻihoʻi

ʻ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:

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

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:

Source: www.habr.com

Pākuʻi i ka manaʻo hoʻopuka