{"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\/fr\/blog\/administrirovanie\/kak-my-ispolzovali-otlozhennuyu-replikatsiyu-dlya-avarijnogo-vosstanovleniya-s-postgresql","title":{"rendered":"Comment nous avons utilis\u00e9 la r\u00e9plication diff\u00e9r\u00e9e pour la r\u00e9cup\u00e9ration d'urgence avec PostgreSQL","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Comment nous avons utilis\u00e9 la r\u00e9plication diff\u00e9r\u00e9e pour la r\u00e9cup\u00e9ration d&#039;urgence avec PostgreSQL\" src=\"\/wp-content\/uploads\/2019\/03\/773f3b6c8d173be91c49066d7067bad3.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nLa r\u00e9plication n'est pas une sauvegarde. Ou peut-\u00eatre que si ? Voici comment nous avons utilis\u00e9 la r\u00e9plication retard\u00e9e pour r\u00e9cup\u00e9rer des donn\u00e9es apr\u00e8s avoir accidentellement supprim\u00e9 des \u00e9tiquettes.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/about.gitlab.com\/handbook\/engineering\/infrastructure\/\">Experts en infrastructure<\/a><\/noindex> sur GitLab sont responsables du fonctionnement <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/\">de GitLab.com<\/a><\/noindex> \u2014 le plus grand exemple de GitLab existant. Ici, il y a 3 millions d'utilisateurs et presque 7 millions de projets, ce qui en fait l'un des plus grands sites open source SaaS avec une architecture d\u00e9di\u00e9e. Sans le syst\u00e8me de bases de donn\u00e9es PostgreSQL, l'infrastructure de GitLab.com n'irait pas loin, et nous faisons tout ce qui est en notre pouvoir pour garantir la r\u00e9silience en cas de d\u00e9faillances qui pourraient entra\u00eener une perte de donn\u00e9es. Bien qu'une telle catastrophe soit peu probable, nous sommes bien pr\u00e9par\u00e9s et avons divers m\u00e9canismes de sauvegarde et de r\u00e9plication.<\/p>\n<p><\/p>\n<p>La r\u00e9plication n'est pas un moyen de sauvegarde de bases de donn\u00e9es (<noindex><a rel=\"nofollow\" href=\"https:\/\/about.gitlab.com\/2019\/02\/13\/delayed-replication-for-disaster-recovery-with-postgresql\/#summing-up\">voir ci-dessous<\/a><\/noindex>). Mais maintenant, nous allons voir comment retrouver rapidement des donn\u00e9es accidentellement supprim\u00e9es en utilisant la r\u00e9plication retard\u00e9e : j'ai <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/\">de GitLab.com<\/a><\/noindex> utilisateur <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-com\/gl-infra\/production\/issues\/509\">supprim\u00e9 une \u00e9tiquette<\/a><\/noindex> pour le projet <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-org\/gitlab-ce\/\"><code>gitlab-ce<\/code><\/a><\/noindex> et j'ai perdu le lien avec les demandes de fusion et les t\u00e2ches.<\/p>\n<p><\/p>\n<p>Avec la r\u00e9plication retard\u00e9e, nous avons r\u00e9cup\u00e9r\u00e9 les donn\u00e9es en seulement 1,5 heure. Voyez comment cela s'est pass\u00e9.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3 id=\"vosstanovlenie-na-moment-vremeni-s-postgresql\">R\u00e9cup\u00e9ration \u00e0 un instant donn\u00e9 avec PostgreSQL<\/h3>\n<p><\/p>\n<p>PostgreSQL poss\u00e8de une fonction int\u00e9gr\u00e9e qui restaure l'\u00e9tat de la base de donn\u00e9es \u00e0 un moment donn\u00e9. Elle s'appelle <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/continuous-archiving.html\">R\u00e9cup\u00e9ration \u00e0 un instant donn\u00e9<\/a><\/noindex> (PITR) et utilise les m\u00eames m\u00e9canismes qui maintiennent la validit\u00e9 de la r\u00e9plique : en commen\u00e7ant par un instantan\u00e9 fiable de l'ensemble du cluster de bases de donn\u00e9es (sauvegarde de base), nous appliquons une s\u00e9rie d'\u00e9tats jusqu'\u00e0 un moment pr\u00e9cis.<\/p>\n<p><\/p>\n<p>Pour utiliser cette fonction pour une sauvegarde \u00e0 froid, nous faisons r\u00e9guli\u00e8rement une sauvegarde de base de la base de donn\u00e9es et la stockons dans un archive (les archives de GitLab r\u00e9sident dans <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.google.com\/storage\/\">le stockage cloud de Google<\/a><\/noindex>). Nous suivons \u00e9galement les changements de l'\u00e9tat de la base de donn\u00e9es en archivant le journal des \u00e9critures anticip\u00e9es (<noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/wal-intro.html\">write-ahead log<\/a><\/noindex>, WAL). Et avec tout cela, nous pouvons effectuer un PITR pour la r\u00e9cup\u00e9ration d'urgence : nous commen\u00e7ons par l'instantan\u00e9 fait avant l'erreur et appliquons les changements \u00e0 partir de l'archive WAL jusqu'\u00e0 la panne.<\/p>\n<p><\/p>\n<h3 id=\"chto-takoe-otlozhennaya-replikaciya\">Qu'est-ce que la r\u00e9plication retard\u00e9e ?<\/h3>\n<p><\/p>\n<p>La r\u00e9plication retard\u00e9e consiste \u00e0 appliquer des modifications du WAL avec un certain d\u00e9lai. Cela signifie qu'une transaction s'est produite \u00e0 une heure donn\u00e9e <code>X<\/code>, mais dans la r\u00e9plique, elle appara\u00eetra avec un retard <code>d<\/code> d'une heure <code>X + d<\/code>.<\/p>\n<p><\/p>\n<p>PostgreSQL propose 2 m\u00e9thodes pour configurer une r\u00e9plication physique de la base de donn\u00e9es : la r\u00e9cup\u00e9ration \u00e0 partir d'une archive et la r\u00e9plication en streaming. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/archive-recovery-settings.html\">R\u00e9cup\u00e9ration \u00e0 partir d'une archive<\/a><\/noindex>, en fait, fonctionne comme un PITR mais de mani\u00e8re continue : nous extrayons constamment les modifications de l'archive WAL et les appliquons \u00e0 la r\u00e9plique. A <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.postgresql.org\/wiki\/Streaming_Replication\">r\u00e9plication continue<\/a><\/noindex> extrait directement le flux WAL de l'h\u00f4te de base de donn\u00e9es sup\u00e9rieur. Nous pr\u00e9f\u00e9rons la r\u00e9cup\u00e9ration depuis l'archive \u2014 c'est plus facile \u00e0 g\u00e9rer et cela poss\u00e8de des performances normales qui ne sont pas inf\u00e9rieures \u00e0 celles du cluster op\u00e9rationnel.<\/p>\n<p><\/p>\n<h3 id=\"kak-nastroit-otlozhennoe-vosstanovlenie-iz-arhiva\">Comment configurer la r\u00e9cup\u00e9ration diff\u00e9r\u00e9e depuis l'archive<\/h3>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/recovery-config.html\">Options de r\u00e9cup\u00e9ration<\/a><\/noindex> d\u00e9crites dans le fichier <code>recovery.conf<\/code>. Exemple :<\/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>Avec ces param\u00e8tres, nous avons configur\u00e9 une r\u00e9plique diff\u00e9r\u00e9e r\u00e9cup\u00e9rant depuis l'archive. Il utilise <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/wal-e\/wal-e\">wal-e<\/a><\/noindex> pour extraire les segments WAL (<code>restore_command<\/code>) de l'archive, et les modifications seront appliqu\u00e9es apr\u00e8s huit heures (<code>recovery_min_apply_delay<\/code>). La r\u00e9plique suivra les changements de la chronologie dans l'archive, par exemple, en raison de la gestion des pannes dans le cluster (<code>recovery_target_timeline<\/code>).<\/p>\n<p><\/p>\n<p>Avec <code>recovery_min_apply_delay<\/code> il est possible de configurer une r\u00e9plication continue avec retard, mais il y a quelques pi\u00e8ges li\u00e9s aux slots de r\u00e9plication, \u00e0 la r\u00e9troaction de secours \u00e0 chaud, etc. L'archive WAL permet de les \u00e9viter.<\/p>\n<p><\/p>\n<p>Param\u00e8tre <code>recovery_min_apply_delay<\/code> est apparue seulement dans PostgreSQL 9.3. Dans les versions pr\u00e9c\u00e9dentes, pour la r\u00e9plication diff\u00e9r\u00e9e, il fallait configurer une combinaison de <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/9.3\/functions-admin.html\">fonctions de gestion de r\u00e9cup\u00e9ration<\/a><\/noindex> (<code>pg_xlog_replay_pause(), pg_xlog_replay_resume()<\/code>) ou conserver les segments WAL dans l'archive pendant la dur\u00e9e du retard.<\/p>\n<p><\/p>\n<h3 id=\"kak-postgresql-eto-delaet\">Comment PostgreSQL fait-il cela ?<\/h3>\n<p><\/p>\n<p>Il est int\u00e9ressant de voir comment PostgreSQL met en \u0153uvre la r\u00e9cup\u00e9ration diff\u00e9r\u00e9e. Regardons <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>. Cela est appel\u00e9 depuis <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/postgres\/postgres\/blob\/c24dcd0cfd949bdf245814c4c2b3df828ee7db36\/src\/backend\/access\/transam\/xlog.c#L7196\">la boucle principale de r\u00e9p\u00e9tition<\/a><\/noindex> pour chaque enregistrement du 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    \/* rien \u00e0 faire si aucun d\u00e9lai n'est configur\u00e9 *\/\n    if (recovery_min_apply_delay &lt;= 0)\n        return false;\n\n    \/* aucun d\u00e9lai n&#039;est appliqu\u00e9 sur une base de donn\u00e9es non encore coh\u00e9rente *\/\n    if (!reachedConsistency)\n        return false;\n\n    \/*\n     * Est-ce un enregistrement COMMIT ?\n     *\n     * Nous choisissons d\u00e9lib\u00e9r\u00e9ment de ne pas retarder les aborts car ils n&#039;ont aucun effet sur\n     * le MVCC. Nous permettons d\u00e9j\u00e0 la relecture des enregistrements qui n&#039;ont pas de timestamp,\n     * donc il y a d\u00e9j\u00e0 des opportunit\u00e9s pour des probl\u00e8mes caus\u00e9s par des conflits pr\u00e9coces sur\n     * les r\u00e9plicas.\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     * Quitter sans armer le latch si c&#039;est d\u00e9j\u00e0 pass\u00e9 le temps d&#039;appliquer cet\n     * enregistrement\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        \/\/ Raccourci :\n        \/\/ Utiliser WaitLatch jusqu&#039;\u00e0 ce que nous atteignions recoveryDelayUntilTime\n        \/\/ puis\n        break;\n    }\n    return true;\n}<\/code><\/pre>\n<p><\/p>\n<p>L'essentiel est que le d\u00e9lai est bas\u00e9 sur le temps physique enregistr\u00e9 dans l'horodatage du commit de la transaction (<code>xtime<\/code>). Comme on peut le voir, le d\u00e9lai ne s'applique qu'aux commits et ne touche pas d'autres enregistrements \u2014 tous les changements sont appliqu\u00e9s directement, et le commit est retard\u00e9, donc nous ne verrons les changements qu'apr\u00e8s le d\u00e9lai configur\u00e9.<\/p>\n<p><\/p>\n<h3 id=\"kak-ispolzovat-otlozhennuyu-repliku-dlya-vosstanovleniya-dannyh\">Comment utiliser une r\u00e9plique retard\u00e9e pour la r\u00e9cup\u00e9ration des donn\u00e9es<\/h3>\n<p><\/p>\n<p>Supposons que nous ayons un cluster de bases de donn\u00e9es en production et une r\u00e9plique avec un retard de huit heures. Voyons comment r\u00e9cup\u00e9rer les donn\u00e9es \u00e0 l'aide de <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-com\/gl-infra\/production\/issues\/509\">la suppression accidentelle de raccourcis<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Lorsque nous avons pris connaissance du probl\u00e8me, nous <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/9.3\/functions-admin.html\">avons suspendu la r\u00e9cup\u00e9ration \u00e0 partir de l'archive<\/a><\/noindex> pour la r\u00e9plique retard\u00e9e :<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">SELECT pg_xlog_replay_pause();<\/code><\/pre>\n<p><\/p>\n<p>Avec la pause, nous n'avions pas le risque que la r\u00e9plique r\u00e9p\u00e8te la requ\u00eate <code>SUPPRIMER<\/code>. C'est utile si vous avez besoin de temps pour tout comprendre.<\/p>\n<p><\/p>\n<p>L'essentiel est que la r\u00e9plique retard\u00e9e doit atteindre le moment juste avant la requ\u00eate <code>SUPPRIMER<\/code>. Nous savions \u00e0 peu pr\u00e8s le temps physique de la suppression. Nous avons supprim\u00e9 <code>recovery_min_apply_delay<\/code> et ajout\u00e9 <code>recovery_target_time<\/code> dans <code>recovery.conf<\/code>. Ainsi, la r\u00e9plique atteint le bon moment sans retard :<\/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>Avec les horodatages, il est pr\u00e9f\u00e9rable de r\u00e9duire, pour ne pas se tromper. Toutefois, plus vous r\u00e9duisez, plus vous perdez de donn\u00e9es. Encore une fois, si nous manquons la requ\u00eate <code>SUPPRIMER<\/code>, tout sera \u00e0 nouveau supprim\u00e9 et il faudra recommencer (ou utiliser une sauvegarde froide pour le PITR).<\/p>\n<p><\/p>\n<p>Nous avons red\u00e9marr\u00e9 l'instance Postgres diff\u00e9r\u00e9e, et les segments WAL se r\u00e9p\u00e9t\u00e8rent jusqu'\u00e0 l'heure indiqu\u00e9e. Vous pouvez suivre les progr\u00e8s \u00e0 ce stade avec la requ\u00eate\u00a0:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">SELECT\n  -- emplacement actuel dans le WAL\n  pg_last_xlog_replay_location(),\n  -- horodatage de transaction actuel (\u00e9tat de la r\u00e9plique)\n  pg_last_xact_replay_timestamp(),\n  -- temps physique actuel\n  now(),\n  -- le temps restant \u00e0 appliquer jusqu'\u00e0 ce que recovery_target_time soit atteint\n  '2018-10-12 09:25:00+00'::timestamptz - pg_last_xact_replay_timestamp() as delay;<\/code><\/pre>\n<p><\/p>\n<p>Si l'horodatage ne change plus, la restauration est termin\u00e9e. Vous pouvez configurer l'action <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/recovery-target-settings.html\"><code>recovery_target_action<\/code><\/a><\/noindex>, pour fermer, avancer ou suspendre l'instance apr\u00e8s la r\u00e9p\u00e9tition (par d\u00e9faut, elle est suspendue).<\/p>\n<p><\/p>\n<p>La base de donn\u00e9es est revenue \u00e0 un \u00e9tat ant\u00e9rieur \u00e0 cette demande malheureuse. Il est maintenant possible, par exemple, d'exporter des donn\u00e9es. Nous avons export\u00e9 les donn\u00e9es supprim\u00e9es sur le marqueur et toutes les relations avec les t\u00e2ches et les demandes de fusion et les avons transf\u00e9r\u00e9es dans la base de donn\u00e9es de travail. S'il y a une perte importante, vous pouvez simplement avancer la r\u00e9plique et l'utiliser comme principale. Mais dans ce cas, toutes les modifications apr\u00e8s le moment jusqu'o\u00f9 nous avons r\u00e9cup\u00e9r\u00e9 seront perdues.<\/p>\n<p><\/p>\n<p>Il est pr\u00e9f\u00e9rable d'utiliser des ID de transactions au lieu d'horodatages. Il est utile de noter ces ID, par exemple, pour les op\u00e9rateurs DDL (comme <code>DROP TABLE<\/code>), en utilisant <code>log_statements = 'ddl'<\/code>. Si nous avions eu l'ID de transaction, nous aurions pris <code>recovery_target_xid<\/code> et l'aurions ex\u00e9cut\u00e9 jusqu'\u00e0 la transaction pr\u00e9c\u00e9dant la demande. <code>SUPPRIMER<\/code>.<\/p>\n<p><\/p>\n<p>Revenir au travail est tr\u00e8s simple\u00a0: retirez toutes les modifications de <code>recovery.conf<\/code> et red\u00e9marrez Postgres. La r\u00e9plique aura bient\u00f4t un retard de huit heures \u00e0 nouveau, et nous serons pr\u00eats pour de futures m\u00e9saventures.<\/p>\n<p><\/p>\n<h3 id=\"preimuschestva-dlya-vosstanovleniya\">Avantages de la restauration<\/h3>\n<p><\/p>\n<p>Avec une r\u00e9plique diff\u00e9r\u00e9e au lieu d'une sauvegarde \u00e0 froid, il n'est pas n\u00e9cessaire de restaurer l'ensemble de l'instantan\u00e9 depuis l'archive pendant des heures. Par exemple, nous avons besoin de cinq heures pour extraire l'ensemble de la sauvegarde de base de 2 To. Et ensuite, il faudra encore appliquer tout le WAL quotidien pour revenir \u00e0 l'\u00e9tat souhait\u00e9 (dans le pire des cas).<\/p>\n<p><\/p>\n<p>Une r\u00e9plique diff\u00e9r\u00e9e est meilleure qu'une sauvegarde \u00e0 froid pour deux raisons\u00a0:<\/p>\n<p><\/p>\n<ol>\n<li>Il n'est pas n\u00e9cessaire d'extraire l'ensemble de la sauvegarde de base depuis l'archive.<\/li>\n<li>Il y a une fen\u00eatre fixe de huit heures de segments WAL \u00e0 r\u00e9p\u00e9ter.<\/li>\n<\/ol>\n<p><\/p>\n<p>De plus, nous v\u00e9rifions en permanence s'il est possible de faire un PITR depuis le WAL, et nous remarquerions rapidement des dommages ou d'autres probl\u00e8mes avec l'archive WAL en surveillant le retard de la r\u00e9plique diff\u00e9r\u00e9e.<\/p>\n<p><\/p>\n<p>Dans cet exemple, nous avons mis 50 minutes pour la restauration, soit une vitesse de 110 Go de donn\u00e9es WAL par heure (l'archive \u00e9tait alors toujours sur <noindex><a rel=\"nofollow\" href=\"https:\/\/aws.amazon.com\/s3\/\">AWS S3<\/a><\/noindex>Nous avons r\u00e9solu le probl\u00e8me et restaur\u00e9 les donn\u00e9es en 1,5 heure.<\/p>\n<p><\/p>\n<h3 id=\"itogi-gde-prigoditsya-otlozhennaya-replika-a-gde-net\">R\u00e9sum\u00e9 : o\u00f9 la r\u00e9plication diff\u00e9r\u00e9e est utile (et o\u00f9 elle ne l'est pas)<\/h3>\n<p><\/p>\n<p>Utilisez la r\u00e9plication diff\u00e9r\u00e9e comme un moyen de premiers secours si vous avez accidentellement perdu des donn\u00e9es et que vous avez remarqu\u00e9 ce probl\u00e8me dans la fen\u00eatre de d\u00e9lai configur\u00e9e.<\/p>\n<p><\/p>\n<blockquote><p>Mais gardez \u00e0 l'esprit : la r\u00e9plication n'est pas une sauvegarde.<\/p><\/blockquote>\n<p>La sauvegarde et la r\u00e9plication ont des objectifs diff\u00e9rents. Une sauvegarde \u00e0 froid est utile si vous avez accidentellement effectu\u00e9 une <code>SUPPRIMER<\/code> ou <code>DROP TABLE<\/code>. Nous faisons une sauvegarde depuis le stockage \u00e0 froid et restaurons l'\u00e9tat pr\u00e9c\u00e9dent de la table ou de l'ensemble de la base de donn\u00e9es. Mais \u00e0 ce stade, la requ\u00eate <code>DROP TABLE<\/code> est presque instantan\u00e9ment reproduite dans toutes les r\u00e9plicas du cluster de travail, donc la r\u00e9plication habituelle ne r\u00e9soudra pas le probl\u00e8me. La r\u00e9plication elle-m\u00eame maintient la base de donn\u00e9es accessible lorsque certains serveurs \u00e9chouent, et r\u00e9partit la charge.<\/p>\n<p><\/p>\n<p>M\u00eame avec une r\u00e9plication diff\u00e9r\u00e9e, nous avons parfois vraiment besoin d'une sauvegarde \u00e0 froid dans un endroit s\u00fbr, au cas o\u00f9 un \u00e9chec du centre de donn\u00e9es se produirait, un dommage cach\u00e9 ou d'autres \u00e9v\u00e9nements qui ne sont pas imm\u00e9diatement visibles. Ici, une simple r\u00e9plication ne suffit pas.<\/p>\n<p><\/p>\n<p><strong>Remarque<\/strong>. \u00c0 <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/\">de GitLab.com<\/a><\/noindex> nous prot\u00e9geons actuellement contre la perte de donn\u00e9es uniquement au niveau du syst\u00e8me et ne restaurons pas les donn\u00e9es au niveau de l'utilisateur.<\/p>\n<p>Source : <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 - 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\/fr\/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\" \/>\n\t\t<meta property=\"og:locale\" content=\"fr_FR\" \/>\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\/fr\/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\udd47Comment nous avons utilis\u00e9 la r\u00e9plication diff\u00e9r\u00e9e pour la r\u00e9cup\u00e9ration d'urgence avec PostgreSQL | ProHoster","description":".","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/kak-my-ispolzovali-otlozhennuyu-replikatsiyu-dlya-avarijnogo-vosstanovleniya-s-postgresql","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"fr_FR","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\/fr\/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\/fr\/wp-json\/wp\/v2\/posts\/30356","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/comments?post=30356"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/30356\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media\/22360"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=30356"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=30356"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=30356"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}