Репликация сақтық көшірме емес. Немесе жоқ? Төте жолдарды кездейсоқ жою арқылы қалпына келтіру үшін жалқау репликацияны қалай қолдандық.
Репликация дерекқордың сақтық көшірмесін жасау құралы емес (gitlab-ce
Кешіктірілген көшірме арқылы біз деректерді небәрі 1,5 сағатта қалпына келтірдік. Қалай болғанын қараңыз.
PostgreSQL көмегімен уақытында қалпына келтіру
PostgreSQL-де дерекқордың күйін белгілі бір уақытқа қалпына келтіретін кірістірілген функция бар. деп аталады
Бұл мүмкіндікті суық сақтық көшірме жасау үшін пайдалану үшін біз жүйелі түрде базалық дерекқордың сақтық көшірмесін жасап, оны мұрағатта сақтаймыз (GitLab мұрағаттары мына жерде орналасқан).
Кешіктірілген репликация дегеніміз не?
Кешіктірілген репликация - кешігумен WAL өзгертулерін қолдану. Яғни, транзакция сағатта болды X
, бірақ ол кідіріспен репликада пайда болады d
сағатына X + d
.
PostgreSQL жүйесінде физикалық дерекқор репликасын орнатудың 2 жолы бар: мұрағатты қалпына келтіру және ағынды репликация.
Кешіктірілген сақтық көшірмені қалпына келтіруді қалай орнатуға болады
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'
Осы параметрлермен біз мұрағатты қалпына келтіруі бар кешіктірілген көшірмені конфигурацияладық. Мұнда қолданылған 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)
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;
}
Қорытындысы: кідіріс транзакцияны орындау уақыт белгісінде жазылған физикалық уақытқа негізделген (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
Мәліметтер базасы мемлекетке сол сәтсіз өтініштен бұрын келді. Енді сіз, мысалы, деректерді экспорттай аласыз. Біз қашықтағы жапсырма деректерін және мәселелер мен біріктіру сұрауларына барлық сілтемелерді экспорттадық және оларды өндіріс дерекқорына тасымалдадық. Егер жоғалтулар үлкен болса, сіз жай ғана көшірмені алға жылжытып, оны негізгі ретінде пайдалана аласыз. Бірақ содан кейін біз қалпына келтірілген сәттен кейін барлық өзгерістер жоғалады.
Уақыт белгілерінің орнына транзакция идентификаторларын қолданған дұрыс. Бұл идентификаторларды жазу пайдалы, мысалы, DDL мәлімдемелері үшін (мысалы DROP TABLE
), көмегімен log_statements = 'ddl'
. Егер бізде транзакция идентификаторы болса, біз қабылдайтын едік recovery_target_xid
және сұраудан бұрын транзакцияға дейін барлығын орындады DELETE
.
Жұмысқа қайта оралу өте қарапайым: барлық өзгерістерді алып тастаңыз recovery.conf
және postgres қайта іске қосыңыз. Жақында тағы да сегіз сағаттық кешігу болады және біз болашақ қиындықтарға дайынбыз.
Қалпына келтіру артықшылықтары
Кешіктірілген көшірмеде суық сақтық көшірменің орнына мұрағаттан бүкіл суретті қалпына келтіруге бірнеше сағат жұмсаудың қажеті жоқ. Мысалы, 2 ТБ негізгі резервтік көшірмені алу үшін бізге бес сағат қажет. Содан кейін сіз қалаған күйге (ең нашар жағдайда) қалпына келтіру үшін барлық күнделікті WAL қолдануыңыз керек.
Кешіктірілген көшірме суық сақтық көшірмеге қарағанда екі жолмен жақсырақ:
- Мұрағаттан негізгі сақтық көшірмені толығымен алудың қажеті жоқ.
- Қайталанатын WAL сегменттерінің бекітілген сегіз сағаттық терезесі бар.
Сондай-ақ, біз WAL-ды PITR-деуге болатын-болмайтынын үнемі тексеріп отырамыз және кешіктірілген көшірменің артта қалуын бақылау арқылы WAL мұрағатындағы сыбайлас жемқорлықты немесе басқа мәселелерді тез байқаймыз.
Бұл мысалда қалпына келтіру үшін бізге 50 минут қажет болды, яғни жылдамдығы сағатына 110 ГБ WAL деректерін құрады (мұрағат әлі қосулы болды)
Түйіндеме: кешіктірілген көшірме қай жерде пайдалы (және қайда емес)
Деректерді кездейсоқ жоғалтып алсаңыз және конфигурацияланған кідіріс ішінде бұл апатты байқасаңыз, алғашқы көмек ретінде кешіктірілген репликацияны пайдаланыңыз.
Бірақ есте сақтаңыз: репликация сақтық көшірме емес.
Сақтық көшірме мен репликацияның мақсаттары әртүрлі. Егер сіз кездейсоқ жасаған болсаңыз, суық сақтық көшірме пайдалы болады DELETE
немесе DROP TABLE
. Біз суық қоймадан сақтық көшірме жасаймыз және кестенің немесе бүкіл дерекқордың алдыңғы күйін қалпына келтіреміз. Бірақ сонымен бірге сұраныс DROP TABLE
жұмыс кластеріндегі барлық репликаларда бірден дерлік ойнатылады, сондықтан тұрақты репликация мұнда сақталмайды. Репликацияның өзі жеке серверлер жалға берілгенде дерекқорды қол жетімді етеді және жүктемені таратады.
Кешіктірілген көшірменің өзінде де, кенеттен деректер орталығының істен шығуы, жасырын зақымдану немесе сіз бірден байқамайтын басқа оқиғалар орын алса, бізге кейде қауіпсіз жерде сақтық көшірме қажет болады. Мұнда бір қайталаудың мағынасы жоқ.
ескерту. туралы
Ақпарат көзі: www.habr.com