
Replicimi â nuk Ă«shtĂ« njĂ« kopje rezervĂ«. Apo ndoshta Ă«shtĂ«? Ja se si e pĂ«rdorĂ«m replicimin e vonuar pĂ«r rikuperim, duke fshirĂ« rastĂ«sisht ikona.
nĂ« GitLab janĂ« pĂ«rgjegjĂ«s pĂ«r funksionimin â instancĂ«n mĂ« tĂ« madhe tĂ« GitLab qĂ« ekziston. KĂ«tu janĂ« 3 milion pĂ«rdorues dhe gati 7 milion projekte, dhe kjo Ă«shtĂ« njĂ« nga uebfaqet mĂ« tĂ« mĂ«dha open-source SaaS me arkitekturĂ« tĂ« dedikuar. Pa sistemin e bazĂ«s sĂ« tĂ« dhĂ«nave PostgreSQL, infrastruktura e GitLab.com nuk do tĂ« shkonte shumĂ« larg, dhe ne bĂ«jmĂ« gjithçka pĂ«r tĂ« siguruar disponueshmĂ«ri nĂ« rast tĂ« çështjeve qĂ« mund tĂ« çojnĂ« nĂ« humbjen e tĂ« dhĂ«nave. SĂ« paku, njĂ« katastrofĂ« e tillĂ« Ă«shtĂ« e pamundur, por ne kemi bĂ«rĂ« pĂ«rgatitjet tona dhe kemi zbatuar mekanizma tĂ« ndryshĂ«m pĂ«r kopje rezervĂ« dhe replikim.
Replikimi â kjo nuk Ă«shtĂ« njĂ« mjet pĂ«r kopje rezervĂ« tĂ« bazĂ«s sĂ« tĂ« dhĂ«nave (). Por tani do tĂ« shohim se si tĂ« rikuperojmĂ« tĂ« dhĂ«nat e fshira rastĂ«sisht me ndihmĂ«n e replikimit tĂ« vonuar: nĂ« pĂ«rdorues pĂ«r projektin dhe humba lidhjen me kĂ«rkesat pĂ«r shkrim dhe detyrat.
Me replikimin e vonuar, ne rikuperuam të dhënat brenda 1.5 orëve. Shihni se si ndodhi.
Rikuperimi në një moment të caktuar me PostgreSQL
PostgreSQL ka një funksion të integruar që rikthen gjendjen e bazës së të dhënave në një moment të caktuar. Quhet (PITR) dhe përdor mekanizmat e njëjtë që mbështesin aktualizimin e replikës: duke filluar nga një moment myslimi të saktë të të gjithë klasterit të bazës së të dhënave (kopja bazë), ne aplikojmë një seri ndryshimesh deri në një moment të caktuar.
Për ta përdorur këtë funksion për kopje rezervë të ftohtë, ne rregullisht bëjmë kopje të bazës së të dhënave dhe e ruajmë atë në arkivë (arkivat e GitLab jetojnë në ). Po ashtu, ne ndjekim ndryshimet e gjendjes së bazës së të dhënave, duke arkivuar regjistrin e shënimeve të parakohshme (, WAL). Dhe me të gjithë këtë, ne mund të realizojmë PITR për rikuperim emergjent: fillojmë me një skenë që është bërë para gabimit dhe aplikojmë ndryshimet nga arkiva WAL deri në gabim.
ĂfarĂ« Ă«shtĂ« replikimi i vonuar?
Replikimi i vonuar është aplikimi i ndryshimeve nga WAL me një vonesë. Pra, transaksioni u ndodhi në orën X, por në replikë do të shfaqet me një vonesë d në orën X + d.
NĂ« PostgreSQL ka dy mĂ«nyra pĂ«r tĂ« konfigururar njĂ« replikĂ« fizike tĂ« bazĂ«s sĂ« tĂ« dhĂ«nave: rikuperimi nga arkiva dhe replikimi streaming. , nĂ« thelb, funksionon si PITR, por nĂ« mĂ«nyrĂ« tĂ« vazhdueshme: ne pĂ«rditĂ« gjejmĂ« ndryshimet nga arkiva WAL dhe i aplikojmĂ« ato nĂ« replikĂ«. NdĂ«rsa direkt nxjerr njĂ« rrjedhĂ« WAL nga hosti i lartĂ« tĂ« bazĂ«s sĂ« tĂ« dhĂ«nave. Ne preferojmĂ« rikuperimin nga arkiva â Ă«shtĂ« mĂ« i lehtĂ« pĂ«r menaxhim dhe ka performancĂ« normale qĂ« nuk mbetet pas klasterit aktiv.
Si të konfigurojmë rikuperimin e vonuar nga arkiva
janë përshkruar në skedarin recovery.conf. Shembull:
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'Me këto parametra, ne kemi konfiguruar një replikë të vonuar me rikuperim nga arkiva. Këtu përdoret për të nxjerrë segmentet e WAL (restore_command) nga arkiva, dhe ndryshimet do të aplikohen pas tetë orëve (recovery_min_apply_delay). Replika do të ndjekë ndryshimet e kronologjisë në arkivë, për shembull, për shkak të daljes në klaster (recovery_target_timeline).
S recovery_min_apply_delay mund të konfiguroni replikimin streaming me vonesë, por këtu ka disa rreziqe që lidhen me slotet e replikimit, rikthimin e nxehtë dhe të tjera. Arkiva WAL lejon që këto të shmangen.
Parametri recovery_min_apply_delay shfaqur vetëm në PostgreSQL 9.3. Në versionet e mëparshme, për replikimin e vonuar duhej të konfiguroni një kombinim të (pg_xlog_replay_pause(), pg_xlog_replay_resume()) ose të mbash segmentet WAL në arkivë për kohën e vonesës.
Si e realizon PostgreSQL këtë?
ĂshtĂ« interesante tĂ« shohim se si PostgreSQL implementon rikuperimin e vonuar. Le tĂ« shohim nĂ« . Ai thirret nga pĂ«r secilĂ«n regjistrim nga WAL.
static bool
recoveryApplyDelay(XLogReaderState *record)
{
uint8 xact_info;
TimestampTz xtime;
long secs;
int microsecs;
/* nuk e ka çfarë për të bërë nëse nuk është konfiguruar asnjë vonesë */
if (recovery_min_apply_delay <= 0)
return false;
/* nuk aplikohet vonesë në një bazë të dhënash që ende nuk është e konsoliduar */
if (!reachedConsistency)
return false;
/*
* A është një rekord COMMIT?
*
* Qëllimisht zgjidhim të mos shqetësojmë abortet pasi ato nuk kanë asnjë efekt në
* MVCC. Ne lejojmë tashmë rivendosjen e regjistrimeve që nuk kanë një timestamp,
* kështu që tashmë ka mundësi për çështje të shkaktuara nga konfliktet e hershme mbi
* qëndrat.
*/
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);
/*
* Dalim pa armaturën e latch nëse është kaluar tashmë koha për të aplikuar këtë
* rekord
*/
TimestampDifference(GetCurrentTimestamp(), recoveryDelayUntilTime,
&secs, µsecs);
if (secs <= 0 && microsecs <= 0)
return false;
while (true)
{
// e shkurtuar:
// Përdorim WaitLatch derisa të arrijmë recoveryDelayUntilTime
// dhe pastaj
break;
}
return true;
}The main point is that the delay is based on the physical time recorded in the transaction commit timestamp (xtime). As seen, the delay only applies to commits and does not affect other records â all changes are applied directly, while the commit is delayed, so we see changes only after the configured delay.
How to use a delayed replica for data recovery
Suppose we have a production database cluster and a replica with an eight-hour delay. Let's see how to recover data using the example of .
When we learned about the problem, we for the delayed replica:
SELECT pg_xlog_replay_pause();With the pause, we had no risk of the replica replaying the request DELETE. A useful thing if you need time to sort everything out.
The main point is that the delayed replica needs to reach the moment before the request DELETE. We had a rough idea of the physical time of the deletion. We deleted recovery_min_apply_delay and added recovery_target_time në recovery.conf. Thus, the replica reaches the desired moment without delays:
recovery_target_time = '2018-10-12 09:25:00+00'With timestamps it's better to reduce the excess to avoid missing. However, the more we reduce, the more data we lose. Again, if we skip the request DELETE, everything will be deleted again, and we'll have to start over (or take a cold backup for PITR).
We restarted the delayed Postgres instance, and the WAL segments replayed up to the specified time. Tracking the progress at this stage can be done with the query:
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;If the timestamp no longer changes, the recovery is complete. You can set the action , to close, advance, or pause the instance after replaying (by default, it is paused).
The database returned to the state before that unfortunate request. Now itâs possible, for example, to export data. We exported the deleted label data and all connections to tasks and merge requests and transferred them to the working database. If the losses are extensive, we can simply advance the replica and use it as primary. But then all changes after the point we recovered will be lost.
Instead of timestamps, itâs better to use transaction IDs. Itâs useful to record these IDs, for example, for DDL operators (like DROP TABLE), using log_statements = 'ddl'. If we had the transaction ID, we would take recovery_target_xid and replay everything up to the transaction before the request. DELETE.
Returning to work is very easy: remove all changes from recovery.conf and restart Postgres. Soon the replica will have the eight-hour delay again, and we are prepared for future troubles.
Advantages for recovery
With the delayed replica instead of a cold backup, there's no need to spend hours recovering the entire snapshot from the archive. For us, for example, it takes five hours to extract the entire base backup of 2 TB. And then we still have to apply all the daily WAL to recover to the desired state (in the worst case).
The delayed replica is better than a cold backup for two reasons:
- No need to retrieve the entire base backup from the archive.
- Thereâs a fixed eight-hour window of WAL segments that need to be replayed.
And we constantly check if it's possible to perform PITR from WAL, and we would quickly notice any corruption or other problems with the WAL archive by monitoring the delay of the delayed replica.
In this example, it took us 50 minutes to recover, which means a speed of 110 GB of WAL data per hour (the archive was still on ). Overall, we solved the problem and recovered the data in 1.5 hours.
Përmbledhje: ku është e dobishme replikimi i vonuar (dhe ku nuk është)
Përdorni replikimin e vonuar si një mjet emergjence nëse keni humbur të dhëna gabimisht dhe e keni vënë re këtë problem brenda vonesës së vendosur.
Por mbani mend: replikimi nuk është kopje rezervë.
Kopja rezervë dhe replikimi kanë qëllime të ndryshme. Një kopje rezervë e ftohtë është e dobishme nëse keni bërë gabimisht DELETE ose DROP TABLE. Ne bëjmë kopje rezervë nga ruajtja e ftohtë dhe rikthejmë gjendjen e mëparshme të tabelës ose të gjithë bazës së të dhënave. Por në këtë rast, kërkesa DROP TABLE përhapen thuajse menjëherë në të gjitha replikat në grumbullin e punës, ndaj replikimi i zakonshëm nuk ndihmon këtu. Vetë replikimi mbështet bazën e të dhënave të jetë e aksesueshme, kur serverët individual janë në pushim, dhe shpërndan ngarkesën.
Edhe me replikimin e vonuar, herë pas here na nevojitet një kopje rezervë e ftohtë në një vend të sigurt, nëse ndodhin ndodhi si dështimi i një qendre të të dhënave, dëmtim i fshehur ose ngjarje të tjera që nuk duken menjëherë. Këtu, replikimi vetë nuk është i mjaftueshëm.
Shënim. Në ne tani po mbrojmë nga humbja e të dhënave vetëm në nivelin e sistemit dhe nuk po rikthejmë të dhënat në nivelin e përdoruesit.
Burimi: habr.com
