Replikatsioon ei ole varukoopia. Või mitte? Siit saate teada, kuidas me kasutasime edasilükatud replikatsiooni, et kogemata otseteede kustutamisest taastuda.
Replikatsioon ei ole vahend andmebaaside varundamiseks (gitlab-ce
Edasilükatud koopiaga taastasime andmed vaid 1,5 tunniga. Vaata, kuidas see juhtus.
Ajapunkti taastamine PostgreSQL-iga
PostgreSQL-il on sisseehitatud funktsioon, mis taastab andmebaasi oleku teatud ajahetkel. Seda nimetatakse
Selle funktsiooni kasutamiseks külmvarundamiseks teeme regulaarselt andmebaasi põhivarukoopia ja salvestame selle arhiivi (GitLabi arhiivid elavad
Mis on edasilükatud replikatsioon?
Laisk replikatsioon on WAL-i muudatuste rakendamine viivitusega. See tähendab, et tehing toimus tunniga X
, kuid see ilmub koopiasse viivitusega d
tunni pärast X + d
.
PostgreSQL-il on füüsilise andmebaasi koopia seadistamiseks kaks võimalust: varukoopia taastamine ja voogesituse replikatsioon.
Kuidas seadistada arhiivist viivitatud taastamist
recovery.conf
... Näide:
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'
Nende parameetritega konfigureerisime edasilükatud koopia koos varukoopia taastamisega. Siin seda kasutatakse restore_command
) arhiivist ja muudatused rakenduvad kaheksa tunni pärast (recovery_min_apply_delay
). Replika jälgib arhiivis ajaskaala muudatusi, näiteks klastri tõrkesiirde tõttu (recovery_target_timeline
).
С recovery_min_apply_delay
Saate seadistada voogesituse replikatsiooni viivitusega, kuid siin on paar lõksu, mis on seotud replikatsioonipesade, kuuma ooterežiimi tagasisidega ja nii edasi. WAL-i arhiiv võimaldab teil neid vältida.
Parameeter recovery_min_apply_delay
ilmus ainult PostgreSQL 9.3-s. Varasemates versioonides peate edasilükatud replikatsiooni jaoks kombinatsiooni konfigureerima pg_xlog_replay_pause(), pg_xlog_replay_resume()
) või hoidke WAL-i segmente viivituse ajaks arhiivis.
Kuidas PostgreSQL seda teeb?
Huvitav on näha, kuidas PostgreSQL rakendab laiska taastamist. Vaatame edasi 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;
}
Lõpptulemus on see, et viivitus põhineb füüsilisel ajal, mis on salvestatud tehingu sooritamise ajatemplisse (xtime
). Nagu näete, kehtib viivitus ainult sissekannete kohta ja ei mõjuta teisi kirjeid – kõik muudatused rakendatakse otse ja commit viibib, seega näeme muudatusi alles pärast seadistatud viivitust.
Kuidas kasutada andmete taastamiseks viivitatud koopiat
Oletame, et meil on andmebaasi klaster ja koopia, mille tootmise viivitus on kaheksa tundi. Vaatame, kuidas näite abil andmeid taastada
Kui saime probleemist teada
SELECT pg_xlog_replay_pause();
Pausi korral ei olnud meil ohtu, et koopia taotlust kordaks DELETE
. Kasulik asi, kui vajate aega, et kõike välja mõelda.
Asi on selles, et edasilükatud koopia peab jõudma päringueelsesse hetke DELETE
. Teadsime ligikaudselt eemaldamise füüsilist aega. Oleme kustutanud recovery_min_apply_delay
ja lisas recovery_target_time
в recovery.conf
. Nii jõuab koopia viivitamata õigele hetkele:
recovery_target_time = '2018-10-12 09:25:00+00'
Ajatemplitega on parem ülejääki vähendada, et mitte mööda minna. Tõsi, mida suurem on langus, seda rohkem andmeid kaotame. Jällegi, kui me jätame taotluse vahele DELETE
, kustutatakse kõik uuesti ja peate otsast alustama (või isegi PITR-i jaoks külma varukoopia tegema).
Taaskäivitasime edasilükatud Postgresi eksemplari ja WAL-i segmente korrati kuni määratud ajani. Selles etapis saate edenemist jälgida, küsides:
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;
Kui ajatempel enam ei muutu, on taastamine lõppenud. Tegevust saab kohandada recovery_target_action
Andmebaas naasis oma olekusse enne seda kahetsusväärset taotlust. Nüüd saate näiteks andmeid eksportida. Eksportisime kustutatud sildiandmed ja kõik probleemide ja liitmistaotluste lingid ning teisaldasime need tootmisandmebaasi. Kui kaod on suuremahulised, saate lihtsalt koopiat reklaamida ja kasutada seda peamisena. Kuid siis kaovad kõik muutused pärast seda punkti, milleni oleme taastunud.
Ajatemplite asemel on parem kasutada tehingu ID-sid. Kasulik on need ID-d salvestada näiteks DDL-i avalduste jaoks (nt DROP TABLE
), kasutades log_statements = 'ddl'
. Kui meil oleks tehingu ID, siis võtaksime recovery_target_xid
ja jooksis kõik tehinguni enne päringut DELETE
.
Tööle naasmine on väga lihtne: eemaldage kõik muudatused recovery.conf
ja taaskäivitage Postgres. Koopial on peagi taas kaheksatunnine viivitus ja me oleme tulevasteks probleemideks valmis.
Taastamise eelised
Külma varukoopia asemel edasilükatud koopiaga ei pea te kulutama tunde kogu pildi arhiivist taastamiseks. Näiteks kogu põhilise 2 TB varukoopia hankimiseks kulub meil viis tundi. Ja siis peate ikkagi rakendama kogu päeva WAL-i, et soovitud olekusse taastuda (halvimal juhul).
Edasilükatud koopia on parem kui külmvarukoopia kahel viisil.
- Kogu põhivarukoopiat pole vaja arhiivist eemaldada.
- Seal on fikseeritud kaheksatunnine WAL-segmentide aken, mida tuleb korrata.
Samuti kontrollime pidevalt, kas WAL-ist on võimalik PITR-i teha, ning me märkaksime kiiresti WAL-i arhiivi korruptsiooni või muid probleeme, jälgides edasilükatud koopia viivitust.
Selles näites kulus meil taastamiseks 50 minutit, mis tähendab, et kiirus oli 110 GB WAL-andmeid tunnis (arhiiv oli endiselt sisse lülitatud
Tulemused: kus edasilükatud koopia on kasulik (ja kus mitte)
Kasutage viivitatud replikatsiooni esmaabina, kui kaotasite kogemata andmed ja märkasite seda probleemi konfigureeritud viivituse jooksul.
Kuid pidage meeles: replikatsioon ei ole varukoopia.
Varundamisel ja replikatsioonil on erinevad eesmärgid. Külm varukoopia tuleb kasuks, kui selle kogemata tegite DELETE
või DROP TABLE
. Teeme külmhoidlast varukoopia ja taastame tabeli või kogu andmebaasi eelmise oleku. Aga samas palve DROP TABLE
reprodutseeritakse peaaegu kohe kõigis tööklastri koopiates, nii et tavaline replikatsioon siin ei aita. Replikatsioon ise hoiab andmebaasi kättesaadavana, kui üksikud serverid on maas, ja jaotab koormuse.
Isegi edasilükatud koopia puhul vajame mõnikord tõesti külma varukoopiat turvalises kohas, kui ilmnevad andmekeskuse rike, varjatud kahjustused või muud sündmused, mida pole kohe märgata. Ainuüksi replikatsioonist pole siin kasu.
Märkus. edasi
Allikas: www.habr.com