Replikacija nije sigurnosna kopija. Ili ne? Evo kako smo koristili odgođenu replikaciju za oporavak od slučajnog brisanja prečica.
Replikacija nije sredstvo pravljenja sigurnosne kopije baza podataka (gitlab-ce
Uz odgođenu repliku, oporavili smo podatke za samo 1,5 sat. Pogledaj kako se to dogodilo.
Oporavak u trenutku uz PostgreSQL
PostgreSQL ima ugrađenu funkciju koja vraća stanje baze podataka na određeni trenutak u vremenu. To se zove
Da bismo koristili ovu funkciju za hladno sigurnosno kopiranje, redovno pravimo osnovnu sigurnosnu kopiju baze podataka i pohranjujemo je u arhivu (GitLab arhive žive u
Šta je odgođena replikacija?
Lijena replikacija je primjena promjena iz WAL-a sa zakašnjenjem. To jest, transakcija se dogodila za sat vremena X
, ali će se pojaviti u replici sa zakašnjenjem d
Za sat vremena X + d
.
PostgreSQL ima 2 načina za postavljanje replike fizičke baze podataka: oporavak sigurnosne kopije i replikacija strujanja.
Kako postaviti odlož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'
Sa ovim parametrima smo konfigurisali odgođenu repliku sa obnavljanjem rezervne kopije. Ovdje se koristi restore_command
) iz arhive, a promjene će biti primijenjene nakon osam sati (recovery_min_apply_delay
). Replika će pratiti promjene vremenske trake u arhivi, na primjer zbog klastera (recovery_target_timeline
).
С recovery_min_apply_delay
Možete postaviti replikaciju strujanja sa zakašnjenjem, ali ovdje postoji nekoliko zamki koje se odnose na slotove za replikaciju, povratne informacije o vrućoj pripravnosti i tako dalje. WAL arhiva vam omogućava da ih izbjegnete.
Parametar recovery_min_apply_delay
pojavio se samo u PostgreSQL 9.3. U prethodnim verzijama, za odgođenu replikaciju trebate konfigurirati kombinaciju pg_xlog_replay_pause(), pg_xlog_replay_resume()
) ili zadržati WAL segmente u arhivi za vrijeme trajanja kašnjenja.
Kako PostgreSQL to radi?
Zanimljivo je vidjeti kako PostgreSQL implementira lijeni oporavak. Hajde da pogledamo 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;
}
Suština je da je kašnjenje zasnovano na fizičkom vremenu zabilježenom u vremenskoj oznaci polaganja transakcije (xtime
). Kao što vidite, kašnjenje se odnosi samo na urezivanje i ne utiče na druge unose - sve promene se primenjuju direktno, a urezivanje je odloženo, tako da ćemo promene videti tek nakon konfigurisanog kašnjenja.
Kako koristiti odloženu repliku za vraćanje podataka
Recimo da imamo klaster baze podataka i repliku sa osmosatnim kašnjenjem u proizvodnji. Pogledajmo kako oporaviti podatke koristeći primjer
Kada smo saznali za problem, mi
SELECT pg_xlog_replay_pause();
Uz pauzu, nismo imali rizik da će replika ponoviti zahtjev DELETE
. Korisna stvar ako vam treba vremena da sve shvatite.
Poenta 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'
Sa vremenskim oznakama, bolje je smanjiti višak kako ne biste propustili. Istina, što je veći pad, gubimo više podataka. Opet, ako propustimo zahtjev DELETE
, sve će biti ponovo izbrisano i morat ćete početi ispočetka (ili čak napraviti hladnu sigurnosnu kopiju za PITR).
Ponovo smo pokrenuli odloženu Postgres instancu i WAL segmenti su se ponavljali do određenog vremena. Možete pratiti napredak u ovoj fazi tako što ćete pitati:
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 završen. Akcija se može prilagoditi recovery_target_action
Baza podataka se vratila u stanje prije tog nesretnog zahtjeva. Sada možete, na primjer, izvesti podatke. Izvezli smo podatke o obrisanoj etiketi i sve veze do problema i zahtjeva za spajanjem i premjestili ih 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 tačke do koje smo se oporavili biti izgubljene.
Umjesto vremenskih oznaka, bolje je koristiti ID transakcije. Korisno je zabilježiti ove ID-ove, na primjer, za DDL naredbe (kao npr DROP TABLE
), korištenjem log_statements = 'ddl'
. Da imamo ID transakcije, uzeli bismo recovery_target_xid
i pokrenuo sve do transakcije prije zahtjeva DELETE
.
Povratak na posao je vrlo jednostavan: uklonite sve promjene iz recovery.conf
i ponovo pokrenite Postgres. Replika će uskoro ponovo imati osam sati kašnjenja, 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š uvijek morate primijeniti cijeli dnevni WAL da biste se oporavili u željeno stanje (u najgorem slučaju).
Odgođena replika je bolja od hladne sigurnosne kopije na dva načina:
- Nema potrebe za uklanjanjem cijele osnovne sigurnosne kopije iz arhive.
- Postoji fiksni osmočasovni prozor WAL segmenata koji se moraju ponoviti.
Također stalno provjeravamo da li je moguće napraviti PITR iz WAL-a, a brzo bismo uočili oštećenje ili druge probleme sa 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š uvijek 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 konfiguriranog kašnjenja.
Ali imajte na umu: replikacija nije rezervna kopija.
Sigurnosna kopija i replikacija imaju različite svrhe. Hladna rezervna kopija će vam dobro doći ako ste slučajno napravili DELETE
ili DROP TABLE
. Izrađujemo rezervnu kopiju iz hladnog skladišta i vraćamo prethodno stanje tablice ili cijele baze podataka. Ali istovremeno i 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 su pojedinačni serveri iznajmljeni i raspoređuje opterećenje.
Čak i sa odgođenom replikom, ponekad nam je zaista potrebna hladna sigurnosna kopija na sigurnom mjestu ako dođe do kvara podatkovnog centra, skrivenih oštećenja ili drugih događaja koji nisu odmah uočljivi. Sama replikacija ovdje nije od koristi.
primjedba... Uključeno
izvor: www.habr.com