WAL-G: copïau wrth gefn ac adfer DBMS PostgreSQL

Mae wedi bod yn hysbys ers tro bod gwneud copïau wrth gefn i mewn i dympiau SQL (gan ddefnyddio tud_dymp neu pg_dumpall) ddim yn syniad da. I wneud copi wrth gefn o'r DBMS PostgreSQL, mae'n well defnyddio'r gorchymyn pg_basebackup, sy'n gwneud copi deuaidd o logiau WAL. Ond pan ddechreuwch astudio'r holl broses o greu copi ac adfer, byddwch yn deall bod angen i chi ysgrifennu o leiaf cwpl o feiciau tair olwyn er mwyn i hyn weithio a pheidio ag achosi poen i chi uwchben ac is. Er mwyn lleddfu dioddefaint, datblygwyd WAL-G.

WAL-G yn offeryn a ysgrifennwyd yn Go ar gyfer gwneud copïau wrth gefn ac adfer cronfeydd data PostgreSQL (ac yn fwy diweddar MySQL/MariaDB, MongoDB a FoundationDB). Mae'n cefnogi gweithio gyda storfa Amazon S3 (a analogau, er enghraifft, Yandex Object Storage), yn ogystal â Google Cloud Storage, Azure Storage, Swift Object Storage ac yn syml gyda'r system ffeiliau. Daw'r gosodiad cyfan i lawr i gamau syml, ond oherwydd y ffaith bod erthyglau amdano wedi'u gwasgaru ar draws y Rhyngrwyd, nid oes llawlyfr sut i wneud cyflawn a fyddai'n cynnwys yr holl gamau o'r dechrau i'r diwedd (mae yna sawl post ar Habré, ond collir llawer o bwyntiau yno).

WAL-G: copïau wrth gefn ac adfer DBMS PostgreSQL

Ysgrifennwyd yr erthygl hon yn bennaf i systemateiddio fy ngwybodaeth. Dydw i ddim yn DBA a gallaf fynegi fy hun yn iaith lleygwr yn rhywle, felly mae croeso i unrhyw gywiriadau!

Ar wahân, nodaf fod popeth isod yn berthnasol ac wedi'i brofi ar gyfer PostgreSQL 12.3 ar Ubuntu 18.04, rhaid gweithredu pob gorchymyn fel defnyddiwr breintiedig.

Gosod

Ar adeg ysgrifennu'r erthygl hon, y fersiwn sefydlog o WAL-G yw v0.2.15 (Mawrth 2020). Dyma beth fyddwn ni'n ei ddefnyddio (ond os ydych chi am ei adeiladu eich hun o'r brif gangen, yna mae gan y storfa github yr holl gyfarwyddiadau ar gyfer hyn). I lawrlwytho a gosod mae angen i chi wneud:

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

Ar ôl hyn, mae angen i chi ffurfweddu WAL-G yn gyntaf, ac yna PostgreSQL ei hun.

Sefydlu WAL-G

Er enghraifft o storio copïau wrth gefn, bydd Amazon S3 yn cael ei ddefnyddio (oherwydd ei fod yn agosach at fy gweinyddwyr ac mae ei ddefnydd yn rhad iawn). I weithio gydag ef, mae angen "bwced s3" ac allweddi mynediad.

Roedd pob erthygl flaenorol am WAL-G yn defnyddio cyfluniad gan ddefnyddio newidynnau amgylchedd, ond gyda'r datganiad hwn gellir lleoli'r gosodiadau ynddynt ffeil .walg.json yng nghyfeirlyfr cartref y defnyddiwr postgres. I'w greu, rhedwch y sgript bash ganlynol:

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

Gadewch imi egluro ychydig am yr holl baramedrau:

  • WALG_S3_PREFIX – y llwybr i'ch bwced S3 lle bydd copïau wrth gefn yn cael eu huwchlwytho (gallwch naill ai i'r gwraidd neu i ffolder);
  • AWS_ACCESS_KEY_ID – allwedd mynediad yn S3 (rhag ofn adferiad ar weinydd prawf, rhaid i'r allweddi hyn gael Polisi ReadOnly! Disgrifir hyn yn fanylach yn yr adran ar adferiad.);
  • AWS_SECRET_ACCESS_KEY – allwedd gyfrinachol yn storfa S3;
  • WALG_COMPRESSION_METHOD - dull cywasgu, mae'n well defnyddio Brotli (gan mai dyma'r cymedr euraidd rhwng y maint terfynol a'r cyflymder cywasgu / datgywasgu);
  • WALG_DELTA_MAX_STEPS – nifer y “deltas” cyn creu copi wrth gefn llawn (maent yn arbed amser a maint y data wedi'i lawrlwytho, ond gallant arafu ychydig ar y broses adfer, felly nid yw'n ddoeth defnyddio gwerthoedd mawr);
  • PGDATA - llwybr i'r cyfeiriadur gyda'ch data cronfa ddata (gallwch ddarganfod trwy redeg y gorchymyn pg_lsclusters);
  • PGHOST – cysylltu â'r gronfa ddata, gyda chopi wrth gefn lleol mae'n well ei wneud trwy unix-soced fel yn yr enghraifft hon.

Mae paramedrau eraill i'w gweld yn y ddogfennaeth: https://github.com/wal-g/wal-g/blob/v0.2.15/PostgreSQL.md#configuration.

Sefydlu PostgreSQL

Er mwyn i'r archifydd y tu mewn i'r gronfa ddata uwchlwytho logiau WAL i'r cwmwl a'u hadfer ohonynt (os oes angen), mae angen i chi osod sawl paramedr yn y ffeil ffurfweddu /etc/postgresql/12/main/postgresql.conf. Dim ond i ddechreuwyr mae angen i chi wneud yn siŵrnad yw'r un o'r gosodiadau isod wedi'u gosod i unrhyw werthoedd eraill, felly pan fydd y ffurfwedd yn cael ei ail-lwytho, nid yw'r DBMS yn chwalu. Gallwch ychwanegu'r paramedrau hyn gan ddefnyddio:

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

Disgrifiad o'r paramedrau i'w gosod:

  • wal_lefel – faint o wybodaeth i'w hysgrifennu mewn logiau CIY, “replica” – ysgrifennu popeth;
  • modd_archif – galluogi lawrlwytho logiau WAL gan ddefnyddio'r gorchymyn o'r paramedr gorchymyn_archif;
  • gorchymyn_archif – gorchymyn ar gyfer archifo log WAL wedi'i gwblhau;
  • goramser_archif - dim ond pan fydd wedi'i gwblhau y cynhelir archifo logiau, ond os yw'ch gweinydd yn newid / ychwanegu ychydig o ddata i'r gronfa ddata, yna mae'n gwneud synnwyr gosod terfyn yma mewn eiliadau, ac ar ôl hynny bydd y gorchymyn archifo yn cael ei alw'n rymus (Rwy'n ysgrifennu'n ddwys i'r gronfa ddata bob eiliad, felly penderfynais beidio â gosod y paramedr hwn wrth gynhyrchu);
  • gorchymyn_adfer – bydd y gorchymyn i adfer y log WAL o gopi wrth gefn yn cael ei ddefnyddio os nad oes gan y “copi wrth gefn llawn” (wrth gefn sylfaen) y newidiadau diweddaraf yn y gronfa ddata.

Gallwch ddarllen mwy am yr holl baramedrau hyn yn y cyfieithiad o'r ddogfennaeth swyddogol: https://postgrespro.ru/docs/postgresql/12/runtime-config-wal.

Sefydlu amserlen wrth gefn

Beth bynnag y bydd rhywun yn ei ddweud, y ffordd fwyaf cyfleus i'w redeg yw cron. Dyma beth fyddwn ni'n ei ffurfweddu i greu copïau wrth gefn. Gadewch i ni ddechrau gyda'r gorchymyn i greu copi wrth gefn llawn: yn wal-g dyma'r ddadl lansio wrth gefn-gwthio. Ond yn gyntaf, mae'n well rhedeg y gorchymyn hwn â llaw gan y defnyddiwr postgres i sicrhau bod popeth yn iawn (ac nid oes unrhyw wallau mynediad):

#!/bin/bash

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

Mae'r dadleuon lansio yn nodi'r llwybr i'r cyfeiriadur data - rwy'n eich atgoffa y gallwch chi ddod o hyd iddo trwy redeg pg_lsclusters.

Os aeth popeth heb wallau a bod y data wedi'i lwytho i storfa S3, yna gallwch chi ffurfweddu lansiad cyfnodol yn 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

Yn yr enghraifft hon, mae'r broses wrth gefn yn dechrau bob dydd am 4:15 am.

Dileu hen gopïau wrth gefn

Yn fwyaf tebygol, nid oes angen i chi gadw'r holl gopïau wrth gefn o'r oes Mesosöig yn llwyr, felly bydd yn ddefnyddiol “glanhau” eich storfa o bryd i'w gilydd ("copïau wrth gefn llawn" a logiau WAL). Byddwn yn gwneud hyn i gyd trwy dasg 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

Bydd Cron yn rhedeg y dasg hon bob dydd am 6:30 am, gan ddileu popeth (copïau wrth gefn llawn, deltas a WALs) ac eithrio copïau am y 10 diwrnod diwethaf, ond gan adael o leiaf un copi wrth gefn i dyddiad penodedig fel bod unrhyw bwynt ar ôl cynhwyswyd dyddiadau yn PITR.

Adfer o gefn

Nid yw'n gyfrinach mai'r allwedd i gronfa ddata iach yw adfer a gwirio cywirdeb y data y tu mewn o bryd i'w gilydd. Dywedaf wrthych sut i wella gan ddefnyddio WAL-G yn yr adran hon, a byddwn yn siarad am wiriadau yn nes ymlaen.

Mae'n werth nodi ar wahân er mwyn adfer mewn amgylchedd prawf (popeth nad yw'n gynhyrchu) mae angen i chi ddefnyddio cyfrif Darllen yn Unig yn S3 er mwyn peidio ag ysgrifennu copïau wrth gefn yn ddamweiniol. Yn achos WAL-G, mae angen i chi osod yr hawliau canlynol ar gyfer y defnyddiwr S3 ym Mholisi Grŵp (Effaith: Caniatáu): s3:GetObject, s3:Bwced Rhestr, s3:GetBucketLocation. Ac, wrth gwrs, peidiwch ag anghofio gosod archive_mode = i ffwrdd yn y ffeil gosodiadau postgresql.conf, fel nad yw eich cronfa ddata prawf eisiau cael ei ategu yn dawel.

Gwneir adferiad gyda symudiad bach yn y llaw dileu holl ddata PostgreSQL (gan gynnwys defnyddwyr), felly byddwch yn hynod ofalus pan fyddwch chi'n rhedeg y gorchmynion canlynol.

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

I'r rhai sydd am wirio'r broses adfer, mae darn bach o hud bash wedi'i baratoi isod, fel, rhag ofn y bydd problemau wrth adfer, bydd y sgript yn chwalu gyda chod ymadael di-sero. Yn yr enghraifft hon, gwneir 120 o wiriadau gydag amser allan o 5 eiliad (cyfanswm o 10 munud ar gyfer adferiad) i ddarganfod a gafodd y ffeil signal ei dileu (bydd hyn yn golygu bod yr adferiad yn llwyddiannus):

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

Ar ôl adferiad llwyddiannus, peidiwch ag anghofio cychwyn pob proses yn ôl (pgbouncer / monit, ac ati).

Gwirio data ar ôl adferiad

Mae'n hanfodol gwirio cywirdeb y gronfa ddata ar ôl ei hadfer, fel nad yw sefyllfa gyda chopi wrth gefn wedi torri/cam yn codi. Ac mae'n well gwneud hyn gyda phob archif a grëwyd, ond mae ble a sut yn dibynnu ar eich dychymyg yn unig (gallwch godi gweinyddwyr unigol fesul awr neu redeg siec yn CI). Ond o leiaf, mae angen gwirio'r data a'r mynegeion yn y gronfa ddata.

I wirio'r data, mae'n ddigon i'w redeg trwy ddymp, ond mae'n well bod siecsums wedi'u galluogi wrth greu'r gronfa ddata (gwiriadau data):

#!/bin/bash

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

I wirio mynegeion - yn bodoli modiwl amcheck, gadewch i ni gymryd yr ymholiad sql ar ei gyfer o Profion WAL-G ac adeiladu ychydig o resymeg o'i gwmpas:

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

I grynhoi

Hoffwn fynegi fy niolch i Andrey Borodin am ei gymorth wrth baratoi’r cyhoeddiad a diolch arbennig am ei gyfraniad i ddatblygiad WAL-G!

Mae hyn yn cloi'r nodyn hwn. Rwy'n gobeithio fy mod wedi gallu cyfleu pa mor hawdd yw sefydlu a'r potensial enfawr ar gyfer defnyddio'r offeryn hwn yn eich cwmni. Clywais lawer am WAL-G, ond ni chefais ddigon o amser i eistedd i lawr a'i ddarganfod. Ac ar ôl i mi ei weithredu gartref, daeth yr erthygl hon allan ohonof.

Ar wahân, mae'n werth nodi y gall WAL-G hefyd weithio gyda'r DBMS canlynol:

Ffynhonnell: hab.com

Ychwanegu sylw