{"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\/sk\/blog\/administrirovanie\/kak-my-ispolzovali-otlozhennuyu-replikatsiyu-dlya-avarijnogo-vosstanovleniya-s-postgresql","title":{"rendered":"Ako sme pou\u017eili oneskoren\u00fa replik\u00e1ciu na havarijn\u00e9 obnovenie s PostgreSQL","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Ako sme pou\u017eili oneskoren\u00fa replik\u00e1ciu na havarijn\u00e9 obnovenie s PostgreSQL\" src=\"\/wp-content\/uploads\/2019\/03\/773f3b6c8d173be91c49066d7067bad3.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nReplik\u00e1cia nie je z\u00e1loha. Alebo \u00e1no? Takto sme pou\u017eili oneskoren\u00fa replik\u00e1ciu na obnovenie po n\u00e1hodnom odstr\u00e1nen\u00ed skratiek.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/about.gitlab.com\/handbook\/engineering\/infrastructure\/\">\u0160pecialisti na infra\u0161trukt\u00faru<\/a><\/noindex> na GitLab sa staraj\u00fa o prev\u00e1dzku <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/\">GitLab.com<\/a><\/noindex> \u2014 najv\u00e4\u010d\u0161ej in\u0161tancie GitLab na svete. Tu je 3 mili\u00f3ny pou\u017e\u00edvate\u013eov a takmer 7 mili\u00f3nov projektov, a to je jedna z najv\u00e4\u010d\u0161\u00edch open-source SaaS str\u00e1nok s dedikovanou architekt\u00farou. Bez syst\u00e9mu datab\u00e1z PostgreSQL sa GitLab.com \u010faleko nedostane, a \u010do len nerob\u00edme preto, aby sme zabezpe\u010dili odolnos\u0165 v pr\u00edpade ak\u00fdchko\u013evek por\u00fach, pri ktor\u00fdch m\u00f4\u017eeme strati\u0165 d\u00e1ta. Je nepravdepodobn\u00e9, \u017ee by sa tak\u00e1 katastrofa stala, ale dobre sme sa pripravili a z\u00e1sobili r\u00f4znymi mechanizmami z\u00e1lohovania a replik\u00e1cie.<\/p>\n<p><\/p>\n<p>Replik\u00e1cia nie je sp\u00f4sob z\u00e1lohovania datab\u00e1z (<noindex><a rel=\"nofollow\" href=\"https:\/\/about.gitlab.com\/2019\/02\/13\/delayed-replication-for-disaster-recovery-with-postgresql\/#summing-up\">pozri ni\u017e\u0161ie<\/a><\/noindex>). Ale teraz uvid\u00edme, ako r\u00fdchlo obnovi\u0165 n\u00e1hodne odstr\u00e1nen\u00e9 d\u00e1ta pomocou oneskorenej replik\u00e1cie: na <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/\">GitLab.com<\/a><\/noindex> pou\u017e\u00edvate\u013e <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-com\/gl-infra\/production\/issues\/509\">som odstr\u00e1nil skratku<\/a><\/noindex> pre projekt <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-org\/gitlab-ce\/\"><code>gitlab-ce<\/code><\/a><\/noindex> a stratil spojenia s merge-requestmi a \u00falohami.<\/p>\n<p><\/p>\n<p>S oneskorenou replikou sme obnovili d\u00e1ta za iba 1,5 hodiny. Pozrite, ako to bolo.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3 id=\"vosstanovlenie-na-moment-vremeni-s-postgresql\">Obnovenie k ur\u010dit\u00e9mu \u010dasu s PostgreSQL<\/h3>\n<p><\/p>\n<p>PostgreSQL m\u00e1 zabudovan\u00fa funkciu, ktor\u00e1 obnovuje stav datab\u00e1zy na ur\u010dit\u00fd \u010das. Naz\u00fdva sa <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/continuous-archiving.html\">Obnova k ur\u010dit\u00e9mu \u010dasu<\/a><\/noindex> (PITR) a vyu\u017e\u00edva rovnak\u00e9 mechanizmy, ktor\u00e9 udr\u017euj\u00fa aktu\u00e1lnos\u0165 repliky: za\u010dneme spo\u013eahliv\u00fdm sn\u00edmkom cel\u00e9ho klasteru datab\u00e1zy (z\u00e1kladn\u00e1 z\u00e1loha) a aplikujeme s\u00e9riu zmien stavu a\u017e do ur\u010dit\u00e9ho \u010dasu.<\/p>\n<p><\/p>\n<p>Aby sme mohli t\u00fato funkciu pou\u017ei\u0165 pre studen\u00fa z\u00e1lohu, pravidelne rob\u00edme z\u00e1kladn\u00fa z\u00e1lohu datab\u00e1zy a uchov\u00e1vame ju v arch\u00edve (arch\u00edvy GitLab \u017eij\u00fa v <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.google.com\/storage\/\">cloudovom \u00falo\u017eisku Google<\/a><\/noindex>). A sledujeme aj zmeny stavu datab\u00e1zy archivovan\u00edm \u017eurn\u00e1lu predch\u00e1dzaj\u00faceho z\u00e1pisu (<noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/wal-intro.html\">write-ahead log<\/a><\/noindex>, WAL). A s t\u00fdm v\u0161etk\u00fdm m\u00f4\u017eeme vykona\u0165 PITR pre havarijn\u00e9 obnovenie: za\u010d\u00edname so sn\u00edmkom, vykonan\u00fdm pred chybou, a aplikujeme zmeny z arch\u00edvu WAL a\u017e do poruchy.<\/p>\n<p><\/p>\n<h3 id=\"chto-takoe-otlozhennaya-replikaciya\">\u010co je to oneskoren\u00e1 replik\u00e1cia?<\/h3>\n<p><\/p>\n<p>Oneskoren\u00e1 replik\u00e1cia je aplik\u00e1cia zmien z WAL so oneskoren\u00edm. To znamen\u00e1, \u017ee transakcia sa uskuto\u010dnila o hodinu <code>X<\/code>, ale v replik\u00e1cii sa objav\u00ed so oneskoren\u00edm <code>d<\/code> o hodinu <code>X + d<\/code>.<\/p>\n<p><\/p>\n<p>V PostgreSQL s\u00fa 2 sp\u00f4soby, ako nastavi\u0165 fyzick\u00fa replik\u00e1ciu datab\u00e1zy: obnova z arch\u00edvu a streamov\u00e1 replik\u00e1cia. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/archive-recovery-settings.html\">Obnova z arch\u00edvu<\/a><\/noindex>, v podstate funguje ako PITR, ale nepretr\u017eite: neust\u00e1le extrahujeme zmeny z arch\u00edvu WAL a aplikujeme ich na replik\u00e1ciu. A <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.postgresql.org\/wiki\/Streaming_Replication\">streamingov\u00e1 replik\u00e1cia<\/a><\/noindex> priamo extrahuje tok WAL z nadraden\u00e9ho hostite\u013ea datab\u00e1zy. Uprednost\u0148ujeme obnovenie z arch\u00edvu \u2013 je to jednoduch\u0161ie na spr\u00e1vu a m\u00e1 norm\u00e1lny v\u00fdkon, ktor\u00fd sa neli\u0161i od pracovn\u00e9ho klasteru.<\/p>\n<p><\/p>\n<h3 id=\"kak-nastroit-otlozhennoe-vosstanovlenie-iz-arhiva\">Ako nastavi\u0165 oneskoren\u00e9 obnovenie z arch\u00edvu<\/h3>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/recovery-config.html\">Mo\u017enosti obnovy<\/a><\/noindex> s\u00fa op\u00edsan\u00e9 v s\u00fabore <code>recovery.conf<\/code>. Pr\u00edklad:<\/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>S t\u00fdmito parametrami sme nastavili oneskoren\u00fa replik\u00e1ciu s obnoven\u00edm z arch\u00edvu. Tu sa pou\u017e\u00edva <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/wal-e\/wal-e\">wal-e<\/a><\/noindex> na extrakciu segmentov WAL (<code>restore_command<\/code>) z arch\u00edvu, a zmeny sa aplikuj\u00fa za osem hod\u00edn (<code>recovery_min_apply_delay<\/code>). Replika bude sledova\u0165 zmeny \u010dasovej osi v arch\u00edve, napr\u00edklad v pr\u00edpade zlyhania v klastri (<code>recovery_target_timeline<\/code>).<\/p>\n<p><\/p>\n<p>S <code>recovery_min_apply_delay<\/code> je mo\u017en\u00e9 nastavi\u0165 streamovaciu replik\u00e1ciu s oneskoren\u00edm, ale existuje nieko\u013eko \u00faskal\u00ed s\u00favisiacich so slotmi replik\u00e1cie, sp\u00e4tnou v\u00e4zbou hor\u00facej rezervy at\u010f. Arch\u00edv WAL umo\u017e\u0148uje ich ob\u00eds\u0165.<\/p>\n<p><\/p>\n<p>Parameter <code>recovery_min_apply_delay<\/code> sa objavil len v PostgreSQL 9.3. V predch\u00e1dzaj\u00facich verzi\u00e1ch bolo na nastavenie oneskorenej replik\u00e1cie potrebn\u00e9 nastavi\u0165 kombin\u00e1ciu <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/9.3\/functions-admin.html\">funkci\u00ed spr\u00e1vy obnovy<\/a><\/noindex> (<code>pg_xlog_replay_pause(), pg_xlog_replay_resume()<\/code>) alebo uchov\u00e1va\u0165 segmenty WAL v arch\u00edve po\u010das doby oneskorenia.<\/p>\n<p><\/p>\n<h3 id=\"kak-postgresql-eto-delaet\">Ako to rob\u00ed PostgreSQL?<\/h3>\n<p><\/p>\n<p>Je zauj\u00edmav\u00e9 vidie\u0165, ako PostgreSQL implementuje oneskoren\u00e9 obnovenie. Pozrime sa na <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>. Je volan\u00fd z <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/postgres\/postgres\/blob\/c24dcd0cfd949bdf245814c4c2b3df828ee7db36\/src\/backend\/access\/transam\/xlog.c#L7196\">hlavn\u00e9ho cyklu opakovania<\/a><\/noindex> pre ka\u017ed\u00fd z\u00e1znam z 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    \/* ni\u010d nerob\u00edme, ak nie je nakonfigurovan\u00e9 oneskorenie *\/\n    if (recovery_min_apply_delay &lt;= 0)\n        return false;\n\n    \/* \u017eiadne oneskorenie sa neuplat\u0148uje na datab\u00e1zu, ktor\u00e1 e\u0161te nie je konzistentn\u00e1 *\/\n    if (!reachedConsistency)\n        return false;\n\n    \/*\n     * Je to z\u00e1znam COMMIT?\n     *\n     * Z\u00e1merne sa rozhodujeme neodklada\u0165 aborty, preto\u017ee nemaj\u00fa \u017eiadny vplyv na\n     * MVCC. U\u017e umo\u017e\u0148ujeme prehr\u00e1vanie z\u00e1znamov, ktor\u00e9 nemaj\u00fa \u010dasov\u00fa pe\u010da\u0165,\n     * tak\u017ee u\u017e existuje mo\u017enos\u0165 probl\u00e9mov sp\u00f4soben\u00fdch skor\u00fdmi konfliktami na\n     * stand-by.\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     * Ukon\u010di\u0165 bez zbrojenia sp\u00fa\u0161\u0165acieho, ak u\u017e uplynul \u010das na uplatnenie tohto\n     * z\u00e1znamu\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        \/\/ Skr\u00e1til:\n        \/\/ Pou\u017eit\u00ed WaitLatch, k\u00fdm nedosiahne recoveryDelayUntilTime\n        \/\/ a potom\n        break;\n    }\n    return true;\n}<\/code><\/pre>\n<p><\/p>\n<p>Podstatn\u00e9 je, \u017ee oneskorenie je zalo\u017een\u00e9 na fyzickom \u010dase zap\u00edsanom v \u010dasovej pe\u010dati komitnej transakcie (<code>xtime<\/code>). Ako je vidno, oneskorenie sa uplat\u0148uje iba na komitmy a net\u00fdka sa ostatn\u00fdch z\u00e1znamov \u2014 v\u0161etky zmeny sa uplat\u0148uj\u00fa priamo, zatia\u013e \u010do komit sa odklad\u00e1, tak\u017ee uvid\u00edme zmeny a\u017e po nastavenom oneskoren\u00ed.<\/p>\n<p><\/p>\n<h3 id=\"kak-ispolzovat-otlozhennuyu-repliku-dlya-vosstanovleniya-dannyh\">Ako pou\u017ei\u0165 oneskoren\u00fa replik\u00e1ciu na obnovu d\u00e1t<\/h3>\n<p><\/p>\n<p>Predpokladajme, \u017ee v produkcii m\u00e1me datab\u00e1zov\u00fd klaster a replik\u00e1ciu s osemhodinov\u00fdm oneskoren\u00edm. Pozrime sa, ako obnovi\u0165 d\u00e1ta na pr\u00edklade <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-com\/gl-infra\/production\/issues\/509\">n\u00e1hodn\u00e9ho vymazania zna\u010diek<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Ke\u010f sme sa dozvedeli o probl\u00e9me, my <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/9.3\/functions-admin.html\">pozastavili sme obnovu z arch\u00edvu<\/a><\/noindex> pre oneskoren\u00fa replik\u00e1ciu:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">SELECT pg_xlog_replay_pause();<\/code><\/pre>\n<p><\/p>\n<p>S pozastaven\u00edm sme nemali riziko, \u017ee replik\u00e1cia zopakuje po\u017eiadavok <code>DELETE<\/code>. U\u017eite\u010dn\u00e1 vec, ak potrebujeme \u010das na v\u0161etko pochopi\u0165.<\/p>\n<p><\/p>\n<p>Podstatn\u00e9 je, \u017ee oneskoren\u00e1 replik\u00e1cia by mala dosiahnu\u0165 \u010das pred po\u017eiadavkou <code>DELETE<\/code>. Pribli\u017ene sme vedeli fyzick\u00fd \u010das odstr\u00e1nenia. Odstr\u00e1nili sme <code>recovery_min_apply_delay<\/code> a pridali <code>recovery_target_time<\/code> v <code>recovery.conf<\/code>. Takto replik\u00e1cia dosiahne potrebn\u00fd \u010das bez oneskoren\u00ed:<\/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>S \u010dasov\u00fdmi pe\u010da\u0165ami je dobr\u00e9 zn\u00ed\u017ei\u0165 zbyto\u010dn\u00e9, aby sme sa netrafili. Pravda, \u010d\u00edm viac zn\u00ed\u017eenia, t\u00fdm viac d\u00e1t str\u00e1came. Op\u00e4\u0165, ak prejdeme po\u017eiadavku <code>DELETE<\/code>, v\u0161etko sa op\u00e4\u0165 vyma\u017ee a bude potrebn\u00e9 za\u010da\u0165 odznova (alebo si vzia\u0165 studen\u00fa z\u00e1lohu na PITR).<\/p>\n<p><\/p>\n<p>Znovu sme spustili odlo\u017een\u00fa in\u0161tanciu Postgres a segmenty WAL sa opakovali do ur\u010den\u00e9ho \u010dasu. Pokrok v tejto f\u00e1ze je mo\u017en\u00e9 sledova\u0165 pomocou dotazu:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">SELECT\n  -- aktu\u00e1lna poloha v WAL\n  pg_last_xlog_replay_location(),\n  -- aktu\u00e1lny \u010dasov\u00fd pe\u010diatok transakcie (stav repliky)\n  pg_last_xact_replay_timestamp(),\n  -- aktu\u00e1lny fyzick\u00fd \u010das\n  now(),\n  -- mno\u017estvo \u010dasu, ktor\u00e9 sa e\u0161te mus\u00ed aplikova\u0165, k\u00fdm sa dosiahne recovery_target_time\n  '2018-10-12 09:25:00+00'::timestamptz - pg_last_xact_replay_timestamp() as delay;<\/code><\/pre>\n<p><\/p>\n<p>Ak sa \u010dasov\u00e1 pe\u010diatka u\u017e nezmen\u00ed, obnovenie je dokon\u010den\u00e9. M\u00f4\u017eeme nastavi\u0165 akciu <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/recovery-target-settings.html\"><code>recovery_target_action<\/code><\/a><\/noindex>, aby sme uzavreli, posunuli alebo pozastavili in\u0161tanciu po opakovan\u00ed (prednastaven\u00e9 je pozastavenie).<\/p>\n<p><\/p>\n<p>Datab\u00e1za sa dostala do stavu pred t\u00fdm ne\u0161\u0165astn\u00fdm dotazom. Teraz m\u00f4\u017eeme napr\u00edklad exportova\u0165 \u00fadaje. Exportovali sme vymazan\u00e9 \u00fadaje o \u0161t\u00edtku a v\u0161etky spojenia s \u00falohami a merge-requestmi a preniesli ich do pracovnej datab\u00e1zy. Ak s\u00fa straty rozsiahle, m\u00f4\u017eeme jednoducho posun\u00fa\u0165 replik\u00e1ciu a pou\u017ei\u0165 ju ako hlavn\u00fa. Ale potom pr\u00eddeme o v\u0161etky zmeny po momente, do ktor\u00e9ho sme sa obnovili.<\/p>\n<p><\/p>\n<p>Namiesto \u010dasov\u00fdch pe\u010diatok je lep\u0161ie pou\u017e\u00edva\u0165 ID transakci\u00ed. Je u\u017eito\u010dn\u00e9 tieto ID zapisova\u0165, napr\u00edklad pre oper\u00e1tory DDL (ako je <code>DROP TABLE<\/code>), pomocou <code>log_statements = 'ddl'<\/code>. Keby sme mali ID transakcie, vzali by sme <code>recovery_target_xid<\/code> a pre\u0161li v\u0161etko a\u017e po transakciu pred dopytom. <code>DELETE<\/code>.<\/p>\n<p><\/p>\n<p>Je ve\u013emi jednoduch\u00e9 vr\u00e1ti\u0165 sa k pr\u00e1ci: vyma\u017eete v\u0161etky zmeny z <code>recovery.conf<\/code> a znovu spust\u00edte Postgres. \u010coskoro sa v replik\u00e1cii op\u00e4\u0165 objav\u00ed osemhodinov\u00e9 oneskorenie a sme pripraven\u00ed na bud\u00face probl\u00e9my.<\/p>\n<p><\/p>\n<h3 id=\"preimuschestva-dlya-vosstanovleniya\">V\u00fdhody obnovenia<\/h3>\n<p><\/p>\n<p>S odlo\u017eenou replikou nemus\u00edme hodiny obnovova\u0165 cel\u00fd sn\u00edmok z arch\u00edvu ako pri studenom z\u00e1lohovan\u00ed. Napr\u00edklad potrebujeme p\u00e4\u0165 hod\u00edn, aby sme dostali cel\u00fa z\u00e1kladn\u00fa z\u00e1lohu na 2 TB. A potom mus\u00edme e\u0161te aplikova\u0165 cel\u00fd denn\u00fd WAL, aby sme sa dostali do po\u017eadovan\u00e9ho stavu (v najhor\u0161om pr\u00edpade).<\/p>\n<p><\/p>\n<p>Odlo\u017een\u00e1 replik\u00e1cia je lep\u0161ia ako studen\u00e9 z\u00e1lohovanie z dvoch bodov:<\/p>\n<p><\/p>\n<ol>\n<li>Nie je potrebn\u00e9 vy\u0165ahova\u0165 cel\u00fa z\u00e1kladn\u00fa z\u00e1lohu z arch\u00edvu.<\/li>\n<li>Existuje fixn\u00e9 osemhodinov\u00e9 okno segmentov WAL, ktor\u00e9 treba zopakova\u0165.<\/li>\n<\/ol>\n<p><\/p>\n<p>A navy\u0161e neust\u00e1le kontrolujeme, \u010di je mo\u017en\u00e9 vykona\u0165 PITR z WAL, a r\u00fdchlo by sme si v\u0161imli po\u0161kodenia alebo in\u00e9 probl\u00e9my s arch\u00edvom WAL, sleduj\u00fac odstup odlo\u017eenej repliky.<\/p>\n<p><\/p>\n<p>V tomto pr\u00edklade sme potrebovali 50 min\u00fat na obnovenie, \u010do znamen\u00e1, \u017ee r\u00fdchlos\u0165 bola 110 GB d\u00e1t WAL za hodinu (arch\u00edv bol st\u00e1le na <noindex><a rel=\"nofollow\" href=\"https:\/\/aws.amazon.com\/s3\/\">AWS S3<\/a><\/noindex>). Celkovo sme probl\u00e9m vyrie\u0161ili a obnovili d\u00e1ta za 1,5 hodiny.<\/p>\n<p><\/p>\n<h3 id=\"itogi-gde-prigoditsya-otlozhennaya-replika-a-gde-net\">Zhrnutie: kde je u\u017eito\u010dn\u00e1 oneskoren\u00e1 replik\u00e1cia (a kde nie)<\/h3>\n<p><\/p>\n<p>Pou\u017eite oneskoren\u00fa replik\u00e1ciu ako prostriedok prvej pomoci, ak ste n\u00e1hodne stratili d\u00e1ta a uvedomili si tento probl\u00e9m v r\u00e1mci nastaven\u00e9ho zdr\u017eania.<\/p>\n<p><\/p>\n<blockquote><p>Ale majte na pam\u00e4ti: replik\u00e1cia nie je z\u00e1loha.<\/p><\/blockquote>\n<p>Z\u00e1loha a replik\u00e1cia maj\u00fa r\u00f4zne ciele. Studen\u00e1 z\u00e1loha bude u\u017eito\u010dn\u00e1, ak ste n\u00e1hodou vykonali <code>DELETE<\/code> alebo <code>DROP TABLE<\/code>. Rob\u00edme z\u00e1lohu zo studen\u00e9ho \u00falo\u017eiska a obnovujeme predch\u00e1dzaj\u00faci stav tabulky alebo celej datab\u00e1zy. Ale v tomto pr\u00edpade sa dopyt <code>DROP TABLE<\/code> takmer okam\u017eite reprodukuje vo v\u0161etk\u00fdch replik\u00e1ch na pracovnom klastri, tak\u017ee be\u017en\u00e1 replik\u00e1cia tu nepom\u00f4\u017ee. Samotn\u00e1 replik\u00e1cia udr\u017eiava datab\u00e1zu dostupn\u00fa, ke\u010f sa odovzdaj\u00fa jednotliv\u00e9 servery, a rozde\u013euje z\u00e1\u0165a\u017e.<\/p>\n<p><\/p>\n<p>Aj s oneskorenou replik\u00e1ciou potrebujeme niekedy ve\u013emi studen\u00fa z\u00e1lohu na bezpe\u010dnom mieste, ak sa n\u00e1hodou vyskytne v\u00fdpadok d\u00e1tov\u00e9ho centra, skryt\u00e9 po\u0161kodenie alebo in\u00e9 udalosti, ktor\u00e9 si hne\u010f nev\u0161imnete. Tu od jednej replik\u00e1cie nie je \u017eiadny \u00fa\u017eitok.<\/p>\n<p><\/p>\n<p><strong>Pozn\u00e1mka<\/strong>. Na <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/\">GitLab.com<\/a><\/noindex> teraz chr\u00e1nime pred stratou d\u00e1t iba na \u00farovni syst\u00e9mu a neobnovujeme d\u00e1ta na \u00farovni pou\u017e\u00edvate\u013ea.<\/p>\n<p>Zdroj: <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.4 - 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\/sk\/blog\/administrirovanie\/kak-my-ispolzovali-otlozhennuyu-replikatsiyu-dlya-avarijnogo-vosstanovleniya-s-postgresql\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sk_SK\" \/>\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\/sk\/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\udd47Ako sme pou\u017eili oneskoren\u00fa replik\u00e1ciu na obnovenie po hav\u00e1rii s PostgreSQL | ProHoster","description":".","canonical_url":"https:\/\/prohoster.info\/sk\/blog\/administrirovanie\/kak-my-ispolzovali-otlozhennuyu-replikatsiyu-dlya-avarijnogo-vosstanovleniya-s-postgresql","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sk_SK","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\/sk\/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\/sk\/wp-json\/wp\/v2\/posts\/30356","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/comments?post=30356"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/posts\/30356\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/media\/22360"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/media?parent=30356"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/categories?post=30356"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/tags?post=30356"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}