Бид PostgreSQL-тэй гамшгийг сэргээхэд хойшлуулсан хуулбарыг хэрхэн ашигласан

Бид PostgreSQL-тэй гамшгийг сэргээхэд хойшлуулсан хуулбарыг хэрхэн ашигласан
Хуулбарлах нь нөөц биш юм. Эсвэл биш? Санамсаргүйгээр устгасан товчлолыг сэргээхийн тулд хойшлуулсан хуулбарыг хэрхэн ашигласан талаар эндээс үзнэ үү.

Дэд бүтцийн мэргэжилтнүүд GitLab нь ажлыг хариуцдаг GitLab.com - байгаль дээрх хамгийн том GitLab жишээ. 3 сая хэрэглэгчтэй, 7 сая орчим төсөлтэй, энэ нь тусгай архитектур бүхий хамгийн том нээлттэй эхийн SaaS сайтуудын нэг юм. PostgreSQL өгөгдлийн сангийн системгүйгээр GitLab.com-ын дэд бүтэц хол явахгүй бөгөөд өгөгдөл алдагдах үед алдаа гарсан тохиолдолд алдааг тэсвэрлэхийн тулд бид юу хийж байна. Ийм гамшиг тохиолдох нь юу л бол, гэхдээ бид маш сайн бэлтгэгдсэн бөгөөд янз бүрийн нөөц, хуулбарлах механизмаар нөөцөлсөн.

Хуулбарлах нь мэдээллийн санг нөөцлөх хэрэгсэл биш (доороос үзнэ үү). Харин одоо бид залхуу хуулбарыг ашиглан санамсаргүйгээр устгасан өгөгдлийг хэрхэн хурдан сэргээхийг харах болно: on GitLab.com хэрэглэгч товчлолыг устгасан төслийн хувьд gitlab-ce нэгтгэх хүсэлт, даалгавартай холбоо тасарсан.

Хойшлогдсон хуулбараар бид ердөө 1,5 цагийн дотор өгөгдлийг сэргээсэн. Энэ нь яаж болсныг хараарай.

PostgreSQL-ийн тусламжтай цагийг сэргээх

PostgreSQL нь өгөгдлийн сангийн төлөвийг тодорхой цаг хугацаанд сэргээдэг суурилуулсан функцтэй. гэж нэрлэдэг Цаг хугацаанд нь сэргээх (PITR) бөгөөд хуулбарыг шинэчилж байх ижил механизмуудыг ашигладаг: мэдээллийн сангийн бүх кластерын найдвартай агшин зургаас (суурь нөөцлөлт) эхлэн бид тодорхой хугацааны туршид хэд хэдэн төлөвийн өөрчлөлтийг хийдэг.

Энэ функцийг хүйтэн нөөцлөлтөд ашиглахын тулд бид мэдээллийн сангийн үндсэн нөөцлөлтийг тогтмол хийж, архивт хадгалдаг (GitLab архивууд Google үүл хадгалах сан). Бид мөн өгөгдлийн сангийн төлөвийн өөрчлөлтийг урьдчилан бичих бүртгэлийг архивлах замаар хянадаг (урьдчилан бичих бүртгэл, WAL). Мөн энэ бүхнийг бий болгосноор бид гамшгийн үед сэргээн засварлах PITR хийж болно: бүтэлгүйтэхээс өмнө авсан агшин зуурын зургаас эхлээд WAL архивын өөрчлөлтийг бүтэлгүйтэл хүртэл ашиглах.

Хойшлогдсон хуулбар гэж юу вэ?

Залхуу хуулбарлах нь WAL-ийн өөрчлөлтийг сааталтайгаар ашиглах явдал юм. Энэ нь нэг цагийн дотор гүйлгээ хийсэн гэсэн үг X, гэхдээ энэ нь сааталтай хуулбар дээр гарч ирнэ d нэг цагийн дотор X + d.

PostgreSQL нь өгөгдлийн сангийн физик хуулбарыг тохируулах 2 аргатай: нөөц сэргээх болон урсгал хуулбарлах. Архиваас сэргээж байна, үндсэндээ PITR шиг ажилладаг, гэхдээ тасралтгүй: бид WAL архиваас өөрчлөлтүүдийг байнга авч, хуулбарлахад ашигладаг. А урсгалын хуулбар дээд талын мэдээллийн сангийн хостоос WAL урсгалыг шууд татаж авдаг. Бид архивыг сэргээхийг илүүд үздэг - үүнийг удирдахад илүү хялбар бөгөөд үйлдвэрлэлийн кластерийг дагаж мөрддөг хэвийн ажиллагаатай.

Архиваас хойшлогдсон сэргээх ажиллагааг хэрхэн тохируулах вэ

Сэргээх сонголтууд файлд тодорхойлсон recovery.confБайна. Жишээ нь:

standby_mode = 'on'
restore_command = '/usr/bin/envdir /etc/wal-e.d/env /opt/wal-e/bin/wal-e wal-fetch -p 4 "%f" "%p"'
recovery_min_apply_delay = '8h'
recovery_target_timeline = 'latest'

Эдгээр параметрүүдийн тусламжтайгаар бид нөөц сэргээх боломжтой хойшлуулсан хуулбарыг тохируулсан. Энд үүнийг ашиглаж байна валь-э WAL сегментүүдийг задлах (restore_command) архиваас авах бөгөөд өөрчлөлтүүд найман цагийн дараа хэрэгжих болно (recovery_min_apply_delay). Хуулбар нь архив дахь цагийн хуваарийн өөрчлөлтийг ажиглах болно, жишээ нь кластерын бүтэлгүйтлийн улмаас (recovery_target_timeline).

С recovery_min_apply_delay Та урсгалын хуулбарыг сааталтайгаар тохируулж болно, гэхдээ энд хуулбарлах үүр, халуун зогсолтын санал хүсэлт гэх мэттэй холбоотой хэд хэдэн бэрхшээл бий. WAL архив нь эдгээрээс зайлсхийх боломжийг танд олгоно.

Үзүүлэлт recovery_min_apply_delay зөвхөн PostgreSQL 9.3 дээр гарсан. Өмнөх хувилбаруудад хойшлуулсан хуулбарлахын тулд та хослолыг тохируулах хэрэгтэй сэргээх удирдлагын функцууд (pg_xlog_replay_pause(), pg_xlog_replay_resume()) эсвэл WAL сегментүүдийг саатлын хугацаанд архивт хадгална.

PostgreSQL үүнийг хэрхэн хийдэг вэ?

PostgreSQL залхуу сэргээх аргыг хэрхэн хэрэгжүүлж байгааг харах нь сонирхолтой юм. Ингээд харцгаая recoveryApplyDelay(XlogReaderState). -аас дууддаг гол давталтын гогцоо WAL-ийн оруулга бүрийн хувьд.

static bool
recoveryApplyDelay(XLogReaderState *record)
{
    uint8       xact_info;
    TimestampTz xtime;
    long        secs;
    int         microsecs;

    /* nothing to do if no delay configured */
    if (recovery_min_apply_delay <= 0)
        return false;

    /* no delay is applied on a database not yet consistent */
    if (!reachedConsistency)
        return false;

    /*
     * Is it a COMMIT record?
     *
     * We deliberately choose not to delay aborts since they have no effect on
     * MVCC. We already allow replay of records that don't have a timestamp,
     * so there is already opportunity for issues caused by early conflicts on
     * standbys.
     */
    if (XLogRecGetRmid(record) != RM_XACT_ID)
        return false;

    xact_info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;

    if (xact_info != XLOG_XACT_COMMIT &&
        xact_info != XLOG_XACT_COMMIT_PREPARED)
        return false;

    if (!getRecordTimestamp(record, &xtime))
        return false;

    recoveryDelayUntilTime =
        TimestampTzPlusMilliseconds(xtime, recovery_min_apply_delay);

    /*
     * Exit without arming the latch if it's already past time to apply this
     * record
     */
    TimestampDifference(GetCurrentTimestamp(), recoveryDelayUntilTime,
                        &secs, &microsecs);
    if (secs <= 0 && microsecs <= 0)
        return false;

    while (true)
    {
        // Shortened:
        // Use WaitLatch until we reached recoveryDelayUntilTime
        // and then
        break;
    }
    return true;
}

Хамгийн гол нь саатал нь гүйлгээ хийх хугацааны тэмдэгт (xtime). Таны харж байгаагаар саатал нь зөвхөн амлалтад хамаарах бөгөөд бусад оруулгуудад нөлөөлөхгүй - бүх өөрчлөлтүүд шууд хэрэгжиж, үүрэг хойшлогдсон тул бид зөвхөн тохируулсан саатлын дараа өөрчлөлтийг харах болно.

Өгөгдлийг сэргээхийн тулд хойшлуулсан хуулбарыг хэрхэн ашиглах вэ

Бид өгөгдлийн сангийн кластер, үйлдвэрлэлийн найман цагийн хоцрогдолтой хуулбартай гэж бодъё. Жишээ ашиглан өгөгдлийг хэрхэн сэргээхийг харцгаая Товчлолыг санамсаргүйгээр устгах.

Асуудлын талаар олж мэдээд бид архивыг сэргээх ажлыг түр зогсоосон хойшлуулсан хуулбарын хувьд:

SELECT pg_xlog_replay_pause();

Түр зогссоноор хуулбар нь хүсэлтийг давтах эрсдэлгүй байсан DELETE. Бүх зүйлийг ойлгоход цаг хугацаа хэрэгтэй бол хэрэгтэй зүйл.

Гол нь хойшлуулсан хуулбар нь хүсэлт гаргахаас өмнөх мөчид хүрэх ёстой DELETE. Бид зайлуулах физик цагийг ойролцоогоор мэддэг байсан. Бид устгасан recovery_min_apply_delay мөн нэмсэн recovery_target_time в recovery.conf. Хуулбар нь ийм байдлаар цаг алдалгүй зөв мөчид хүрдэг:

recovery_target_time = '2018-10-12 09:25:00+00'

Цагийн тэмдэгтэй бол алдахгүйн тулд илүүдлийг багасгах нь дээр. Үнэн бол буурах тусам бид илүү их мэдээлэл алддаг. Дахин хэлэхэд, хэрэв бид хүсэлтийг орхигдуулсан бол DELETE, бүх зүйл дахин устах бөгөөд та дахин эхлүүлэх хэрэгтэй болно (эсвэл бүр PITR-д зориулж хүйтэн нөөцлөлт авах).

Бид хойшлогдсон Postgres жишээг дахин эхлүүлсэн бөгөөд WAL сегментүүд заасан цаг хүртэл давтагдсан. Та энэ үе шатанд ахиц дэвшлийг хянах боломжтой:

SELECT
  -- current location in WAL
  pg_last_xlog_replay_location(),
  -- current transaction timestamp (state of the replica)
  pg_last_xact_replay_timestamp(),
  -- current physical time
  now(),
  -- the amount of time still to be applied until recovery_target_time has been reached
  '2018-10-12 09:25:00+00'::timestamptz - pg_last_xact_replay_timestamp() as delay;

Хэрэв цагийн тэмдэг өөрчлөгдөхгүй бол сэргээх ажиллагаа дуусна. Үйлдлийг өөрчлөх боломжтой recovery_target_actionДахин оролдсоны дараа жишээг хаах, сурталчлах, түр зогсоох (энэ нь анхдагчаар түдгэлзүүлсэн).

Өгөгдлийн сан тэрхүү харамсалтай хүсэлтийн өмнөх байдалдаа буцаж ирэв. Одоо та жишээ нь өгөгдлийг экспортлох боломжтой. Бид устгасан шошгоны өгөгдөл болон асуудал, нэгтгэх хүсэлтийн бүх холбоосыг экспортолж, үйлдвэрлэлийн мэдээллийн сан руу шилжүүлсэн. Хэрэв алдагдал их байвал та хуулбарыг сурталчилж, гол зүйл болгон ашиглаж болно. Гэхдээ дараа нь бидний сэргээсэн цэгээс хойшхи бүх өөрчлөлтүүд алга болно.

Цагийн тэмдгийн оронд гүйлгээний ID ашиглах нь дээр. Эдгээр ID-г, жишээлбэл, DDL мэдэгдлийн хувьд (жишээ нь DROP TABLE), ашиглах замаар log_statements = 'ddl'. Хэрэв бид гүйлгээний үнэмлэхтэй байсан бол бид авах байсан recovery_target_xid мөн хүсэлтийн өмнө гүйлгээ хүртэлх бүх зүйлийг гүйлгэсэн DELETE.

Ажилдаа буцаж орох нь маш энгийн: бүх өөрчлөлтийг устгана уу recovery.conf болон Postgres-г дахин эхлүүлнэ үү. Хуулбар удахгүй дахин найман цагийн хоцрогдолтой байх бөгөөд бид ирээдүйн асуудалд бэлэн байна.

Сэргээх үр өгөөж

Хүйтэн нөөцлөхийн оронд хойшлуулсан хуулбарыг ашигласнаар архиваас зургийг бүхэлд нь сэргээхэд олон цаг зарцуулах шаардлагагүй болно. Жишээлбэл, 2 TB-ийн үндсэн нөөцийг бүхэлд нь авахад бид таван цаг зарцуулдаг. Дараа нь та хүссэн төлөвтөө (хамгийн муу тохиолдолд) сэргээхийн тулд өдөр тутмын WAL-ийг бүхэлд нь хэрэглэх шаардлагатай хэвээр байна.

Хойшлогдсон хуулбар нь хүйтэн нөөцөөс хоёр аргаар илүү дээр юм:

  1. Архиваас үндсэн нөөцлөлтийг бүхэлд нь устгах шаардлагагүй.
  2. Давтагдах ёстой WAL сегментүүдийн тогтсон найман цагийн цонх байдаг.

Бид мөн WAL-аас PITR хийх боломжтой эсэхийг байнга шалгадаг бөгөөд хойшлуулсан хуулбарын хоцролтыг хянах замаар WAL архивтай холбоотой авлига эсвэл бусад асуудлуудыг хурдан анзаарах болно.

Энэ жишээн дээр сэргээхэд 50 минут зарцуулсан бөгөөд энэ нь WAL дата/цагт 110 ГБ хурдтай байсан (архив асаалттай байсан) AWS S3). Нийтдээ бид асуудлыг шийдэж, өгөгдлийг 1,5 цагийн дотор сэргээсэн.

Үр дүн: хойшлуулсан хуулбар хаана хэрэгтэй вэ (мөн хаана ч хэрэггүй)

Хэрэв та санамсаргүйгээр мэдээллээ алдаж, тохируулсан саатал дотор энэ асуудлыг анзаарсан бол хойшлуулсан хуулбарыг анхны тусламж болгон ашиглаарай.

Гэхдээ санаж байгаарай: хуулбарлах нь нөөц биш юм.

Нөөцлөх болон хуулбарлах нь өөр өөр зорилготой. Хэрэв та санамсаргүйгээр хийсэн бол хүйтэн нөөцлөлт хэрэгтэй болно DELETE буюу DROP TABLE. Бид хүйтэн агуулахаас нөөцлөлт хийж, хүснэгтийн өмнөх төлөв эсвэл мэдээллийн баазыг бүхэлд нь сэргээдэг. Гэхдээ тэр үед хүсэлт DROP TABLE нь ажлын кластер дээрх бүх хуулбаруудад бараг шууд хуулбарлагддаг тул энгийн хуулбар нь энд тус болохгүй. Хувилбар нь бие даасан серверүүдийг түрээслэх үед мэдээллийн санг бэлэн байлгаж, ачааллыг хуваарилдаг.

Хойшлогдсон хуулбартай байсан ч бид заримдаа дата төвийн доголдол, далд гэмтэл эсвэл шууд анзаарагдахгүй бусад үйл явдал тохиолдвол аюулгүй газар нөөцлөх шаардлагатай болдог. Зөвхөн хуулбарлах нь энд ямар ч ашиггүй юм.

тайлбар. Дээр GitLab.com Бид одоогоор зөвхөн системийн түвшинд өгөгдөл алдагдахаас хамгаалж байгаа бөгөөд хэрэглэгчийн түвшинд өгөгдлийг сэргээхгүй байна.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх