Replikacija nije sigurnosna kopija. Ili ne? Evo kako smo koristili odgođenu replikaciju za oporavak od slučajnog brisanja prečaca.
Replikacija nije sredstvo sigurnosne kopije baza podataka (gitlab-ce
S odgođenom replikom vratili smo podatke za samo 1,5 sat. Pogledajte kako se to dogodilo.
Oporavak točke u vremenu uz PostgreSQL
PostgreSQL ima ugrađenu funkciju koja vraća stanje baze podataka u određeno vrijeme. To se zove
Da bismo koristili ovu značajku za hladno sigurnosno kopiranje, redovito izrađujemo osnovnu sigurnosnu kopiju baze podataka i pohranjujemo je u arhivu (GitLab arhive žive u
Što je odgođena replikacija?
Lijena replikacija je primjena promjena iz WAL-a s odgodom. Odnosno, transakcija se dogodila za sat vremena X
, ali će se u replici pojaviti s odgodom d
za sat vremena X + d
.
PostgreSQL ima 2 načina za postavljanje fizičke replike baze podataka: oporavak sigurnosne kopije i strujanje replikacije.
Kako postaviti odgođeni oporavak iz arhive
recovery.conf
, Primjer:
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'
S ovim smo parametrima konfigurirali odgođenu repliku s oporavkom sigurnosne kopije. Ovdje se koristi restore_command
) iz arhive, a promjene će biti primijenjene nakon osam sati (recovery_min_apply_delay
). Replika će paziti na promjene vremenske trake u arhivi, na primjer zbog prestanka rada klastera (recovery_target_timeline
).
С recovery_min_apply_delay
Možete postaviti strujanje replikacije s odgodom, ali ovdje postoji nekoliko zamki koje se odnose na utore za replikaciju, povratne informacije o vrućem stanju pripravnosti i tako dalje. WAL arhiva omogućuje vam da ih izbjegnete.
Parametar recovery_min_apply_delay
pojavio se tek u PostgreSQL 9.3. U prethodnim verzijama, za odgođenu replikaciju trebate konfigurirati kombinaciju pg_xlog_replay_pause(), pg_xlog_replay_resume()
) ili držite WAL segmente u arhivi tijekom trajanja odgode.
Kako PostgreSQL to radi?
Zanimljivo je vidjeti kako PostgreSQL implementira lijeni oporavak. Pogledajmo 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;
}
Zaključak je da se odgoda temelji na fizičkom vremenu zabilježenom u vremenskoj oznaci izvršenja transakcije (xtime
). Kao što vidite, odgoda se odnosi samo na predaje i ne utječe na druge unose - sve se promjene primjenjuju izravno, a predaja je odgođena, tako da ćemo promjene vidjeti tek nakon konfigurirane odgode.
Kako koristiti odgođenu repliku za vraćanje podataka
Recimo da imamo klaster baze podataka i repliku s osmosatnim kašnjenjem u proizvodnji. Pogledajmo kako oporaviti podatke pomoću primjera
Kada smo saznali za problem, mi
SELECT pg_xlog_replay_pause();
Uz pauzu, nismo imali rizika da će replika ponoviti zahtjev DELETE
. Korisna stvar ako vam treba vremena da sve shvatite.
Poanta je da odgođena replika mora doći do trenutka prije zahtjeva DELETE
. Približno smo znali fizičko vrijeme uklanjanja. Izbrisali smo recovery_min_apply_delay
i dodao recovery_target_time
в recovery.conf
. Ovako replika stiže u pravi trenutak bez odlaganja:
recovery_target_time = '2018-10-12 09:25:00+00'
S vremenskim oznakama, bolje je smanjiti višak kako ne biste propustili. Istina, što je smanjenje veće, gubimo više podataka. Opet, ako propustimo zahtjev DELETE
, sve će se ponovno izbrisati i morat ćete početi ispočetka (ili čak napraviti hladnu sigurnosnu kopiju za PITR).
Ponovno smo pokrenuli odgođenu instancu Postgresa i WAL segmenti su se ponavljali do navedenog vremena. Možete pratiti napredak u ovoj fazi postavljajući pitanje:
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;
Ako se vremenska oznaka više ne mijenja, oporavak je dovršen. Akcija se može prilagoditi recovery_target_action
Baza se vratila u stanje prije tog nesretnog zahtjeva. Sada možete, na primjer, izvesti podatke. Izvezli smo izbrisane podatke o oznaci i sve poveznice na probleme i zahtjeve za spajanje te ih premjestili u proizvodnu bazu podataka. Ako su gubici velikih razmjera, možete jednostavno promovirati repliku i koristiti je kao glavnu. Ali tada će sve promjene nakon točke do koje smo se oporavili biti izgubljene.
Umjesto vremenskih oznaka, bolje je koristiti ID-ove transakcija. Korisno je zabilježiti ove ID-ove, na primjer, za DDL izjave (kao što je DROP TABLE
), pomoću log_statements = 'ddl'
. Da imamo ID transakcije, uzeli bismo recovery_target_xid
i proveo sve do transakcije prije zahtjeva DELETE
.
Povratak na posao vrlo je jednostavan: uklonite sve promjene iz recovery.conf
i ponovno pokrenite Postgres. Replika će uskoro ponovno imati odgodu od osam sati, a mi smo spremni za buduće probleme.
Prednosti oporavka
Uz odgođenu repliku umjesto hladne sigurnosne kopije, ne morate trošiti sate vraćajući cijelu sliku iz arhive. Na primjer, potrebno nam je pet sati da dobijemo cijelu osnovnu sigurnosnu kopiju od 2 TB. I onda još morate primijeniti cijeli dnevni WAL da se vratite u željeno stanje (u najgorem slučaju).
Odgođena replika bolja je od hladne sigurnosne kopije na dva načina:
- Nema potrebe za uklanjanjem cijele osnovne sigurnosne kopije iz arhive.
- Postoji fiksni osmosatni prozor WAL segmenata koji se moraju ponavljati.
Također stalno provjeravamo je li moguće napraviti PITR iz WAL-a i brzo bismo primijetili oštećenje ili druge probleme s WAL arhivom praćenjem kašnjenja odgođene replike.
U ovom primjeru, trebalo nam je 50 minuta za vraćanje, što znači da je brzina bila 110 GB WAL podataka na sat (arhiva je još bila uključena
Rezultati: gdje je odgođena replika korisna (a gdje nije)
Koristite odgođenu replikaciju kao prvu pomoć ako ste slučajno izgubili podatke i primijetili ovaj problem unutar konfigurirane odgode.
Ali imajte na umu: replikacija nije sigurnosna kopija.
Sigurnosno kopiranje i replikacija imaju različite svrhe. Hladna sigurnosna kopija će vam dobro doći ako ste slučajno napravili DELETE
ili DROP TABLE
. Izrađujemo backup iz hladnjače i vraćamo tablicu ili cijelu bazu u prethodno stanje. Ali u isto vrijeme zahtjev DROP TABLE
se gotovo trenutno reproducira u svim replikama na radnom klasteru, tako da obična replikacija ovdje neće pomoći. Sama replikacija održava bazu podataka dostupnom kada se pojedinačni poslužitelji iznajmljuju i raspoređuje opterećenje.
Čak i s odgođenom replikom, ponekad stvarno trebamo hladnu sigurnosnu kopiju na sigurnom mjestu ako dođe do kvara podatkovnog centra, skrivene štete ili drugih događaja koji nisu odmah vidljivi. Sama replikacija ovdje nema nikakve koristi.
Primijetiti, na
Izvor: www.habr.com