WAL-G: PostgreSQL DBMS جي بيڪ اپ ۽ بحالي

اهو ڊگهي عرصي کان معلوم ٿي چڪو آهي ته SQL ڊمپس ۾ بيڪ اپ ٺاهڻ (استعمال ڪندي pg_dump يا pg_dumpall) سٺو خيال ناهي. PostgreSQL DBMS کي بيڪ اپ ڪرڻ لاء، اهو بهتر آهي ته حڪم استعمال ڪريو pg_basebackup، جيڪو WAL لاگز جي بائنري ڪاپي ٺاهي ٿو. پر جڏهن توهان هڪ ڪاپي ٺاهڻ ۽ بحال ڪرڻ جي سڄي عمل جو مطالعو شروع ڪندا، توهان سمجهي ويندا ته توهان کي ڪم ڪرڻ لاءِ گهٽ ۾ گهٽ ٻه ٽي سائيڪلون لکڻ گهرجن ۽ نه ته توهان کي مٿي ۽ هيٺان ٻنهي ۾ درد پيدا ٿئي. مصيبت کي گھٽائڻ لاء، WAL-G ترقي ڪئي وئي.

وال-جي پوسٽ گري ايس ايس ايل ڊيٽابيسس کي بيڪ اپ ۽ بحال ڪرڻ لاءِ Go ۾ لکيل هڪ اوزار آهي (۽ تازو ئي MySQL/MariaDB، MongoDB ۽ FoundationDB). اهو Amazon S3 اسٽوريج (۽ analogues، مثال طور، Yandex Object Storage) سان گڏ ڪم ڪرڻ جي حمايت ڪري ٿو، انهي سان گڏ گوگل ڪلائوڊ اسٽوريج، Azure اسٽوريج، Swift Object Storage ۽ صرف فائل سسٽم سان. سڄو سيٽ اپ سادو قدمن تي اچي ٿو، پر حقيقت جي ڪري ته ان بابت آرٽيڪل انٽرنيٽ تي پکڙيل آهن، اتي ڪو به مڪمل دستياب ناهي ته ڪيئن ڪجي جنهن ۾ شروع کان ختم ٿيڻ تائين سڀني مرحلن کي شامل ڪيو وڃي (هبري تي ڪيترائي پوسٽون آهن، پر اتي ڪيترائي نقطا غائب آهن).

WAL-G: PostgreSQL DBMS جي بيڪ اپ ۽ بحالي

هي مضمون بنيادي طور تي منهنجي ڄاڻ کي منظم ڪرڻ لاءِ لکيو ويو هو. مان ڊي بي اي نه آهيان ۽ مان پاڻ کي عام ماڻهو جي ٻولي ۾ ڪٿي به اظهار ڪري سگهان ٿو، تنهنڪري ڪا به اصلاح ڀليڪار آهي!

الڳ الڳ، مان نوٽ ڪريان ٿو ته هيٺ ڏنل هر شيء لاڳاپيل آهي ۽ Ubuntu 12.3 تي PostgreSQL 18.04 لاءِ آزمائشي آهي، سڀني حڪمن کي لازمي طور تي عمل ڪيو وڃي هڪ مراعات يافته صارف جي طور تي.

تنصيب

هن آرٽيڪل لکڻ جي وقت، WAL-G جو مستحڪم نسخو آهي v0.2.15 (مارچ 2020). اھو اھو آھي جيڪو اسان استعمال ڪنداسين (پر جيڪڏھن توھان چاھيو ٿا اھو پاڻ ٺاھيو ماسٽر برانچ مان، پوءِ گيٿب مخزن وٽ ھن لاءِ سڀ ھدايتون آھن). ڊائون لوڊ ۽ انسٽال ڪرڻ لاء توهان کي ڪرڻو پوندو:

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

ان کان پوء، توهان کي ترتيب ڏيڻ جي ضرورت آهي WAL-G پهرين، ۽ پوء PostgreSQL پاڻ.

WAL-G ترتيب ڏيڻ

بيڪ اپ رکڻ جي مثال لاءِ، Amazon S3 استعمال ڪيو ويندو (ڇاڪاڻ ته اهو منهنجي سرور جي ويجهو آهي ۽ ان جو استعمال تمام سستو آهي). ان سان گڏ ڪم ڪرڻ لاء، توهان کي ضرورت آهي "s3 بالٽ" ۽ رسائي چابيون.

WAL-G بابت سڀ پوئين مضمون ماحوليات جي متغيرن کي استعمال ڪندي ترتيب ڏيڻ جو استعمال ڪيو، پر ھن رليز سان سيٽنگون واقع ٿي سگھن ٿيون .walg.json فائل پوسٽ گريس استعمال ڪندڙ جي گهر ڊاريڪٽري ۾. ان کي ٺاھڻ لاء، ھيٺ ڏنل بش اسڪرپٽ ھلايو:

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

مون کي سڀني پيراگرافن جي باري ۾ ٿورو وضاحت ڪرڻ ڏيو:

  • WALG_S3_PREFIX - توهان جي S3 بالٽ ڏانهن رستو جتي بيڪ اپ اپ لوڊ ڪيو ويندو (توهان يا ته روٽ يا فولڊر ڏانهن)؛
  • AWS_ACCESS_KEY_ID - ايس 3 ۾ رسائي چيڪ (ٽيسٽ سرور تي بحالي جي صورت ۾، انهن ڪنجين کي صرف پڙهڻ واري پاليسي هجڻ گهرجي! اهو وڌيڪ تفصيل سان بيان ڪيو ويو آهي سيڪشن ۾ وصولي تي.);
  • AWS_SECRET_ACCESS_KEY - S3 اسٽوريج ۾ ڳجهي چيڪ؛
  • WALG_COMPRESSION_METHOD - ڪمپريشن جو طريقو، اهو بهتر آهي ته بروٽلي استعمال ڪيو وڃي (ڇاڪاڻ ته هي فائنل سائيز ۽ کمپريشن / ڊيڪپريشن جي رفتار جي وچ ۾ گولڊن مطلب آهي)؛
  • WALG_DELTA_MAX_STEPS - مڪمل بيڪ اپ ٺاھڻ کان اڳ ”ڊيلٽا“ جو تعداد (اھي وقت بچائيندا آھن ۽ ڊائون لوڊ ٿيل ڊيٽا جي سائيز، پر بحاليءَ جي عمل کي ٿورڙو سست ڪري سگھن ٿا، تنھنڪري وڏي قدرن کي استعمال ڪرڻ جي صلاح نه آھي)؛
  • PGDATA - توھان جي ڊيٽابيس ڊيٽا سان ڊاريڪٽري ڏانھن رستو (توھان ڳولي سگھوٿا حڪم هلائڻ سان pg_lsclusters);
  • PGHOST - ڊيٽابيس سان ڳنڍڻ، مقامي بيڪ اپ سان ان کي يونڪس ساکٽ ذريعي ڪرڻ بهتر آهي جيئن هن مثال ۾.

ٻيا پيرا ميٽر دستاويز ۾ ڳولي سگهجن ٿا: https://github.com/wal-g/wal-g/blob/v0.2.15/PostgreSQL.md#configuration.

PostgreSQL ترتيب ڏيڻ

ڊيٽابيس جي اندر آرڪائيور لاءِ WAL لاگز کي ڪلائوڊ تي اپلوڊ ڪرڻ ۽ انهن کي بحال ڪرڻ لاءِ (جيڪڏهن ضروري هجي)، توهان کي ترتيب ڏيڻ واري فائل ۾ ڪيترائي پيرا ميٽر مقرر ڪرڻ گهرجن. /etc/postgresql/12/main/postgresql.conf. صرف شروعاتن لاءِ توهان کي پڪ ڪرڻ جي ضرورت آهيته هيٺ ڏنل سيٽنگن مان ڪنهن به ٻئي قدر تي مقرر نه ڪيو ويو آهي، تنهنڪري جڏهن ترتيب ٻيهر لوڊ ڪيو ويندو آهي، DBMS حادثو نه ٿيندو. توھان ھي استعمال ڪندي شامل ڪري سگھوٿا ھي پيٽرول:

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

مقرر ڪرڻ لاء پيراگراف جي وضاحت:

  • wal_level - WAL لاگز ۾ ڪيتري معلومات لکڻ لاءِ، ”ريپليڪا“ - سڀ ڪجھ لکو؛
  • archive_mode - پيراميٽر مان ڪمانڊ استعمال ڪندي WAL لاگز کي ڊائونلوڊ ڪرڻ کي فعال ڪريو archive_command;
  • archive_command - مڪمل ٿيل WAL لاگ آرڪائيو ڪرڻ لاء حڪم؛
  • archive_timeout - لاگس جي آرڪائيو صرف ان وقت ڪئي ويندي آهي جڏهن اهو مڪمل ٿئي ٿو، پر جيڪڏهن توهان جو سرور تبديل ڪري ٿو / ڊيٽابيس ۾ ٿورو ڊيٽا شامل ڪري ٿو، پوء اهو سمجھ ۾ اچي ٿو ته هتي سيڪنڊن ۾ هڪ حد مقرر ڪيو وڃي، جنهن کان پوء آرڪائيو ڪمانڊ کي زبردستي سڏيو ويندو (مان ڊيٽابيس تي هر سيڪنڊ کي شدت سان لکندو آهيان، تنهن ڪري مون فيصلو ڪيو ته هن پيٽرول کي پيداوار ۾ مقرر نه ڪيو وڃي);
  • بحال_ڪمانڊ - بيڪ اپ مان WAL لاگ کي بحال ڪرڻ لاءِ ڪمانڊ استعمال ڪيو ويندو جيڪڏھن ”مڪمل بيڪ اپ“ (بيس بيڪ اپ) ڊيٽابيس ۾ جديد تبديلين جي کوٽ آھي.

توهان سرڪاري دستاويز جي ترجمي ۾ انهن سڀني پيٽرولن بابت وڌيڪ پڙهي سگهو ٿا: https://postgrespro.ru/docs/postgresql/12/runtime-config-wal.

بيڪ اپ شيڊول کي ترتيب ڏيڻ

جيڪو ڪجھ به چئي سگھي ٿو، ان کي هلائڻ جو سڀ کان وڌيڪ آسان طريقو ڪرون آھي. اهو آهي جيڪو اسان ترتيب ڏينداسين بيڪ اپ ٺاهڻ لاءِ. اچو ته هڪ مڪمل بيڪ اپ ٺاهڻ لاء حڪم سان شروع ڪريو: wal-g ۾ هي لانچ دليل آهي بيڪ اپ-پش. پر پهرين، اهو بهتر آهي ته هن حڪم کي دستي طور تي هلائڻ لاء پوسٽ گريس استعمال ڪندڙ کي يقيني بڻائڻ لاء هر شيء ٺيڪ آهي (۽ رسائي جي غلطي ناهي):

#!/bin/bash

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

لانچ دلائل ڊيٽا ڊاريڪٽري ڏانهن رستو ڏيکاري ٿو - مان توهان کي ياد ڏيان ٿو ته توهان ان کي هلائي سگهو ٿا pg_lsclusters.

جيڪڏهن سڀ ڪجهه غلطين کان سواء ٿي ويو ۽ ڊيٽا S3 اسٽوريج ۾ لوڊ ڪئي وئي، ته پوء توهان ڪرنٽاب ۾ وقتي لانچ کي ترتيب ڏئي سگهو ٿا:

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

هن مثال ۾، بيڪ اپ عمل هر روز 4:15 تي شروع ٿئي ٿو.

پراڻي بيڪ اپ کي ختم ڪرڻ

گهڻو ڪري، توهان کي Mesozoic دور کان بلڪل سڀئي بيڪ اپ رکڻ جي ضرورت ناهي، تنهنڪري اهو وقتي طور تي توهان جي اسٽوريج کي "صاف" ڪرڻ لاء مفيد ٿيندو (ٻئي "مڪمل بيڪ اپ" ۽ وال لاگز). اسان اهو سڀ ڪجهه ڪرون ٽاسڪ ذريعي ڪنداسين:

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

ڪرون اهو ڪم هر روز صبح 6:30 تي هلائيندو، آخري 10 ڏينهن جي ڪاپين کانسواءِ هر شيءِ (مڪمل بيڪ اپ، ڊيلٽا ۽ والز) کي حذف ڪندي، پر گهٽ ۾ گهٽ هڪ بيڪ اپ ڇڏيندي ڪرڻ مخصوص تاريخ ته جيئن ڪنهن به نقطي после تاريخون PITR ۾ شامل ڪيون ويون.

بيڪ اپ مان بحالي

اهو ڪو راز ناهي ته هڪ صحتمند ڊيٽابيس جي ڪنجي آهي وقتي بحالي ۽ اندر اندر ڊيٽا جي سالميت جي تصديق. مان توهان کي ٻڌايان ٿو ته هن سيڪشن ۾ WAL-G استعمال ڪندي ڪيئن بحال ڪجي، ۽ اسان بعد ۾ چيڪن بابت ڳالهائينداسين.

ان کي الڳ الڳ نوٽ ڪيو وڃي جيڪو آزمائشي ماحول ۾ بحال ڪرڻ لاءِ (هر شي جيڪا پيداوار نه آهي) توهان کي S3 ۾ صرف پڙهڻ وارو اڪائونٽ استعمال ڪرڻ جي ضرورت آهي ته جيئن حادثاتي طور تي بيڪ اپ کي اوور رائٽ نه ڪيو وڃي. WAL-G جي صورت ۾، توھان کي ھيٺ ڏنل حقن کي سيٽ ڪرڻ جي ضرورت آھي S3 استعمال ڪندڙ گروپ پاليسي ۾ (اثر: اجازت ڏيو): s3: GetObject, s3: ListBucket, s3: GetBucket Location. ۽، يقينا، سيٽ ڪرڻ نه وساريو archive_mode = بند سيٽنگون فائل ۾ postgresql.conf، انهي ڪري ته توهان جو ٽيسٽ ڊيٽابيس خاموشي سان بيڪ اپ ٿيڻ نٿو چاهي.

بحالي هٿ جي معمولي حرڪت سان ڪيو ويندو آهي سڀ PostgreSQL ڊيٽا کي ختم ڪرڻ (استعمال ڪندڙن سميت)، تنھنڪري مھرباني ڪري ڏاڍا محتاط رھو جڏھن توھان ھيٺ ڏنل حڪم جاري ڪريو.

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

انهن لاءِ جيڪي وصولي جي عمل کي جانچڻ چاهين ٿا، هيٺ بش ميجڪ جو هڪ ننڍڙو ٽڪرو تيار ڪيو ويو آهي، ته جيئن وصولي ۾ مشڪلاتن جي صورت ۾، اسڪرپٽ هڪ غير صفر ايگزٽ ڪوڊ سان حادثو ٿي ويندو. هن مثال ۾، 120 چيڪ ڪيا ويا آهن 5 سيڪنڊن جي ٽائم آئوٽ سان (مجموعي طور تي 10 منٽ وصولي لاءِ) اهو معلوم ڪرڻ لاءِ ته ڇا سگنل فائل ڊهي وئي هئي (ان جو مطلب اهو ٿيندو ته بحالي ڪامياب هئي):

#!/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، وغيره).

وصولي کان پوء ڊيٽا چيڪ ڪرڻ

بحاليءَ کان پوءِ ڊيٽابيس جي سالميت کي جانچڻ لاءِ ضروري آهي، ته جيئن ٽٽل/ڪروڙيل بيڪ اپ واري صورتحال پيدا نه ٿئي. ۽ اهو بهتر آهي ته اهو هر هڪ ٺاهيل آرڪائيو سان ڪيو، پر ڪٿي ۽ ڪيئن منحصر آهي صرف توهان جي تخيل تي (توهان انفرادي سرور کي ڪلاڪ جي بنياد تي وڌائي سگهو ٿا يا سي آءِ ۾ چيڪ هلائي سگهو ٿا). پر گهٽ ۾ گهٽ، اهو ضروري آهي ته ڊيٽابيس ۾ ڊيٽا ۽ انڊيڪس چيڪ ڪريو.

ڊيٽا کي چيڪ ڪرڻ لاء، اهو ڪافي آهي ته ان کي ڊمپ ذريعي هلائڻ، پر اهو بهتر آهي ته ڊيٽابيس ٺاهيندي توهان چيڪسمس کي فعال ڪيو آهي (ڊيٽا جي چڪاس):

#!/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 بابت گهڻو ڪجهه ٻڌو، پر ويهڻ ۽ ان کي سمجهڻ لاءِ ڪڏهن به ڪافي وقت نه مليو. ۽ مون ان کي گهر ۾ لاڳو ڪرڻ کان پوء، هي مضمون مون کان ٻاهر آيو.

الڳ الڳ، اهو نوٽ ڪرڻ جي قابل آهي ته WAL-G پڻ هيٺين DBMS سان ڪم ڪري سگهي ٿو:

جو ذريعو: www.habr.com

تبصرو شامل ڪريو