Replikasiya ehtiyat deyil. Yoxsa yox? Qısayolların təsadüfən silinməsindən sonra bərpa etmək üçün təxirə salınmış replikasiyadan necə istifadə etdiyimiz budur.
Replikasiya verilənlər bazalarının ehtiyat nüsxəsini çıxarmaq vasitəsi deyil (gitlab-ce
Təxirə salınmış bir replika ilə məlumatları cəmi 1,5 saat ərzində bərpa etdik. Görün necə oldu.
PostgreSQL ilə vaxtı bərpa edin
PostgreSQL verilənlər bazasının vəziyyətini müəyyən bir zamana bərpa edən daxili funksiyaya malikdir. Bu adlanır
Soyuq ehtiyat nüsxə üçün bu funksiyadan istifadə etmək üçün biz müntəzəm olaraq baza verilənlər bazasının ehtiyat nüsxəsini çıxarırıq və onu arxivdə saxlayırıq (GitLab arxivləri burada yaşayır)
Təxirə salınmış replikasiya nədir?
Tənbəl təkrarlama WAL-dan dəyişikliklərin gecikmə ilə tətbiqidir. Yəni əməliyyat bir saat ərzində baş verib X
, lakin gecikmə ilə replikada görünəcək d
bir saata X + d
.
PostgreSQL-in fiziki verilənlər bazası replikasını qurmaq üçün 2 yolu var: ehtiyat nüsxəsinin bərpası və axın replikasiyası.
Arxivdən gecikmiş bərpanı necə qurmaq olar
recovery.conf
. Nümunə:
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'
Bu parametrlərlə biz ehtiyat bərpası ilə təxirə salınmış replikanı konfiqurasiya etdik. Burada istifadə olunur restore_command
) arxivdən və dəyişikliklər səkkiz saatdan sonra tətbiq olunacaq (recovery_min_apply_delay
). Replika arxivdə vaxt qrafiki dəyişikliklərini izləyəcək, məsələn, klaster uğursuzluğu (recovery_target_timeline
).
С recovery_min_apply_delay
Siz gecikmə ilə axın replikasiyasını qura bilərsiniz, lakin burada replikasiya yuvaları, isti gözləmə rejimində rəy və s. ilə əlaqəli bir neçə tələ var. WAL arxivi onlardan qaçmağa imkan verir.
Parametr recovery_min_apply_delay
yalnız PostgreSQL 9.3-də ortaya çıxdı. Əvvəlki versiyalarda təxirə salınmış təkrarlama üçün kombinasiyanı konfiqurasiya etməlisiniz pg_xlog_replay_pause(), pg_xlog_replay_resume()
) və ya gecikmə müddətində WAL seqmentlərini arxivdə saxlayın.
PostgreSQL bunu necə edir?
PostgreSQL-in tənbəl bərpanı necə həyata keçirdiyini görmək maraqlıdır. Gəlin baxaq recoveryApplyDelay(XlogReaderState)
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, µsecs);
if (secs <= 0 && microsecs <= 0)
return false;
while (true)
{
// Shortened:
// Use WaitLatch until we reached recoveryDelayUntilTime
// and then
break;
}
return true;
}
Nəticə odur ki, gecikmə əməliyyatın icrası vaxt möhüründə qeydə alınan fiziki vaxta əsaslanır (xtime
). Gördüyünüz kimi, gecikmə yalnız öhdəliklərə aiddir və digər qeydlərə təsir göstərmir - bütün dəyişikliklər birbaşa tətbiq edilir və öhdəlik gecikdirilir, buna görə də dəyişiklikləri yalnız konfiqurasiya edilmiş gecikmədən sonra görəcəyik.
Məlumatları bərpa etmək üçün gecikmiş replikadan necə istifadə etmək olar
Tutaq ki, bizim verilənlər bazası klasterimiz və istehsalda səkkiz saat gecikmə ilə replikamız var. Bir nümunədən istifadə edərək məlumatların necə bərpa olunacağına baxaq
Problemi öyrənəndə biz
SELECT pg_xlog_replay_pause();
Fasilə ilə replikanın sorğunu təkrarlayacağı riskimiz yox idi DELETE
. Hər şeyi anlamaq üçün vaxta ehtiyacınız varsa, faydalı bir şey.
Məsələ burasındadır ki, təxirə salınmış replika sorğudan əvvəlki ana çatmalıdır DELETE
. Biz fiziki olaraq çıxarılma vaxtını təxminən bilirdik. Biz sildik recovery_min_apply_delay
və əlavə etdi recovery_target_time
в recovery.conf
. Replika gecikmədən lazımi məqama belə çatır:
recovery_target_time = '2018-10-12 09:25:00+00'
Vaxt möhürləri ilə qaçırmamaq üçün artıqlığı azaltmaq daha yaxşıdır. Düzdür, azalma nə qədər çox olarsa, bir o qədər çox məlumat itiririk. Yenə xahişi qaçırsaq DELETE
, hər şey yenidən silinəcək və siz yenidən başlamalı olacaqsınız (və ya hətta PITR üçün soyuq ehtiyat nüsxəsini götürməlisiniz).
Biz təxirə salınmış Postgres instansiyasını yenidən işə saldıq və WAL seqmentləri göstərilən vaxta qədər təkrarlandı. Bu mərhələdəki inkişafı izləyə bilərsiniz:
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;
Vaxt damğası artıq dəyişməzsə, bərpa tamamlandı. Fəaliyyət fərdiləşdirilə bilər recovery_target_action
Verilənlər bazası bu uğursuz sorğudan əvvəl öz vəziyyətinə qayıtdı. İndi, məsələn, məlumatları ixrac edə bilərsiniz. Biz silinmiş etiket datasını və problemlərə və birləşmə sorğularına bütün keçidləri ixrac etdik və onları istehsal verilənlər bazasına köçürdük. Zərərlər böyük miqyaslıdırsa, sadəcə replikanı təbliğ edə və onu əsas kimi istifadə edə bilərsiniz. Ancaq sonra bərpa etdiyimiz nöqtədən sonra bütün dəyişikliklər itiriləcək.
Vaxt ştampları əvəzinə əməliyyat identifikatorlarından istifadə etmək daha yaxşıdır. Bu identifikatorları, məsələn, DDL ifadələri üçün qeyd etmək faydalıdır (məsələn DROP TABLE
), istifadə edərək log_statements = 'ddl'
. Əgər əməliyyat identifikatorumuz olsaydı, götürərdik recovery_target_xid
və sorğudan əvvəl əməliyyata qədər hər şeyi qaçırdı DELETE
.
İşə qayıtmaq çox sadədir: bütün dəyişiklikləri buradan silin recovery.conf
və Postgres-i yenidən başladın. Replikanın tezliklə yenidən səkkiz saat gecikməsi olacaq və biz gələcək çətinliklərə hazırıq.
Bərpa Faydaları
Soyuq ehtiyat nüsxəsi əvəzinə təxirə salınmış replika ilə bütün şəkli arxivdən bərpa etmək üçün saatlarla vaxt sərf etməli deyilsiniz. Məsələn, bütün əsas 2 TB ehtiyat nüsxəsini əldə etmək bizə beş saat çəkir. Və sonra istədiyiniz vəziyyətə qayıtmaq üçün bütün gündəlik WAL tətbiq etməlisiniz (ən pis halda).
Təxirə salınmış nüsxə iki cəhətdən soyuq ehtiyat nüsxəsindən daha yaxşıdır:
- Bütün əsas ehtiyat nüsxəsini arxivdən çıxarmağa ehtiyac yoxdur.
- Təkrarlanmalı olan WAL seqmentlərinin sabit səkkiz saatlıq pəncərəsi var.
Biz həmçinin WAL-dan PITR düzəltməyin mümkün olub-olmadığını yoxlamaq üçün mütəmadi olaraq yoxlayırıq və təxirə salınmış replikanın gecikməsinə nəzarət etməklə WAL arxivində korrupsiya və ya digər problemləri tez bir zamanda görərik.
Bu misalda bərpa etmək bizə 50 dəqiqə çəkdi, yəni sürət saatda 110 GB WAL datası idi (arxiv hələ də açıq idi)
Nəticələr: təxirə salınmış nüsxənin faydalı olduğu yerdə (və olmayan yerdə)
Təsadüfən məlumatları itirmisinizsə və bu problemi konfiqurasiya edilmiş gecikmə ərzində görmüsünüzsə, ilk yardım kimi gecikmiş replikasiyadan istifadə edin.
Ancaq unutmayın: replikasiya ehtiyat nüsxə deyil.
Yedəkləmə və təkrarlamanın müxtəlif məqsədləri var. Təsadüfən etsəniz, soyuq bir ehtiyat nüsxə faydalı olacaq DELETE
və ya DROP TABLE
. Biz soyuq anbardan ehtiyat nüsxəsini çıxarırıq və cədvəlin və ya bütün verilənlər bazasının əvvəlki vəziyyətini bərpa edirik. Amma eyni zamanda istək DROP TABLE
demək olar ki, dərhal işləyən klasterdəki bütün replikalarda təkrarlanır, ona görə də adi replikasiya burada kömək etməyəcək. Replikasiyanın özü fərdi serverlər icarəyə verildikdə verilənlər bazasını əlçatan saxlayır və yükü paylayır.
Təxirə salınmış replika ilə belə, məlumat mərkəzinin nasazlığı, gizli zədələnmə və ya dərhal nəzərə çarpmayan digər hadisələr baş verərsə, bəzən təhlükəsiz yerdə soyuq ehtiyat nüsxəsinə ehtiyacımız var. Təkcə təkrarlamanın burada heç bir faydası yoxdur.
Qeyd. Haqqında
Mənbə: www.habr.com