ReplikÄcija nav dublÄjums. Vai nÄ? LÅ«k, kÄ mÄs izmantojÄm atlikto replikÄciju, lai atgÅ«tu no nejauÅ”as Ä«sceļu dzÄÅ”anas.
ReplikÄcija nav lÄ«dzeklis datu bÄzu dublÄÅ”anai (gitlab-ce
Izmantojot atlikto kopiju, mÄs atkopÄm datus tikai 1,5 stundu laikÄ. Paskaties, kÄ tas notika.
AtgÅ«Å”ana noteiktÄ laikÄ, izmantojot PostgreSQL
PostgreSQL ir iebÅ«vÄta funkcija, kas atjauno datu bÄzes stÄvokli noteiktÄ brÄ«dÄ«. Tas tiek saukts
Lai izmantotu Å”o funkciju aukstai dublÄÅ”anai, mÄs regulÄri izveidojam pamata datu bÄzes dublÄjumu un glabÄjam to arhÄ«vÄ (GitLab arhÄ«vi ir pieejami
Kas ir atliktÄ replikÄcija?
Slinka replikÄcija ir izmaiÅu pielietoÅ”ana no WAL ar aizkavi. Tas ir, darÄ«jums notika stundas laikÄ X
, bet tas tiks parÄdÄ«ts replikÄ ar kavÄÅ”anos d
pÄc stundas X + d
.
PostgreSQL ir divi veidi, kÄ iestatÄ«t fizisku datu bÄzes kopiju: dublÄjuma atkopÅ”ana un straumÄÅ”anas replikÄcija.
KÄ iestatÄ«t aizkavÄtu atkopÅ”anu no arhÄ«va
recovery.conf
. PiemÄrs:
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'
Izmantojot Å”os parametrus, mÄs konfigurÄjÄm atlikto repliku ar dublÄjuma atkopÅ”anu. Å eit tas tiek izmantots restore_command
) no arhÄ«va, un izmaiÅas tiks piemÄrotas pÄc astoÅÄm stundÄm (recovery_min_apply_delay
). Reprodukcija vÄros laika skalas izmaiÅas arhÄ«vÄ, piemÄram, klastera kļūmjpÄrlÄces (recovery_target_timeline
).
Š” recovery_min_apply_delay
Varat iestatÄ«t straumÄÅ”anas replikÄciju ar aizkavi, taÄu Å”eit ir dažas nepilnÄ«bas, kas saistÄ«tas ar replikÄcijas slotiem, karstÄs gaidstÄves atgriezenisko saiti un tÄ tÄlÄk. WAL arhÄ«vs ļauj no tiem izvairÄ«ties.
Parametrs recovery_min_apply_delay
parÄdÄ«jÄs tikai PostgreSQL 9.3. IepriekÅ”ÄjÄs versijÄs, lai veiktu atlikto replikÄciju, jums ir jÄkonfigurÄ kombinÄcija pg_xlog_replay_pause(), pg_xlog_replay_resume()
) vai turiet WAL segmentus arhÄ«vÄ uz aizkaves laiku.
KÄ PostgreSQL to dara?
Interesanti redzÄt, kÄ PostgreSQL Ä«steno slinko atkopÅ”anu. ApskatÄ«sim 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;
}
Galvenais ir tas, ka aizkave ir balstÄ«ta uz fizisko laiku, kas reÄ£istrÄts darÄ«juma izpildes laikspiedolÄ (xtime
). KÄ redzat, aizkave attiecas tikai uz commitiem un neietekmÄ citus ierakstus ā visas izmaiÅas tiek lietotas tieÅ”i, un commit tiek aizkavÄta, tÄpÄc izmaiÅas redzÄsim tikai pÄc konfigurÄtÄs aizkaves.
KÄ izmantot aizkavÄtu repliku datu atjaunoÅ”anai
PieÅemsim, ka mums ir datu bÄzes klasteris un kopija ar astoÅu stundu ražoÅ”anas aizkavi. ApskatÄ«sim, kÄ atgÅ«t datus, izmantojot piemÄru
Kad uzzinÄjÄm par problÄmu, mÄs
SELECT pg_xlog_replay_pause();
Ar pauzi mums nebija riska, ka kopija atkÄrtos pieprasÄ«jumu DELETE
. NoderÄ«ga lieta, ja nepiecieÅ”ams laiks, lai visu izdomÄtu.
Lieta ir tÄda, ka atliktajai kopijai ir jÄsasniedz brÄ«dis pirms pieprasÄ«juma DELETE
. MÄs aptuveni zinÄjÄm fizisko izÅemÅ”anas laiku. MÄs esam izdzÄsuÅ”i recovery_min_apply_delay
un pievienoja recovery_target_time
Š² recovery.conf
. LÅ«k, kÄ replika bez kavÄÅ”anÄs sasniedz pareizo brÄ«di:
recovery_target_time = '2018-10-12 09:25:00+00'
Izmantojot laika zÄ«mogus, labÄk ir samazinÄt pÄrpalikumu, lai nepalaistu garÄm. Tiesa, jo lielÄks samazinÄjums, jo vairÄk datu mÄs zaudÄjam. Atkal, ja mÄs palaidÄm garÄm pieprasÄ«jumu DELETE
, viss tiks dzÄsts vÄlreiz, un jums bÅ«s jÄsÄk no jauna (vai pat jÄuzÅem aukstÄ dublÄjums PITR).
MÄs restartÄjÄm atlikto Postgres gadÄ«jumu, un WAL segmenti tika atkÄrtoti lÄ«dz norÄdÄ«tajam laikam. Å ajÄ posmÄ varat izsekot progresam, jautÄjot:
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;
Ja laikspiedols vairs nemainÄs, atkopÅ”ana ir pabeigta. DarbÄ«bu var pielÄgot recovery_target_action
DatubÄze atgriezÄs savÄ stÄvoklÄ« pirms Ŕī nelaimÄ«gÄ pieprasÄ«juma. Tagad varat, piemÄram, eksportÄt datus. MÄs eksportÄjÄm dzÄstos etiÄ·eÅ”u datus un visas saites uz problÄmÄm un sapludinÄÅ”anas pieprasÄ«jumiem un pÄrvietojÄm tos uz ražoÅ”anas datu bÄzi. Ja zaudÄjumi ir liela mÄroga, varat vienkÄrÅ”i reklamÄt kopiju un izmantot to kÄ galveno. Bet tad visas izmaiÅas pÄc punkta, lÄ«dz kuram esam atguvuÅ”ies, tiks zaudÄtas.
Laikspiedolu vietÄ labÄk izmantot darÄ«jumu ID. Ir lietderÄ«gi ierakstÄ«t Å”os ID, piemÄram, DDL paziÅojumiem (piemÄram, DROP TABLE
), izmantojot log_statements = 'ddl'
. Ja mums bÅ«tu darÄ«juma ID, mÄs Åemtu recovery_target_xid
un palaida visu līdz darījumam pirms pieprasījuma DELETE
.
AtgrieÅ”anÄs darbÄ ir ļoti vienkÄrÅ”a: noÅemiet visas izmaiÅas no recovery.conf
un restartÄjiet programmu Postgre. DrÄ«zumÄ replika atkal aizkavÄsies par astoÅÄm stundÄm, un mÄs esam gatavi turpmÄkÄm nepatikÅ”anÄm.
AtgūŔanas priekŔrocības
Izmantojot atlikto kopiju, nevis aukstu dublÄjumu, jums nav jÄtÄrÄ stundas, lai atjaunotu visu attÄlu no arhÄ«va. PiemÄram, mums ir nepiecieÅ”amas piecas stundas, lai iegÅ«tu visu pamata 2 TB dublÄjumu. Un tad vÄl jÄpieliek visa ikdienas WAL, lai atgÅ«tos vÄlamajÄ stÄvoklÄ« (sliktÄkajÄ gadÄ«jumÄ).
AtliktÄ kopija ir labÄka par aukstu dublÄjumu divos veidos:
- Nav nepiecieÅ”ams noÅemt visu pamata dublÄjumu no arhÄ«va.
- Ir fiksÄts astoÅu stundu WAL segmentu logs, kas ir jÄatkÄrto.
MÄs arÄ« pastÄvÄ«gi pÄrbaudÄm, vai ir iespÄjams izveidot PITR no WAL, un mÄs Ätri pamanÄm WAL arhÄ«va bojÄjumus vai citas problÄmas, uzraugot atliktÄs kopijas nobÄ«di.
Å ajÄ piemÄrÄ atjaunoÅ”ana aizÅÄma 50 minÅ«tes, kas nozÄ«mÄ, ka Ätrums bija 110 GB WAL datu stundÄ (arhÄ«vs joprojÄm bija ieslÄgts
RezultÄti: kur atliktÄ kopija ir noderÄ«ga (un kur tÄ nav)
Izmantojiet aizkavÄto replikÄciju kÄ pirmo palÄ«dzÄ«bu, ja nejauÅ”i pazaudÄjÄt datus un pamanÄ«jÄt Å”o problÄmu konfigurÄtÄs aizkaves laikÄ.
Bet paturiet prÄtÄ: replikÄcija nav dublÄjums.
DublÄÅ”anai un replikÄcijai ir dažÄdi mÄrÄ·i. AukstÄ dublÄjums noderÄs, ja nejauÅ”i izveidojÄt DELETE
vai DROP TABLE
. MÄs izveidojam dublÄjumu no saldÄtavas un atjaunojam tabulas vai visas datu bÄzes iepriekÅ”Äjo stÄvokli. Bet tajÄ paÅ”Ä laikÄ lÅ«gums DROP TABLE
gandrÄ«z uzreiz tiek reproducÄts visÄs darba klastera replikÄs, tÄpÄc parastÄ replikÄcija Å”eit nepalÄ«dzÄs. Pati replikÄcija nodroÅ”ina datubÄzes pieejamÄ«bu, kad atseviŔķi serveri tiek iznomÄti un sadala slodzi.
Pat ar atliktu reprodukciju mums dažreiz patieÅ”Äm ir nepiecieÅ”ama auksta dublÄÅ”ana droÅ”Ä vietÄ, ja rodas datu centra kļūme, slÄpti bojÄjumi vai citi notikumi, kas nav uzreiz pamanÄmi. Tikai replikÄcija Å”eit nav noderÄ«ga.
Piezīme. Par
Avots: www.habr.com