{"id":30356,"date":"2019-10-31T21:35:06","date_gmt":"2019-10-31T18:35:06","guid":{"rendered":"https:\/\/prohoster.info\/blog\/kak-my-ispolzovali-otlozhennuyu-replikatsiyu-dlya-avarijnogo-vosstanovleniya-s-postgresql\/"},"modified":"2019-10-31T21:35:06","modified_gmt":"2019-10-31T18:35:06","slug":"kak-my-ispolzovali-otlozhennuyu-replikatsiyu-dlya-avarijnogo-vosstanovleniya-s-postgresql","status":"publish","type":"post","link":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/kak-my-ispolzovali-otlozhennuyu-replikatsiyu-dlya-avarijnogo-vosstanovleniya-s-postgresql","title":{"rendered":"Cum am folosit replicarea \u00eent\u00e2rziat\u0103 pentru recuperarea \u00een caz de dezastru cu PostgreSQL","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Cum am folosit replicarea \u00eent\u00e2rziat\u0103 pentru recuperarea \u00een caz de dezastru cu PostgreSQL\" src=\"\/wp-content\/uploads\/2019\/03\/773f3b6c8d173be91c49066d7067bad3.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nReplica\u021bia nu este backup. Sau poate? Iat\u0103 cum am folosit replica\u021bia \u00eent\u00e2rziat\u0103 pentru a restaura, dup\u0103 ce am \u0219ters din gre\u0219eal\u0103 scurt\u0103turile.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/about.gitlab.com\/handbook\/engineering\/infrastructure\/\">Speciali\u0219ti \u00een infrastructur\u0103<\/a><\/noindex> pe GitLab sunt responsabili pentru func\u021bionarea <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/\">GitLab.com<\/a><\/noindex> \u2014 cea mai mare instan\u021b\u0103 GitLab din lume. Aici sunt 3 milioane de utilizatori \u0219i aproape 7 milioane de proiecte, \u0219i este unul dintre cele mai mari site-uri open-source SaaS cu o arhitectur\u0103 dedicat\u0103. F\u0103r\u0103 sistemul de baze de date PostgreSQL, infrastructura GitLab.com nu s-ar descurca, iar noi facem tot ce putem pentru a asigura continuitatea \u00een cazul oric\u0103ror defec\u021biuni, c\u00e2nd ar putea fi pierdute date. De\u0219i o astfel de calamitate este pu\u021bin probabil s\u0103 se \u00eent\u00e2mple, suntem bine preg\u0103ti\u021bi \u0219i am luat m\u0103suri cu diverse mecanisme de backup \u0219i replicare.<\/p>\n<p><\/p>\n<p>Replica\u021bia nu este un mijloc de backup pentru baze de date (<noindex><a rel=\"nofollow\" href=\"https:\/\/about.gitlab.com\/2019\/02\/13\/delayed-replication-for-disaster-recovery-with-postgresql\/#summing-up\">vezi mai jos<\/a><\/noindex>). Dar acum vom vedea c\u00e2t de rapid putem restaura datele \u0219terse din gre\u0219eal\u0103 folosind replica\u021bia \u00eent\u00e2rziat\u0103: la <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/\">GitLab.com<\/a><\/noindex> utilizator <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-com\/gl-infra\/production\/issues\/509\">a \u0219ters o scurt\u0103tur\u0103<\/a><\/noindex> pentru proiectul <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-org\/gitlab-ce\/\"><code>gitlab-ce<\/code><\/a><\/noindex> \u0219i a pierdut leg\u0103turile cu cererile de fuziune \u0219i sarcinile.<\/p>\n<p><\/p>\n<p>Cu replica\u021bia \u00eent\u00e2rziat\u0103, am restaurat datele \u00een doar 1,5 ore. Uite cum a fost.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3 id=\"vosstanovlenie-na-moment-vremeni-s-postgresql\">Restaurare la un moment dat cu PostgreSQL<\/h3>\n<p><\/p>\n<p>PostgreSQL are o func\u021bie \u00eencorporat\u0103 care restaureaz\u0103 starea bazei de date la un anumit moment. Se nume\u0219te <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/continuous-archiving.html\">Recuperare la punct \u00een timp<\/a><\/noindex> (PITR) \u0219i utilizeaz\u0103 acelea\u0219i mecanisme care sus\u021bin actualitatea replicii: \u00eencepem cu o captur\u0103 de siguran\u021b\u0103 a \u00eentregului cluster de baze de date (backup de baz\u0103), aplic\u0103m o serie de modific\u0103ri de stare p\u00e2n\u0103 la un moment dat.<\/p>\n<p><\/p>\n<p>Pentru a utiliza aceast\u0103 func\u021bie pentru backup rece, facem regulat backup de baz\u0103 al bazei de date \u0219i \u00eel stoc\u0103m \u00een arhiv\u0103 (arhivele GitLab tr\u0103iesc \u00een <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.google.com\/storage\/\">stocarea \u00een cloud Google<\/a><\/noindex>). De asemenea, urm\u0103rim modific\u0103rile st\u0103rii bazei de date, arhiv\u00e2nd jurnalul de scriere anticipat\u0103 (<noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/wal-intro.html\">jurnal de scriere anticipat\u0103<\/a><\/noindex>, WAL). \u0218i cu toate acestea putem efectua PITR pentru recuperare \u00een caz de dezastru: \u00eencepem cu captura efectuat\u0103 \u00eenainte de eroare \u0219i aplic\u0103m modific\u0103rile din arhiva WAL p\u00e2n\u0103 la defec\u021biune.<\/p>\n<p><\/p>\n<h3 id=\"chto-takoe-otlozhennaya-replikaciya\">Ce este replica\u021bia \u00eent\u00e2rziat\u0103?<\/h3>\n<p><\/p>\n<p>Replica\u021bia \u00eent\u00e2rziat\u0103 este aplicarea modific\u0103rilor din WAL cu o \u00eent\u00e2rziere. Adic\u0103 tranzac\u021bia a avut loc la ora <code>X<\/code>, dar \u00een replic\u0103 va ap\u0103rea cu o \u00eent\u00e2rziere <code>d<\/code> la ora <code>X + d<\/code>.<\/p>\n<p><\/p>\n<p>\u00cen PostgreSQL exist\u0103 2 moduri de a configura replica\u021bia fizic\u0103 a bazei de date: restaurare din arhiv\u0103 \u0219i replica\u021bie \u00een flux. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/archive-recovery-settings.html\">Restaurare din arhiv\u0103<\/a><\/noindex>, \u00een esen\u021b\u0103, func\u021bioneaz\u0103 ca PITR, dar continuu: extragem constant modific\u0103rile din arhiva WAL \u0219i le aplic\u0103m pe replic\u0103. A <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.postgresql.org\/wiki\/Streaming_Replication\">replicarea \u00een flux<\/a><\/noindex> extrage direct fluxul WAL din gazda de baz\u0103 de date superioar\u0103. Prefer\u0103m recuperarea din arhiv\u0103 \u2014 este mai u\u0219or de gestionat \u0219i are o performan\u021b\u0103 normal\u0103, care nu este inferioar\u0103 celei a clusterului de lucru.<\/p>\n<p><\/p>\n<h3 id=\"kak-nastroit-otlozhennoe-vosstanovlenie-iz-arhiva\">Cum s\u0103 configurezi recuperarea \u00eent\u00e2rziat\u0103 din arhiv\u0103<\/h3>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/recovery-config.html\">Op\u021biunile de recuperare<\/a><\/noindex> sunt descrise \u00een fi\u0219ierul <code>recovery.conf<\/code>. Exemplu:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">standby_mode = 'on'\nrestore_command = '\"\/usr\/bin\/envdir \/etc\/wal-e.d\/env \/opt\/wal-e\/bin\/wal-e wal-fetch -p 4 \"%f\" \"%p\"'\\nrecovery_min_apply_delay = '8h'\\nrecovery_target_timeline = 'latest'<\/code><\/pre>\n<p><\/p>\n<p>Cu aceste set\u0103ri, am configurat o replic\u0103 \u00eent\u00e2rziat\u0103 cu recuperare din arhiv\u0103. Aici se folose\u0219te <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/wal-e\/wal-e\">wal-e<\/a><\/noindex> pentru extragerea segmentelor WAL (<code>restore_command<\/code>) din arhiv\u0103, iar modific\u0103rile vor fi aplicate dup\u0103 opt ore (<code>recovery_min_apply_delay<\/code>). Replica va monitoriza modific\u0103rile din cronologia arhivei, de exemplu, din cauza unui e\u0219ec \u00een cluster (<code>recovery_target_timeline<\/code>).<\/p>\n<p><\/p>\n<p>Cu <code>recovery_min_apply_delay<\/code> se poate configura replicarea \u00een flux cu \u00eent\u00e2rziere, dar exist\u0103 c\u00e2teva capcane legate de sloturile de replicare, feedback-ul hot standby \u0219i altele. Arhiva WAL permite evitarea acestora.<\/p>\n<p><\/p>\n<p>Parametru <code>recovery_min_apply_delay<\/code> a fost introdus\u0103 abia \u00een PostgreSQL 9.3. \u00cen versiunile anterioare, pentru replicarea \u00eent\u00e2rziat\u0103 era necesar\u0103 configurarea unei combina\u021bii de <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/9.3\/functions-admin.html\">func\u021bii de gestionare a recuper\u0103rii<\/a><\/noindex> (<code>pg_xlog_replay_pause(), pg_xlog_replay_resume()<\/code>) sau p\u0103strarea segmentelor WAL \u00een arhiv\u0103 pentru timpul \u00eent\u00e2rzierii.<\/p>\n<p><\/p>\n<h3 id=\"kak-postgresql-eto-delaet\">Cum o face PostgreSQL?<\/h3>\n<p><\/p>\n<p>Este interesant s\u0103 vedem cum PostgreSQL implementeaz\u0103 recuperarea \u00eent\u00e2rziat\u0103. S\u0103 ne uit\u0103m la <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/postgres\/postgres\/blob\/c24dcd0cfd949bdf245814c4c2b3df828ee7db36\/src\/backend\/access\/transam\/xlog.c#L6124\"><code>recoveryApplyDelay(XlogReaderState)<\/code><\/a><\/noindex>. Este apelat din <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/postgres\/postgres\/blob\/c24dcd0cfd949bdf245814c4c2b3df828ee7db36\/src\/backend\/access\/transam\/xlog.c#L7196\">ciclul principal de repetare<\/a><\/noindex> pentru fiecare \u00eenregistrare din WAL.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">static bool\nrecoveryApplyDelay(XLogReaderState *record)\n{\n    uint8       xact_info;\n    TimestampTz xtime;\n    long        secs;\n    int         microsecs;\n\n    \/* nu avem nimic de f\u0103cut dac\u0103 nu este configurat\u0103 nicio \u00eent\u00e2rziere *\/\n    if (recovery_min_apply_delay &lt;= 0)\n        return false;\n\n    \/* nicio \u00eent\u00e2rziere nu se aplic\u0103 pe o baz\u0103 de date care nu este \u00eenc\u0103 consistent\u0103 *\/\n    if (!reachedConsistency)\n        return false;\n\n    \/*\n     * Este un \u00eenregistrare COMMIT?\n     *\n     * Alegem \u00een mod inten\u021bionat s\u0103 nu \u00eent\u00e2rziem abaterile deoarece nu au efect pe\n     * MVCC. Permitem deja redarea \u00eenregistr\u0103rilor care nu au un timestamp,\n     * astfel c\u0103 exist\u0103 deja oportunitatea pentru probleme cauzate de conflictele timpurii pe\n     * standby-uri.\n     * \/\n    if (XLogRecGetRmid(record) != RM_XACT_ID)\n        return false;\n\n    xact_info = XLogRecGetInfo(record) &amp; XLOG_XACT_OPMASK;\n\n    if (xact_info != XLOG_XACT_COMMIT &amp;&amp;\n        xact_info != XLOG_XACT_COMMIT_PREPARED)\n        return false;\n\n    if (!getRecordTimestamp(record, &amp;xtime))\n        return false;\n\n    recoveryDelayUntilTime =\n        TimestampTzPlusMilliseconds(xtime, recovery_min_apply_delay);\n\n    \/*\n     * Ie\u015fire f\u0103r\u0103 a activa latch-ul dac\u0103 a trecut deja timpul pentru a aplica acest\n     * \u00eenregistrare\n     * \/\n    TimestampDifference(GetCurrentTimestamp(), recoveryDelayUntilTime,\n                        &amp;secs, &amp;microsecs);\n    if (secs &lt;= 0 &amp;&amp; microsecs &lt;= 0)\n        return false;\n\n    while (true)\n    {\n        \/\/ Scurtat:\n        \/\/ Folosim WaitLatch p\u00e2n\u0103 ajungem la recoveryDelayUntilTime\n        \/\/ \u0219i apoi\n        break;\n    }\n    return true;\n}<\/code><\/pre>\n<p><\/p>\n<p>Ideea este c\u0103 \u00eent\u00e2rzierea se bazeaz\u0103 pe timpul fizic, \u00eenregistrat \u00een timestamp-ul comitetului tranzac\u021biei (<code>xtime<\/code>). Dup\u0103 cum se vede, \u00eent\u00e2rzierea se aplic\u0103 numai la comitete \u0219i nu afecteaz\u0103 alte \u00eenregistr\u0103ri - toate modific\u0103rile se aplic\u0103 direct, iar comitetul este \u00eent\u00e2rziat, astfel \u00eenc\u00e2t vom vedea modific\u0103rile doar dup\u0103 \u00eent\u00e2rzierea configurat\u0103.<\/p>\n<p><\/p>\n<h3 id=\"kak-ispolzovat-otlozhennuyu-repliku-dlya-vosstanovleniya-dannyh\">Cum s\u0103 folose\u0219ti o replic\u0103 \u00eent\u00e2rziat\u0103 pentru recuperarea datelor<\/h3>\n<p><\/p>\n<p>S\u0103 presupunem c\u0103 avem \u00een produc\u021bie un cluster de baze de date \u0219i o replic\u0103 cu o \u00eent\u00e2rziere de opt ore. S\u0103 vedem cum s\u0103 recuper\u0103m datele folosind exemplul <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-com\/gl-infra\/production\/issues\/509\">unei \u0219tergeri accidentale a etichetelor<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>C\u00e2nd am aflat despre problem\u0103, am <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/9.3\/functions-admin.html\">suspendat recuperarea din arhiv\u0103<\/a><\/noindex> pentru replica \u00eent\u00e2rziat\u0103:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">SELECT pg_xlog_replay_pause();<\/code><\/pre>\n<p><\/p>\n<p>Cu pauza nu am avut riscul ca replica s\u0103 repete solicitarea <code>DELETE<\/code>. O treab\u0103 util\u0103, dac\u0103 ai nevoie de timp pentru a \u00een\u021belege totul.<\/p>\n<p><\/p>\n<p>Ideea este c\u0103 replica \u00eent\u00e2rziat\u0103 trebuie s\u0103 ajung\u0103 la momentul dinaintea solicit\u0103rii <code>DELETE<\/code>. \u0218tiam aproximativ timpul fizic al \u0219tergerii. Am \u0219ters <code>recovery_min_apply_delay<\/code> \u0219i am ad\u0103ugat <code>recovery_target_time<\/code> \u00een <code>recovery.conf<\/code>. Astfel, replica ajunge la momentul dorit f\u0103r\u0103 \u00eent\u00e2rzieri:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">recovery_target_time = '2018-10-12 09:25:00+00'<\/code><\/pre>\n<p><\/p>\n<p>Cu timpii mai bine s\u0103 reduc\u0103 \u00een exces, pentru a nu rata. Totu\u0219i, cu c\u00e2t reduc mai mult, cu at\u00e2t mai multe date se pierd. Din nou, dac\u0103 trecem peste solicitare <code>DELETE<\/code>, totul se va \u0219terge din nou \u0219i va trebui s\u0103 \u00eencepem de la zero (sau chiar s\u0103 lu\u0103m un backup rece pentru PITR).<\/p>\n<p><\/p>\n<p>Am repornit instan\u021ba am\u00e2nat\u0103 de Postgres, iar segmentele WAL au fost repetate p\u00e2n\u0103 la timpul specificat. Progresul \u00een aceast\u0103 etap\u0103 poate fi urm\u0103rit prin cererea:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">SELECT\n  -- loca\u021bia curent\u0103 \u00een WAL\n  pg_last_xlog_replay_location(),\n  -- timestamp-ul curent al tranzac\u021biei (starea replicii)\n  pg_last_xact_replay_timestamp(),\n  -- timpul fizic curent\n  now(),\n  -- cantitatea de timp care trebuie aplicat\u0103 p\u00e2n\u0103 ce recovery_target_time a fost atins\n  '2018-10-12 09:25:00+00'::timestamptz - pg_last_xact_replay_timestamp() as delay;<\/code><\/pre>\n<p><\/p>\n<p>Dac\u0103 timestamp-ul nu se mai schimb\u0103, recuperarea s-a \u00eencheiat. Se poate configura ac\u021biunea <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/recovery-target-settings.html\"><code>recovery_target_action<\/code><\/a><\/noindex>, pentru a \u00eenchide, avansa sau suspenda instan\u021ba dup\u0103 repetare (implicit este suspendat\u0103).<\/p>\n<p><\/p>\n<p>baza de date a revenit la starea anterioar\u0103 acelui reflux nefericit. Acum se poate, de exemplu, exporta datele. Am exportat datele \u0219terse despre etichete \u0219i toate rela\u021biile cu sarcinile \u0219i cererile de fuziune \u0219i le-am transferat \u00een baza de date de lucru. Dac\u0103 pierderile sunt semnificative, se poate pur \u0219i simplu avansa replica \u0219i folosi ca pe cea principal\u0103. Dar atunci se vor pierde toate modific\u0103rile dup\u0103 momentul la care ne-am recuperat.<\/p>\n<p><\/p>\n<p>\u00cen loc de timestamp-uri, este mai bine s\u0103 folose\u0219ti ID-urile tranzac\u021biilor. E util s\u0103 notezi aceste ID-uri, de exemplu, pentru operatorii DDL (de tipul <code>DROP TABLE<\/code>), cu ajutorul <code>log_statements = 'ddl'<\/code>. Dac\u0103 am avea ID-ul tranzac\u021biei, l-am lua pe <code>recovery_target_xid<\/code> \u0219i am rula toate p\u00e2n\u0103 la tranzac\u021bia anterioar\u0103 cererii. <code>DELETE<\/code>.<\/p>\n<p><\/p>\n<p>A reveni la activitate este foarte simplu: elimin\u0103 toate modific\u0103rile din <code>recovery.conf<\/code> \u0219i reporne\u0219te Postgres. \u00cen cur\u00e2nd, \u00een replic\u0103 va ap\u0103rea din nou \u00eent\u00e2rzierea de opt ore, \u0219i suntem preg\u0103ti\u021bi pentru viitoarele nepl\u0103ceri.<\/p>\n<p><\/p>\n<h3 id=\"preimuschestva-dlya-vosstanovleniya\">Avantajele pentru recuperare<\/h3>\n<p><\/p>\n<p>Cu o replic\u0103 am\u00e2nat\u0103 \u00een loc de un backup rece, nu trebuie s\u0103 recuper\u0103m \u00eentreaga imagine din arhiv\u0103 timp de ore. De exemplu, avem nevoie de cinci ore pentru a ob\u021bine \u00eentreaga baz\u0103 de backup de 2 TB. Apoi, mai trebuie aplicat tot WAL-ul zilnic pentru a ne recupera la starea dorit\u0103 (\u00een cel mai r\u0103u caz).<\/p>\n<p><\/p>\n<p>Replica am\u00e2nat\u0103 este superioar\u0103 backup-ului rece din dou\u0103 puncte de vedere:<\/p>\n<p><\/p>\n<ol>\n<li>Nu trebuie s\u0103 aducem \u00eentreaga baz\u0103 de backup din arhiv\u0103.<\/li>\n<li>Exist\u0103 o fereastr\u0103 fix\u0103 de opt ore de segmente WAL care trebuie repetate.<\/li>\n<\/ol>\n<p><\/p>\n<p>De asemenea, verific\u0103m constant dac\u0103 se poate realiza PITR din WAL \u0219i am observa rapid deterior\u0103rile sau alte probleme cu arhiva WAL, urm\u0103rind \u00eent\u00e2rzierea replicii am\u00e2nate.<\/p>\n<p><\/p>\n<p>\u00cen acest exemplu, ne-a luat 50 de minute s\u0103 ne recuper\u0103m, adic\u0103 viteza a fost de 110 GB de date WAL pe or\u0103 (arhiva era \u00eenc\u0103 pe <noindex><a rel=\"nofollow\" href=\"https:\/\/aws.amazon.com\/s3\/\">AWS S3<\/a><\/noindex>). Am rezolvat problema \u0219i am restaurat datele \u00een 1,5 ore.<\/p>\n<p><\/p>\n<h3 id=\"itogi-gde-prigoditsya-otlozhennaya-replika-a-gde-net\">Concluzii: unde este util\u0103 replicarea \u00eent\u00e2rziat\u0103 (\u0219i unde nu)<\/h3>\n<p><\/p>\n<p>Folosi\u021bi replicarea \u00eent\u00e2rziat\u0103 ca un instrument de prim ajutor dac\u0103 a\u021bi pierdut accidental datele \u0219i a\u021bi observat acest lucru \u00een cadrul \u00eent\u00e2rzierii configurate.<\/p>\n<p><\/p>\n<blockquote><p>Dar re\u021bine\u021bi: replicarea nu este un backup.<\/p><\/blockquote>\n<p>Backup-ul \u0219i replicarea au scopuri diferite. Un backup rece este util dac\u0103 a\u021bi realizat accidental <code>DELETE<\/code> sau <code>DROP TABLE<\/code>. Facem un backup dintr-un depozit rece \u0219i restaur\u0103m starea anterioar\u0103 a tabelului sau a \u00eentregii baze de date. Dar, \u00een acela\u0219i timp, solicitarea <code>DROP TABLE<\/code> se reproduce aproape instantaneu \u00een toate replicile din clusterul de lucru, a\u0219a c\u0103 replicarea obi\u0219nuit\u0103 nu va ajuta. Replicarea, \u00een sine, men\u021bine baza de date disponibil\u0103 atunci c\u00e2nd serverele sunt oprite \u0219i distribuie sarcina.<\/p>\n<p><\/p>\n<p>Chiar \u0219i cu o replic\u0103 \u00eent\u00e2rziat\u0103, uneori avem nevoie urgent\u0103 de un backup rece \u00eentr-un loc sigur, \u00een cazul \u00een care survine o defec\u021biune a centrului de date, o deteriorare ascuns\u0103 sau alte evenimente care nu sunt imediat observabile. Aici, replicarea nu este de ajutor.<\/p>\n<p><\/p>\n<p><strong>Not\u0103<\/strong>. Pe <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/\">GitLab.com<\/a><\/noindex> noi protej\u0103m \u00een prezent \u00eempotriva pierderii datelor doar la nivel de sistem \u0219i nu restaur\u0103m datele la nivel de utilizator.<\/p>\n<p>Sursa: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/southbridge\/blog\/445446\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0420\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u2014 \u043d\u0435 \u0431\u044d\u043a\u0430\u043f. \u0418\u043b\u0438 \u043d\u0435\u0442? \u0412\u043e\u0442 \u043a\u0430\u043a \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u0443\u044e \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f, \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0432 \u044f\u0440\u043b\u044b\u043a\u0438. \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0441\u0442\u044b \u043f\u043e \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u043d\u0430 GitLab \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u0437\u0430 \u0440\u0430\u0431\u043e\u0442\u0443 GitLab.com \u2014 \u0441\u0430\u043c\u043e\u0433\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 GitLab \u0432 \u043f\u0440\u0438\u0440\u043e\u0434\u0435. \u0417\u0434\u0435\u0441\u044c 3 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0438 \u043f\u043e\u0447\u0442\u0438 7 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432, \u0438 \u044d\u0442\u043e \u043e\u0434\u0438\u043d \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u043a\u0440\u0443\u043f\u043d\u044b\u0445 \u043e\u043f\u0435\u043d\u0441\u043e\u0440\u0441-\u0441\u0430\u0439\u0442\u043e\u0432 SaaS \u0441 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043e\u0439. \u0411\u0435\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u044b [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":22360,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-30356","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2.1 - aioseo.com -->\n\t<meta name=\"description\" content=\".\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/kak-my-ispolzovali-otlozhennuyu-replikatsiyu-dlya-avarijnogo-vosstanovleniya-s-postgresql\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041a\u0430\u043a \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u0443\u044e \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0430\u0432\u0430\u0440\u0438\u0439\u043d\u043e\u0433\u043e \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441 PostgreSQL | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\".\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/kak-my-ispolzovali-otlozhennuyu-replikatsiyu-dlya-avarijnogo-vosstanovleniya-s-postgresql\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:35:06+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:35:06+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Cum am folosit replicarea \u00eent\u00e2rziat\u0103 pentru recuperarea de urgen\u021b\u0103 cu PostgreSQL | ProHoster","description":".","canonical_url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/kak-my-ispolzovali-otlozhennuyu-replikatsiyu-dlya-avarijnogo-vosstanovleniya-s-postgresql","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"ro_RO","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041a\u0430\u043a \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u0443\u044e \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0430\u0432\u0430\u0440\u0438\u0439\u043d\u043e\u0433\u043e \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441 PostgreSQL | ProHoster","og:description":".","og:url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/kak-my-ispolzovali-otlozhennuyu-replikatsiyu-dlya-avarijnogo-vosstanovleniya-s-postgresql","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:35:06+00:00","article:modified_time":"2019-10-31T18:35:06+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"30356","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 00:50:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 11:48:29","updated":"2026-01-21 00:50:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/30356","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=30356"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/30356\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media\/22360"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=30356"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=30356"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=30356"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}