{"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\/cs\/blog\/administrirovanie\/kak-my-ispolzovali-otlozhennuyu-replikatsiyu-dlya-avarijnogo-vosstanovleniya-s-postgresql","title":{"rendered":"Jak jsme pou\u017eili asynchronn\u00ed replikaci pro obnoven\u00ed po hav\u00e1rii s PostgreSQL","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Jak jsme pou\u017eili asynchronn\u00ed replikaci pro obnoven\u00ed po hav\u00e1rii s PostgreSQL\" src=\"\/wp-content\/uploads\/2019\/03\/773f3b6c8d173be91c49066d7067bad3.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nReplikace nen\u00ed z\u00e1loha. Nebo ano? Tady je n\u00e1\u0161 zp\u016fsob, jak jsme pou\u017eili asynchronn\u00ed replikaci pro obnoven\u00ed po n\u00e1hodn\u00e9m smaz\u00e1n\u00ed zkratek.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/about.gitlab.com\/handbook\/engineering\/infrastructure\/\">Infrastrukturn\u00ed specialist\u00e9<\/a><\/noindex> na GitLabu jsou zodpov\u011bdn\u00ed za provoz <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/\">GitLab.com<\/a><\/noindex> \u2014 nejv\u011bt\u0161\u00ed instance GitLabu na sv\u011bt\u011b. Zde je 3 miliony u\u017eivatel\u016f a t\u00e9m\u011b\u0159 7 milion\u016f projekt\u016f, co\u017e z n\u011bj \u010din\u00ed jeden z nejv\u011bt\u0161\u00edch open-source SaaS web\u016f s dedikovanou architekturou. Bez datab\u00e1zov\u00e9ho syst\u00e9mu PostgreSQL by GitLab.com daleko nedo\u0161el, a d\u011bl\u00e1me v\u0161e pro to, abychom zajistili odolnost proti jak\u00fdmkoliv selh\u00e1n\u00edm, kdy by mohly b\u00fdt ztraceny \u00fadaje. Takov\u00e1 katastrofa pravd\u011bpodobn\u011b nenastane, ale jsme dob\u0159e p\u0159ipraveni a m\u00e1me r\u016fzn\u00e9 mechanismy z\u00e1lohov\u00e1n\u00ed a replikace.<\/p>\n<p><\/p>\n<p>Replikace, to nen\u00ed z\u00e1lohov\u00e1n\u00ed datab\u00e1z\u00ed (<noindex><a rel=\"nofollow\" href=\"https:\/\/about.gitlab.com\/2019\/02\/13\/delayed-replication-for-disaster-recovery-with-postgresql\/#summing-up\">viz n\u00ed\u017ee<\/a><\/noindex>). Ale nyn\u00ed uvid\u00edme, jak rychle obnovit n\u00e1hodn\u011b smazan\u00e1 data pomoc\u00ed asynchronn\u00ed replikace: na <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/\">GitLab.com<\/a><\/noindex> u\u017eivateli <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-com\/gl-infra\/production\/issues\/509\">smazal zkratku<\/a><\/noindex> pro projekt <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-org\/gitlab-ce\/\"><code>gitlab-ce<\/code><\/a><\/noindex> a ztratil vazbu na merge requesty a \u00fakoly.<\/p>\n<p><\/p>\n<p>S asynchronn\u00ed replikac\u00ed jsme obnovili data za pouh\u00e9 1,5 hodiny. Pod\u00edvejte se, jak to bylo.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3 id=\"vosstanovlenie-na-moment-vremeni-s-postgresql\">Obnoven\u00ed do bodu v \u010dase s PostgreSQL<\/h3>\n<p><\/p>\n<p>PostgreSQL m\u00e1 vestav\u011bnou funkci, kter\u00e1 obnovuje stav datab\u00e1ze do ur\u010dit\u00e9ho bodu v \u010dase. \u0158\u00edk\u00e1 se j\u00ed <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/continuous-archiving.html\">Obnova do bodu v \u010dase<\/a><\/noindex> (PITR) a pou\u017e\u00edv\u00e1 stejn\u00e9 mechanismy, kter\u00e9 zaji\u0161\u0165uj\u00ed aktu\u00e1lnost repliky: za\u010d\u00edn\u00e1me d\u016fv\u011bryhodn\u00fdm sn\u00edmkem cel\u00e9ho datab\u00e1zov\u00e9ho klastru (z\u00e1kladn\u00ed z\u00e1loha) a aplikujeme s\u00e9rii zm\u011bn stavu a\u017e do ur\u010dit\u00e9ho okam\u017eiku.<\/p>\n<p><\/p>\n<p>Abychom mohli tuto funkci pou\u017e\u00edt pro studenou z\u00e1lohu, pravideln\u011b prov\u00e1d\u00edme z\u00e1kladn\u00ed z\u00e1lohu datab\u00e1ze a uchov\u00e1v\u00e1me ji v archivu (archivy GitLabu \u017eij\u00ed v <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.google.com\/storage\/\">cloudov\u00e9m \u00falo\u017ei\u0161ti Google<\/a><\/noindex>). Tak\u00e9 sledujeme zm\u011bny stavu datab\u00e1ze archivov\u00e1n\u00edm protokolu p\u0159edb\u011b\u017en\u00e9ho z\u00e1pisu (<noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/wal-intro.html\">protokol p\u0159edb\u011b\u017en\u00e9ho z\u00e1pisu<\/a><\/noindex>, WAL). S t\u00edmto v\u0161\u00edm m\u016f\u017eeme prov\u00e9st PITR pro obnovu po hav\u00e1rii: za\u010d\u00edn\u00e1me se sn\u00edmkem p\u0159ed chybou a aplikujeme zm\u011bny z archivu WAL a\u017e do selh\u00e1n\u00ed.<\/p>\n<p><\/p>\n<h3 id=\"chto-takoe-otlozhennaya-replikaciya\">Co je to asynchronn\u00ed replikace?<\/h3>\n<p><\/p>\n<p>Asynchronn\u00ed replikace je aplikace zm\u011bn z WAL se zpo\u017ed\u011bn\u00edm. To znamen\u00e1, \u017ee transakce se stala v hodin\u011b <code>X<\/code>, ale v replikaci se objev\u00ed se zpo\u017ed\u011bn\u00edm <code>\u2013 perioda ant\u00e9nn\u00ed m\u0159\u00ed\u017eky (vzd\u00e1lenost mezi sousedn\u00edmi prvky),<\/code> o hodinu <code>X + d<\/code>.<\/p>\n<p><\/p>\n<p>V PostgreSQL existuj\u00ed 2 zp\u016fsoby, jak nastavit fyzickou replikaci datab\u00e1ze: obnovu z archivu a streamovac\u00ed replikaci. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/archive-recovery-settings.html\">Obnova z archivu<\/a><\/noindex>, v podstat\u011b funguje jako PITR, ale neust\u00e1le: neust\u00e1le extrahujeme zm\u011bny z archivu WAL a aplikujeme je na replikaci. A <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.postgresql.org\/wiki\/Streaming_Replication\">streamovac\u00ed replikace<\/a><\/noindex> p\u0159\u00edmo extrahuje tok WAL z nad\u0159azen\u00e9ho hostitele datab\u00e1ze. Preferujeme obnovu z archivu \u2014 je snaz\u0161\u00ed s n\u00ed manipulovat a m\u00e1 norm\u00e1ln\u00ed v\u00fdkon, kter\u00fd nen\u00ed pozadu za pracovn\u00edm clusterem.<\/p>\n<p><\/p>\n<h3 id=\"kak-nastroit-otlozhennoe-vosstanovlenie-iz-arhiva\">Jak nastavit zpo\u017ed\u011bnou obnovu z archivu<\/h3>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/recovery-config.html\">Parametry obnovy<\/a><\/noindex> jsou pops\u00e1ny v souboru <code>recovery.conf<\/code>. P\u0159\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\u011bmito parametry jsme nastavili zpo\u017ed\u011bnou replikaci s obnovou z archivu. Pou\u017e\u00edv\u00e1 se zde <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/wal-e\/wal-e\">wal-e<\/a><\/noindex> k extrakci segment\u016f WAL (<code>restore_command<\/code>) z archivu, a zm\u011bny budou aplikov\u00e1ny po osmi hodin\u00e1ch (<code>recovery_min_apply_delay<\/code>). Replika bude sledovat zm\u011bny \u010dasov\u00e9 osy v archivu, nap\u0159\u00edklad kv\u016fli vy\u0159azen\u00ed v clusteru (<code>recovery_target_timeline<\/code>).<\/p>\n<p><\/p>\n<p>S <code>recovery_min_apply_delay<\/code> je mo\u017en\u00e9 nastavit streamovac\u00ed replikaci se zpo\u017ed\u011bn\u00edm, ale zde jsou n\u011bkter\u00e9 n\u00e1strahy spojen\u00e9 se sloty replikace, zp\u011btnou vazbou hork\u00e9 rezervy a dal\u0161\u00edmi. Archiv WAL umo\u017e\u0148uje jejich vyhnut\u00ed.<\/p>\n<p><\/p>\n<p>Parameter <code>recovery_min_apply_delay<\/code> se objevil pouze v PostgreSQL 9.3. V p\u0159edchoz\u00edch verz\u00edch bylo nutn\u00e9 nastavit kombinaci <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/9.3\/functions-admin.html\">funkc\u00ed pro spr\u00e1vu obnovy<\/a><\/noindex> (<code>pg_xlog_replay_pause(), pg_xlog_replay_resume()<\/code>) nebo uchov\u00e1vat segmenty WAL v archivu po dobu zpo\u017ed\u011bn\u00ed.<\/p>\n<p><\/p>\n<h3 id=\"kak-postgresql-eto-delaet\">Jak PostgreSQL to d\u011bl\u00e1?<\/h3>\n<p><\/p>\n<p>Zaj\u00edmav\u00e9 je pod\u00edvat se, jak PostgreSQL realizuje zpo\u017ed\u011bnou obnovu. Pod\u00edvejme se 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 vol\u00e1na z <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/postgres\/postgres\/blob\/c24dcd0cfd949bdf245814c4c2b3df828ee7db36\/src\/backend\/access\/transam\/xlog.c#L7196\">hlavn\u00edho cyklu opakov\u00e1n\u00ed<\/a><\/noindex> pro ka\u017edou polo\u017eku 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    \/* nic se ned\u011bje, pokud nen\u00ed nastavena \u017e\u00e1dn\u00e1 prodleva *\/\n    if (recovery_min_apply_delay &lt;= 0)\n        return false;\n\n    \/* \u017e\u00e1dn\u00e1 prodleva se nepou\u017e\u00edv\u00e1 na datab\u00e1zi, kter\u00e1 je\u0161t\u011b nen\u00ed konzistentn\u00ed *\/\n    if (!reachedConsistency)\n        return false;\n\n    \/*\n     * Je to z\u00e1znam COMMIT?\n     *\n     * Z\u00e1m\u011brn\u011b se rozhodujeme nezdr\u017eovat zru\u0161en\u00ed, proto\u017ee nem\u00e1 vliv na\n     * MVCC. U\u017e nyn\u00ed umo\u017e\u0148ujeme p\u0159ehr\u00e1v\u00e1n\u00ed z\u00e1znam\u016f, kter\u00e9 nemaj\u00ed \u010dasov\u00e9 raz\u00edtko,\n     * tak\u017ee u\u017e je zde p\u0159\u00edle\u017eitost k probl\u00e9m\u016fm zp\u016fsoben\u00fdm p\u0159ed\u010dasn\u00fdmi konflikty na\n     * z\u00e1loh\u00e1ch.\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\u010dete bez spu\u0161t\u011bn\u00ed latch, pokud u\u017e je po \u010dase pou\u017e\u00edt tento\n     * z\u00e1znam\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        \/\/ Zkr\u00e1ceno:\n        \/\/ Pou\u017eijte WaitLatch, dokud nedos\u00e1hneme recoveryDelayUntilTime\n        \/\/ a pak\n        break;\n    }\n    return true;\n}<\/code><\/pre>\n<p><\/p>\n<p>Ji\u017e na tom z\u00e1le\u017e\u00ed, proto\u017ee prodleva je zalo\u017eena na fyzick\u00e9m \u010dase zaznamenan\u00e9m v \u010dasov\u00e9m raz\u00edtku commitu transakce (<code>xtime<\/code>). Jak je vid\u011bt, prodleva se aplikuje pouze na commity a nedot\u00fdk\u00e1 se ostatn\u00edch z\u00e1znam\u016f \u2014 v\u0161echny zm\u011bny se aplikuj\u00ed p\u0159\u00edmo, a commit se oddaluje, tak\u017ee vid\u00edme zm\u011bny a\u017e po nastaven\u00e9 prodlev\u011b.<\/p>\n<p><\/p>\n<h3 id=\"kak-ispolzovat-otlozhennuyu-repliku-dlya-vosstanovleniya-dannyh\">Jak pou\u017e\u00edvat odlo\u017eenou replikaci pro obnoven\u00ed dat<\/h3>\n<p><\/p>\n<p>P\u0159edstavme si, \u017ee m\u00e1me v produkci cluster datab\u00e1ze a replikaci s osmihodinovou prodlevou. Pod\u00edvejme se, jak obnovit data na p\u0159\u00edkladu <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-com\/gl-infra\/production\/issues\/509\">n\u00e1hodn\u00e9ho smaz\u00e1n\u00ed z\u00e1znam\u016f<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Kdy\u017e jsme se o probl\u00e9mu dozv\u011bd\u011bli, my <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/9.3\/functions-admin.html\">pozastavili obnoven\u00ed z archivu<\/a><\/noindex> pro odlo\u017eenou replikaci:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">SELECT pg_xlog_replay_pause();<\/code><\/pre>\n<p><\/p>\n<p>S pauzou jsme nem\u011bli riziko, \u017ee by replikace zopakovala p\u0159\u00edkaz <code>DELETE<\/code>. U\u017eite\u010dn\u00e1 funkce, pokud je pot\u0159eba si v\u0161e v klidu promyslet.<\/p>\n<p><\/p>\n<p>Ji\u017e na tom z\u00e1le\u017e\u00ed, proto\u017ee odlo\u017een\u00e1 replikace by m\u011bla dos\u00e1hnout okam\u017eiku p\u0159ed p\u0159\u00edkazem <code>DELETE<\/code>. P\u0159ibli\u017en\u011b jsme v\u011bd\u011bli fyzick\u00fd \u010das smaz\u00e1n\u00ed. Smazali jsme <code>recovery_min_apply_delay<\/code> a p\u0159idali <code>recovery_target_time<\/code> v <code>recovery.conf<\/code>. Tak replikace dos\u00e1hne pot\u0159ebn\u00e9ho okam\u017eiku bez prodlen\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 raz\u00edtky je lep\u0161\u00ed ubrat v\u00edc, abychom se netrefili vedle. Pravda, \u010d\u00edm v\u00edc ubr\u00e1n\u00edme, t\u00edm v\u00edc dat ztr\u00e1c\u00edme. Znovu, pokud p\u0159ehl\u00e9dneme p\u0159\u00edkaz <code>DELETE<\/code>, v\u0161echno se znovu sma\u017ee a budeme muset za\u010d\u00edt znovu (nebo \u00fapln\u011b vz\u00edt studenou z\u00e1lohu pro PITR).<\/p>\n<p><\/p>\n<p>Restartovali jsme odlo\u017eenou instanci Postgres a segmenty WAL se opakovaly do uveden\u00e9ho \u010dasu. Pokrok v t\u00e9to f\u00e1zi lze sledovat dotazem:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">SELECT\n  -- aktu\u00e1ln\u00ed um\u00edst\u011bn\u00ed v WAL\n  pg_last_xlog_replay_location(),\n  -- aktu\u00e1ln\u00ed \u010dasov\u00e1 zna\u010dka transakce (stav repliky)\n  pg_last_xact_replay_timestamp(),\n  -- aktu\u00e1ln\u00ed fyzick\u00fd \u010das\n  now(),\n  -- mno\u017estv\u00ed \u010dasu, kter\u00e9 je st\u00e1le t\u0159eba aplikovat, dokud nebude dosa\u017eeno 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>Pokud se \u010dasov\u00e1 zna\u010dka u\u017e nem\u011bn\u00ed, obnoven\u00ed je dokon\u010deno. Lze nastavit akci <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/recovery-target-settings.html\"><code>recovery_target_action<\/code><\/a><\/noindex>, kter\u00e1 uzav\u0159e, posune nebo pozastav\u00ed instanci po opakov\u00e1n\u00ed (v\u00fdchoz\u00ed je pozastaven\u00ed).<\/p>\n<p><\/p>\n<p>Datab\u00e1ze se dostala do stavu p\u0159ed onou ne\u0161\u0165astnou \u017e\u00e1dost\u00ed. Nyn\u00ed je mo\u017en\u00e9 nap\u0159\u00edklad exportovat data. Exportovali jsme odstran\u011bn\u00e1 data o \u0161t\u00edtku a v\u0161echny vazby na \u00fakoly a merge requesty a p\u0159enesli je do pracovn\u00ed datab\u00e1ze. Pokud jsou ztr\u00e1ty rozs\u00e1hl\u00e9, lze replikaci jednodu\u0161e posunout a pou\u017e\u00edt ji jako prim\u00e1rn\u00ed. Ale v tom p\u0159\u00edpad\u011b se ztrat\u00ed v\u0161echny zm\u011bny od okam\u017eiku, do kter\u00e9ho jsme se vr\u00e1tili.<\/p>\n<p><\/p>\n<p>M\u00edsto \u010dasov\u00fdch zna\u010dek je lep\u0161\u00ed pou\u017e\u00edvat ID transakc\u00ed. Je u\u017eite\u010dn\u00e9 zapisovat tato ID, nap\u0159\u00edklad pro oper\u00e1tory DDL (typu <code>DROP TABLE<\/code>), pomoc\u00ed <code>log_statements = 'ddl'<\/code>. Kdybychom m\u011bli ID transakce, vzali bychom <code>recovery_target_xid<\/code> a spustili v\u0161echno a\u017e do transakce p\u0159ed \u017e\u00e1dost\u00ed. <code>DELETE<\/code>.<\/p>\n<p><\/p>\n<p>Vr\u00e1tit se k pr\u00e1ci je velmi jednoduch\u00e9: odstra\u0148te v\u0161echny zm\u011bny z <code>recovery.conf<\/code> a restartujte Postgres. Brzy se v replikaci op\u011bt objev\u00ed osmihodinov\u00e9 zpo\u017ed\u011bn\u00ed a jsme p\u0159ipraveni na budouc\u00ed pot\u00ed\u017ee.<\/p>\n<p><\/p>\n<h3 id=\"preimuschestva-dlya-vosstanovleniya\">V\u00fdhody pro obnovu<\/h3>\n<p><\/p>\n<p>S odlo\u017eenou replikou nen\u00ed t\u0159eba hodiny obnovovat celou sn\u00edmku z archivu. Nap\u0159\u00edklad n\u00e1m trv\u00e1 p\u011bt hodin, ne\u017e z\u00edsk\u00e1me cel\u00fd z\u00e1kladn\u00ed z\u00e1lohu o velikosti 2 TB. A pak je\u0161t\u011b mus\u00edme aplikovat cel\u00e9 denn\u00ed WAL, abychom se vr\u00e1tili do po\u017eadovan\u00e9ho stavu (v nejhor\u0161\u00edm p\u0159\u00edpad\u011b).<\/p>\n<p><\/p>\n<p>Odlo\u017een\u00e1 replika je lep\u0161\u00ed ne\u017e studen\u00e1 z\u00e1loha z dvou d\u016fvod\u016f:<\/p>\n<p><\/p>\n<ol>\n<li>Nen\u00ed nutn\u00e9 z\u00edsk\u00e1vat celou z\u00e1kladn\u00ed z\u00e1lohu z archivu.<\/li>\n<li>Existuje pevn\u00e9 osmihodinov\u00e9 okno segment\u016f WAL, kter\u00e9 je t\u0159eba opakovat.<\/li>\n<\/ol>\n<p><\/p>\n<p>A tak\u00e9 neust\u00e1le kontrolujeme, zda lze prov\u00e1d\u011bt PITR z WAL, a rychle bychom si v\u0161imli po\u0161kozen\u00ed nebo jin\u00fdch probl\u00e9m\u016f s arch\u00edvem WAL, sledov\u00e1n\u00edm zpo\u017ed\u011bn\u00ed odlo\u017een\u00e9 repliky.<\/p>\n<p><\/p>\n<p>V tomto p\u0159\u00edkladu n\u00e1m obnovov\u00e1n\u00ed trvalo 50 minut, co\u017e znamen\u00e1, \u017ee rychlost byla 110 GB dat WAL za hodinu (arch\u00edv tehdy st\u00e1le byl na <noindex><a rel=\"nofollow\" href=\"https:\/\/aws.amazon.com\/s3\/\">AWS S3<\/a><\/noindex>). Celkem jsme probl\u00e9m vy\u0159e\u0161ili a obnovili data za 1,5 hodiny.<\/p>\n<p><\/p>\n<h3 id=\"itogi-gde-prigoditsya-otlozhennaya-replika-a-gde-net\">Shrnut\u00ed: kde se hod\u00ed zpo\u017ed\u011bn\u00e1 replikace (a kde ne)<\/h3>\n<p><\/p>\n<p>Pou\u017eijte zpo\u017ed\u011bnou replikaci jako prvn\u00ed pomoc, pokud jste n\u00e1hodou ztratili data a v\u0161imli si t\u00e9to pot\u00ed\u017ee v r\u00e1mci nastaven\u00e9ho zpo\u017ed\u011bn\u00ed.<\/p>\n<p><\/p>\n<blockquote><p>Ale pamatujte: replikace nen\u00ed z\u00e1loha.<\/p><\/blockquote>\n<p>Z\u00e1loha a replikace maj\u00ed r\u016fzn\u00e9 c\u00edle. Studen\u00e1 z\u00e1loha je u\u017eite\u010dn\u00e1, pokud jste n\u00e1hodou ud\u011blali <code>DELETE<\/code> nebo <code>DROP TABLE<\/code>. D\u011bl\u00e1me z\u00e1lohu ze studen\u00e9ho \u00falo\u017ei\u0161t\u011b a obnovujeme p\u0159edchoz\u00ed stav tabulky nebo cel\u00e9 datab\u00e1ze. Ale z\u00e1rove\u0148 je dotaz <code>DROP TABLE<\/code> t\u00e9m\u011b\u0159 okam\u017eit\u011b reprodukov\u00e1n ve v\u0161ech replik\u00e1ch na pracovn\u00edm clusteru, tak\u017ee obvykl\u00e1 replikace tu nezachr\u00e1n\u00ed. Sama o sob\u011b replikace udr\u017euje datab\u00e1zi dostupnou, kdy\u017e se odevzd\u00e1vaj\u00ed jednotliv\u00e9 servery, a rozd\u011bluje z\u00e1t\u011b\u017e.<\/p>\n<p><\/p>\n<p>I s zpo\u017ed\u011bnou replikac\u00ed n\u00e1m n\u011bkdy velmi pom\u016f\u017ee studen\u00e1 z\u00e1loha na bezpe\u010dn\u00e9m m\u00edst\u011b, pokud dojde k v\u00fdpadku datov\u00e9ho centra, skryt\u00e9mu po\u0161kozen\u00ed nebo jin\u00fdm ud\u00e1lostem, kter\u00e9 okam\u017eit\u011b nezaznamen\u00e1te. Tady od jedn\u00e9 replikace nen\u00ed \u017e\u00e1dn\u00fd u\u017eitek.<\/p>\n<p><\/p>\n<p><strong>Pozn\u00e1mka<\/strong>. Na <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/\">GitLab.com<\/a><\/noindex> chr\u00e1n\u00edme nyn\u00ed ztr\u00e1tu dat pouze na \u00farovni syst\u00e9mu a neobnovujeme data na \u00farovni u\u017eivatele.<\/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.3 - 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\/cs\/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.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"cs_CZ\" \/>\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\/cs\/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\udd47Jak jsme pou\u017eili zpo\u017ed\u011bnou replikaci pro obnovu po hav\u00e1rii s PostgreSQL | ProHoster","description":".","canonical_url":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/kak-my-ispolzovali-otlozhennuyu-replikatsiyu-dlya-avarijnogo-vosstanovleniya-s-postgresql","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"cs_CZ","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\/cs\/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\/cs\/wp-json\/wp\/v2\/posts\/30356","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/comments?post=30356"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts\/30356\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media\/22360"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media?parent=30356"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/categories?post=30356"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/tags?post=30356"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}