Replikasie is nie rugsteun nie. Of nie? Hier is hoe ons uitgestelde replikasie gebruik het om te herstel nadat kortpaaie per ongeluk uitgevee is.
Replikasie is nie 'n manier om databasisse te rugsteun nie (gitlab-ce
Met 'n uitgestelde replika het ons data in net 1,5 uur herwin. Kyk hoe het dit gebeur.
Punt in tyd herstel met PostgreSQL
PostgreSQL het 'n ingeboude funksie wat die toestand van 'n databasis na 'n spesifieke tydstip herstel. Dit word genoem
Om hierdie kenmerk vir koue rugsteun te gebruik, maak ons ββgereeld 'n basiese databasisrugsteun en stoor dit in 'n argief (GitLab argiewe woon in
Wat is uitgestelde replikasie?
Lui replikasie is die toepassing van veranderinge vanaf WAL met 'n vertraging. Dit wil sΓͺ, die transaksie het binne 'n uur plaasgevind X
, maar dit sal met 'n vertraging in die replika verskyn d
in 'n uur X + d
.
PostgreSQL het 2 maniere om 'n fisiese databasis replika op te stel: rugsteunherwinning en stroomreplikasie.
Hoe om vertraagde herstel uit 'n argief op te stel
recovery.conf
. 'N Voorbeeld:
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'
Met hierdie parameters het ons 'n uitgestelde replika met rugsteunherstel opgestel. Hier word dit gebruik restore_command
) uit die argief, en veranderinge sal na agt uur toegepas word (recovery_min_apply_delay
). Die replika sal kyk vir tydlynveranderinge in die argief, byvoorbeeld as gevolg van 'n cluster failover (recovery_target_timeline
).
Π‘ recovery_min_apply_delay
U kan stroomreplikasie met 'n vertraging opstel, maar hier is 'n paar slaggate wat verband hou met replikasiegleuwe, warm bystand-terugvoer, ensovoorts. Die WAL-argief laat jou toe om dit te vermy.
Parameter recovery_min_apply_delay
het slegs in PostgreSQL 9.3 verskyn. In vorige weergawes, vir uitgestelde replikasie moet jy die kombinasie konfigureer pg_xlog_replay_pause(), pg_xlog_replay_resume()
) of hou WAL-segmente in die argief vir die duur van die vertraging.
Hoe doen PostgreSQL dit?
Dit is interessant om te sien hoe PostgreSQL lui herstel implementeer. Kom ons kyk na 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;
}
Die slotsom is dat die vertraging gebaseer is op die fisiese tyd wat aangeteken is in die transaksie-toewysingstydstempel (xtime
). Soos u kan sien, is die vertraging slegs van toepassing op commits en beΓ―nvloed dit nie ander inskrywings nie - alle veranderinge word direk toegepas, en die commit is vertraag, so ons sal die veranderinge eers na die gekonfigureerde vertraging sien.
Hoe om 'n vertraagde replika te gebruik om data te herstel
Kom ons sΓͺ ons het 'n databasiskluster en 'n replika met 'n vertraging van agt uur in produksie. Kom ons kyk hoe om data te herstel deur 'n voorbeeld te gebruik
Toe ons van die probleem geleer het, het ons
SELECT pg_xlog_replay_pause();
Met 'n pouse het ons geen risiko gehad dat die replika die versoek sou herhaal nie DELETE
. 'n Nuttige ding as jy tyd nodig het om alles uit te vind.
Die punt is dat die uitgestelde replika die oomblik voor die versoek moet bereik DELETE
. Ons het omtrent die fisiese tyd van verwydering geweet. Ons het uitgevee recovery_min_apply_delay
en bygevoeg recovery_target_time
Π² recovery.conf
. Dit is hoe die replika sonder versuim die regte oomblik bereik:
recovery_target_time = '2018-10-12 09:25:00+00'
Met tydstempels is dit beter om die oorskot te verminder om nie te mis nie. Dit is waar, hoe groter die afname, hoe meer data verloor ons. Weereens, as ons die versoek mis DELETE
, sal alles weer uitgevee word en jy sal oor moet begin (of selfs 'n koue rugsteun vir PITR neem).
Ons het die uitgestelde Postgres-instansie weer begin en die WAL-segmente is herhaal tot die gespesifiseerde tyd. U kan vordering op hierdie stadium dophou deur te vra:
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;
As die tydstempel nie meer verander nie, is die herstel voltooi. Aksie kan aangepas word recovery_target_action
Die databasis het teruggekeer na sy toestand voor daardie ongelukkige versoek. Nou kan jy byvoorbeeld data uitvoer. Ons het die geskrapte etiketdata en alle skakels na kwessies en samesmeltingsversoeke uitgevoer en na die produksiedatabasis geskuif. As die verliese grootskaalse is, kan jy eenvoudig die replika bevorder en dit as die hoof een gebruik. Maar dan sal alle veranderinge nΓ‘ die punt waartoe ons herstel het, verlore gaan.
In plaas van tydstempels, is dit beter om transaksie-ID's te gebruik. Dit is nuttig om hierdie ID's op te teken, byvoorbeeld vir DDL-stellings (soos DROP TABLE
), deur die gebruik van log_statements = 'ddl'
. As ons 'n transaksie-ID gehad het, sou ons dit neem recovery_target_xid
en het alles afgeloop tot die transaksie voor die versoek DELETE
.
Om terug te gaan werk toe is baie eenvoudig: verwyder alle veranderinge van recovery.conf
en herbegin Postgres. Die replika sal binnekort weer 'n agt uur vertraging hΓͺ, en ons is voorbereid op toekomstige probleme.
Herstelvoordele
Met 'n uitgestelde replika in plaas van 'n koue rugsteun, hoef u nie ure te spandeer om die hele beeld uit die argief te herstel nie. Dit neem ons byvoorbeeld vyf uur om die hele basiese 2 TB-rugsteun te kry. En dan moet jy nog die hele daaglikse WAL aanwend om na die verlangde toestand te herstel (in die ergste geval).
βn Uitgestelde replika is op twee maniere beter as βn koue rugsteun:
- Dit is nie nodig om die hele basiese rugsteun uit die argief te verwyder nie.
- Daar is 'n vaste agt-uur-venster van WAL-segmente wat herhaal moet word.
Ons kyk ook voortdurend of dit moontlik is om 'n PITR van WAL te maak, en ons sal vinnig korrupsie of ander probleme met die WAL-argief opmerk deur die vertraging van die uitgestelde replika te monitor.
In hierdie voorbeeld het dit ons 50 minute geneem om te herstel, wat beteken dat die spoed 110 GB WAL-data per uur was (die argief was steeds aan
Resultate: waar 'n uitgestelde replika nuttig is (en waar dit nie is nie)
Gebruik vertraagde replikasie as 'n noodhulp as jy per ongeluk data verloor het en hierdie probleem binne die gekonfigureerde vertraging opgemerk het.
Maar hou in gedagte: replikasie is nie 'n rugsteun nie.
Rugsteun en replikasie het verskillende doeleindes. 'n Koue rugsteun sal handig te pas kom as jy dit per ongeluk gemaak het DELETE
of DROP TABLE
. Ons maak 'n rugsteun vanaf koelberging en herstel die vorige toestand van die tabel of die hele databasis. Maar terselfdertyd die versoek DROP TABLE
word byna onmiddellik in alle replikas op die werkende groep gereproduseer, so gewone replikasie sal nie hier help nie. Replikasie self hou die databasis beskikbaar wanneer individuele bedieners verhuur word en versprei die vrag.
Selfs met 'n uitgestelde replika het ons soms regtig 'n koue rugsteun op 'n veilige plek nodig as 'n datasentrumfout, verborge skade of ander gebeurtenisse wat nie onmiddellik opmerklik is nie, plaasvind. Replikasie alleen is hier van geen nut nie.
Let daarop. Op
Bron: will.com