Replikointi ei ole varmuuskopio. Tai ei? Näin käytimme laiskaa replikointia palauttamiseen poistamalla vahingossa pikakuvakkeita.
Replikointi ei ole tietokannan varmuuskopiointityökalu (gitlab-ce
Viivästyneen replikan ansiosta palautimme tiedot vain 1,5 tunnissa. Katso kuinka kävi.
Täsmällinen palautus PostgreSQL:llä
PostgreSQL:ssä on sisäänrakennettu toiminto, joka palauttaa tietokannan tilan tiettyyn ajankohtaan. Sitä kutsutaan
Käyttääksemme tätä ominaisuutta kylmään varmuuskopiointiin teemme säännöllisesti perustietokannan varmuuskopion ja tallennamme sen arkistoon (GitLab-arkistot elävät
Mikä on viivästynyt replikaatio?
Viivästetty replikointi tarkoittaa WAL-muutosten soveltamista viiveellä. Eli kauppa tapahtui tunnin aikana X
, mutta se näkyy replikassa viiveellä d
tunnissa X + d
.
Fyysisen tietokannan replikan määrittämiseen PostgreSQL:ssä on kaksi tapaa: arkiston palautus ja suoratoiston replikointi.
Kuinka määrittää viivästetty varmuuskopion palautus
recovery.conf
. Esimerkki:
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'
Näillä asetuksilla olemme määrittäneet viivästetyn replikan arkiston palautuksella. Käytetty täällä restore_command
) arkistosta, ja muutokset tulevat voimaan kahdeksan tunnin kuluttua (recovery_min_apply_delay
). Replica tarkkailee arkistossa tapahtuvia aikajanan muutoksia, kuten klusterin vikasietoa (recovery_target_timeline
).
С recovery_min_apply_delay
voit määrittää latenssin suoratoiston replikoinnin, mutta replikointipaikkoihin, kuumaan varapalautteeseen ja niin edelleen liittyy muutama sudenkuoppa. WAL-arkisto välttää ne.
Parametri recovery_min_apply_delay
ilmestyi vain PostgreSQL 9.3:ssa. Aiemmissa versioissa viivästetty replikointi vaatii yhdistelmän pg_xlog_replay_pause(), pg_xlog_replay_resume()
) tai pidä WAL-segmentit arkistossa viiveen ajan.
Miten PostgreSQL tekee sen?
On mielenkiintoista nähdä, kuinka PostgreSQL toteuttaa laiskan palautuksen. Katsotaanpa 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;
}
Lopputulos on, että viive perustuu fyysiseen aikaan, joka on tallennettu tapahtumasitoumuksen aikaleimaan (xtime
). Kuten näette, viive koskee vain sitoumuksia eikä vaikuta muihin tietueisiin - kaikki muutokset otetaan käyttöön suoraan ja toimitus viivästyy, joten näemme muutokset vasta määritetyn viiveen jälkeen.
Laiskan replikan käyttäminen tietojen palauttamiseen
Oletetaan, että meillä on tietokantaklusteri tuotannossa ja replika kahdeksan tunnin viiveellä. Katsotaanpa, kuinka tiedot palautetaan esimerkin avulla
Kun huomasimme ongelman, me
SELECT pg_xlog_replay_pause();
Tauon jälkeen meillä ei ollut riskiä, että kopio toistaisi pyynnön DELETE
. Hyödyllinen asia, jos tarvitset aikaa kaiken selvittämiseen.
Tärkeintä on, että viivästyneen replikan on saavutettava pyyntöä edeltävä hetki DELETE
. Tiesimme suunnilleen fyysisen poiston ajan. Poistimme recovery_min_apply_delay
ja lisätty recovery_target_time
в recovery.conf
. Joten kopio saavuttaa oikean hetken viipymättä:
recovery_target_time = '2018-10-12 09:25:00+00'
Aikaleimoilla on parempi vähentää ylijäämää, jotta se ei jää huomaamatta. Totta, mitä suurempi lasku, sitä enemmän menetämme tietoja. Jälleen, jos ohitamme pyynnön DELETE
, kaikki poistetaan uudelleen ja sinun on aloitettava alusta (tai jopa otettava kylmä varmuuskopio PITR:stä).
Aloitimme viivästyneen Postgres-ilmentymän uudelleen ja WAL-segmentit toistettiin määritettyyn aikaan asti. Voit seurata edistymistä tässä vaiheessa kyselyllä:
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;
Jos aikaleima ei enää muutu, palautus on valmis. Voit mukauttaa toimintoa recovery_target_action
Tietokanta tuli tilaan ennen tuota epäonnista pyyntöä. Nyt voit esimerkiksi viedä tietoja. Olemme vieneet etätarratiedot ja kaikki linkit ongelmiin ja yhdistämispyyntöihin ja siirtäneet ne tuotantotietokantaan. Jos häviöt ovat suuria, voit yksinkertaisesti mainostaa kopiota ja käyttää sitä pääkappaleena. Mutta sitten kaikki muutokset menetetään sen hetken jälkeen, johon olemme toipuneet.
On parempi käyttää tapahtumatunnuksia aikaleimien sijaan. Nämä tunnukset on hyödyllistä tallentaa esimerkiksi DDL-lauseita varten (esim DROP TABLE
), käyttämällä log_statements = 'ddl'
. Jos meillä olisi tapahtumatunnus, ottaisimme recovery_target_xid
ja suoritti kaiken tapahtumaan ennen pyyntöä DELETE
.
Töihin paluu on hyvin yksinkertaista: poista kaikki muutokset kohteesta recovery.conf
ja käynnistä postgres uudelleen. Pian vihjeessä on taas kahdeksan tunnin viive, ja olemme valmiita tuleviin ongelmiin.
Palautusedut
Viivästetyn replikan kanssa kylmän varmuuskopion sijaan sinun ei tarvitse viettää tuntikausia palauttamaan koko tilannekuvaa arkistosta. Tarvitsemme esimerkiksi viisi tuntia saadaksemme koko 2 Tt:n perusvarmuuskopion. Ja sitten sinun on vielä käytettävä koko päivittäinen WAL palautuaksesi haluttuun tilaan (pahimmassa tapauksessa).
Viivästetty kopio on parempi kuin kylmä varmuuskopio kahdella tavalla:
- Sinun ei tarvitse saada koko perusvarmuuskopiota arkistosta.
- On kiinteä kahdeksan tunnin WAL-segmenttien ikkuna, joka on toistettava.
Lisäksi tarkistamme jatkuvasti, voidaanko WAL:lle tehdä PITR-koodi, ja havaitsimme nopeasti WAL-arkiston korruption tai muita ongelmia seuraamalla viivästyneen replikan ruuhkaa.
Tässä esimerkissä palautus kesti 50 minuuttia, eli nopeus oli 110 Gt WAL-dataa tunnissa (arkisto oli edelleen päällä
Yhteenveto: missä viivästetty replika on hyödyllinen (ja missä ei)
Käytä viivästettyä replikointia ensiapuna, jos menetät vahingossa tietoja ja huomaat tämän katastrofin määritetyn viiveen sisällä.
Mutta muista: replikointi ei ole varmuuskopio.
Varmuuskopioinnilla ja replikaatiolla on eri tarkoitus. Kylmä varmuuskopio on hyödyllinen, jos teit vahingossa DELETE
tai DROP TABLE
. Teemme varmuuskopion kylmävarastosta ja palautamme taulukon tai koko tietokannan aiemman tilan. Mutta samalla pyyntö DROP TABLE
toistetaan lähes välittömästi kaikissa toimivan klusterin replikoissa, joten tavallinen replikointi ei tallennu tähän. Itse replikointi pitää tietokannan saatavilla, kun yksittäiset palvelimet vuokrataan ja jakaa kuorman.
Jopa viivästyneen replikan kanssa tarvitsemme joskus todella kylmän varmuuskopion turvalliseen paikkaan, jos yhtäkkiä tapahtuu datakeskuksen vika, piilotettu vaurio tai muu tapahtuma, jota et heti huomaa. Tässä yhdestä replikaatiosta ei ole mitään järkeä.
Huomata. päälle
Lähde: will.com