{"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\/es\/blog\/administrirovanie\/kak-my-ispolzovali-otlozhennuyu-replikatsiyu-dlya-avarijnogo-vosstanovleniya-s-postgresql","title":{"rendered":"C\u00f3mo usamos la replicaci\u00f3n diferida para la recuperaci\u00f3n de emergencia con PostgreSQL","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"C\u00f3mo usamos la replicaci\u00f3n diferida para la recuperaci\u00f3n de emergencia con PostgreSQL\" src=\"\/wp-content\/uploads\/2019\/03\/773f3b6c8d173be91c49066d7067bad3.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nLa replicaci\u00f3n no es una copia de seguridad. \u00bfO s\u00ed? Aqu\u00ed te mostramos c\u00f3mo utilizamos la replicaci\u00f3n retrasada para la recuperaci\u00f3n al eliminar accidentalmente accesos directos.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/about.gitlab.com\/handbook\/engineering\/infrastructure\/\">Especialistas en infraestructura<\/a><\/noindex> en GitLab se encargan del funcionamiento <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/\">GitLab.com<\/a><\/noindex> \u2014 el mayor ejemplar de GitLab en la naturaleza. Aqu\u00ed hay 3 millones de usuarios y casi 7 millones de proyectos, y es uno de los sitios de c\u00f3digo abierto SaaS m\u00e1s grandes con una arquitectura dedicada. Sin un sistema de bases de datos PostgreSQL, la infraestructura de GitLab.com no avanzar\u00eda mucho, y hacemos todo lo posible para garantizar la disponibilidad en caso de fallos que puedan llevar a la p\u00e9rdida de datos. Es poco probable que ocurra tal cat\u00e1strofe, pero estamos bien preparados y contamos con varios mecanismos de copia de seguridad y replicaci\u00f3n.<\/p>\n<p><\/p>\n<p>La replicaci\u00f3n no es un medio de copia de seguridad de bases de datos (<noindex><a rel=\"nofollow\" href=\"https:\/\/about.gitlab.com\/2019\/02\/13\/delayed-replication-for-disaster-recovery-with-postgresql\/#summing-up\">ver m\u00e1s abajo<\/a><\/noindex>). Pero ahora veremos c\u00f3mo recuperar r\u00e1pidamente datos eliminados accidentalmente utilizando la replicaci\u00f3n retrasada: en <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/\">GitLab.com<\/a><\/noindex> usuario <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-com\/gl-infra\/production\/issues\/509\">elimin\u00f3 el acceso directo<\/a><\/noindex> para el proyecto <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-org\/gitlab-ce\/\"><code>gitlab-ce<\/code><\/a><\/noindex> y perdi\u00f3 la conexi\u00f3n con las solicitudes de fusi\u00f3n y tareas.<\/p>\n<p><\/p>\n<p>Con la replicaci\u00f3n retrasada, restauramos los datos en solo 1.5 horas. Mira c\u00f3mo fue.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3 id=\"vosstanovlenie-na-moment-vremeni-s-postgresql\">Recuperaci\u00f3n a un punto en el tiempo con PostgreSQL<\/h3>\n<p><\/p>\n<p>PostgreSQL tiene una funci\u00f3n incorporada que restaura el estado de la base de datos a un punto en el tiempo espec\u00edfico. Se llama <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/continuous-archiving.html\">Recuperaci\u00f3n a un Punto en el Tiempo<\/a><\/noindex> (PITR) y utiliza los mismos mecanismos que mantienen la validez de la r\u00e9plica: comenzando con una instant\u00e1nea confiable de todo el cl\u00faster de bases de datos (copia de seguridad base), aplicamos una serie de cambios de estado hasta un punto en el tiempo determinado.<\/p>\n<p><\/p>\n<p>Para usar esta funci\u00f3n para una copia de seguridad en fr\u00edo, hacemos copias de seguridad base de la base de datos regularmente y las archivamos (los archivos de respaldo de GitLab residen en <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.google.com\/storage\/\">almacenamiento en la nube de Google<\/a><\/noindex>). Tambi\u00e9n rastreamos los cambios de estado de la base de datos archivando el registro de escritura anticipada (<noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/wal-intro.html\">write-ahead log<\/a><\/noindex>, WAL). Y con todo esto, podemos realizar PITR para la recuperaci\u00f3n de desastres: comenzamos con una instant\u00e1nea tomada antes del error y aplicamos cambios del archivo WAL hasta el fallo.<\/p>\n<p><\/p>\n<h3 id=\"chto-takoe-otlozhennaya-replikaciya\">\u00bfQu\u00e9 es la replicaci\u00f3n retrasada?<\/h3>\n<p><\/p>\n<p>La replicaci\u00f3n retrasada es la aplicaci\u00f3n de cambios del WAL con un retraso. Es decir, la transacci\u00f3n ocurri\u00f3 a la hora <code>X<\/code>, pero en la r\u00e9plica aparecer\u00e1 con un retraso <code>d<\/code> de una hora <code>X + d<\/code>.<\/p>\n<p><\/p>\n<p>En PostgreSQL hay 2 formas de configurar una r\u00e9plica f\u00edsica de la base de datos: recuperaci\u00f3n desde archivo y replicaci\u00f3n en streaming. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/archive-recovery-settings.html\">Recuperaci\u00f3n desde archivo<\/a><\/noindex>, en esencia, funciona como PITR, pero de forma continua: estamos extrayendo constantemente cambios del archivo WAL y aplic\u00e1ndolos a la r\u00e9plica. A <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.postgresql.org\/wiki\/Streaming_Replication\">replicaci\u00f3n en streaming<\/a><\/noindex> extrae directamente el flujo WAL del host de base de datos superior. Preferimos la recuperaci\u00f3n desde el archivo, ya que es m\u00e1s f\u00e1cil de administrar y tiene un rendimiento normal que no se queda atr\u00e1s del cl\u00faster de trabajo.<\/p>\n<p><\/p>\n<h3 id=\"kak-nastroit-otlozhennoe-vosstanovlenie-iz-arhiva\">C\u00f3mo configurar la recuperaci\u00f3n retrasada desde el archivo<\/h3>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/recovery-config.html\">Opciones de recuperaci\u00f3n<\/a><\/noindex> se describen en el archivo <code>recovery.conf<\/code>. Ejemplo:<\/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>Con estas configuraciones, hemos configurado una r\u00e9plica retrasada con recuperaci\u00f3n desde el archivo. Aqu\u00ed se utiliza <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/wal-e\/wal-e\">wal-e<\/a><\/noindex> para extraer segmentos WAL (<code>restore_command<\/code>) del archivo, y los cambios se aplicar\u00e1n en ocho horas (<code>recovery_min_apply_delay<\/code>). La r\u00e9plica estar\u00e1 al tanto de los cambios en la l\u00ednea de tiempo del archivo, por ejemplo, debido a la recuperaci\u00f3n de fallos en el cl\u00faster (<code>recovery_target_timeline<\/code>).<\/p>\n<p><\/p>\n<p>Con <code>recovery_min_apply_delay<\/code> se puede configurar la replicaci\u00f3n en streaming con retraso, pero hay un par de trampas relacionadas con los slots de replicaci\u00f3n, la retroalimentaci\u00f3n de respaldo en caliente, etc. El archivo WAL permite evitarlas.<\/p>\n<p><\/p>\n<p>Par\u00e1metro <code>recovery_min_apply_delay<\/code> apareci\u00f3 solo en PostgreSQL 9.3. En versiones anteriores, para la replicaci\u00f3n retrasada se deb\u00eda configurar una combinaci\u00f3n de <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/9.3\/functions-admin.html\">funciones de control de recuperaci\u00f3n<\/a><\/noindex> (<code>pg_xlog_replay_pause(), pg_xlog_replay_resume()<\/code>) o mantener segmentos WAL en el archivo durante el per\u00edodo de retraso.<\/p>\n<p><\/p>\n<h3 id=\"kak-postgresql-eto-delaet\">\u00bfC\u00f3mo lo hace PostgreSQL?<\/h3>\n<p><\/p>\n<p>Es interesante ver c\u00f3mo PostgreSQL implementa la recuperaci\u00f3n retrasada. Observemos c\u00f3mo <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>. Se llama desde <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/postgres\/postgres\/blob\/c24dcd0cfd949bdf245814c4c2b3df828ee7db36\/src\/backend\/access\/transam\/xlog.c#L7196\">el ciclo principal de repetici\u00f3n<\/a><\/noindex> para cada registro del 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    \/* no hay nada que hacer si no se ha configurado un retraso *\/\n    if (recovery_min_apply_delay &lt;= 0)\n        return false;\n\n    \/* no se aplica ning\u00fan retraso en una base de datos que a\u00fan no es consistente *\/\n    if (!reachedConsistency)\n        return false;\n\n    \/*\n     * \u00bfEs un registro de COMMIT?\n     *\n     * Elegimos deliberadamente no retrasar abortos ya que no tienen efecto en\n     * MVCC. Ya permitimos la reproducci\u00f3n de registros que no tienen una marca de tiempo,\n     * as\u00ed que ya hay una oportunidad para que surjan problemas causados por conflictos tempranos en\n     * 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     * Salir sin armar la cerradura si ya ha pasado el tiempo para aplicar este\n     * registro\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        \/\/ Abreviado:\n        \/\/ Usa WaitLatch hasta que lleguemos a recoveryDelayUntilTime\n        \/\/ y luego\n        break;\n    }\n    return true;\n}<\/code><\/pre>\n<p><\/p>\n<p>La esencia es que el retraso se basa en el tiempo f\u00edsico registrado en la marca de tiempo del commit de la transacci\u00f3n (<code>xtime<\/code>). Como se puede ver, el retraso se aplica solo a los commits y no afecta a otros registros; todos los cambios se aplican directamente, y el commit se retrasa, por lo que veremos los cambios solo despu\u00e9s del retraso configurado.<\/p>\n<p><\/p>\n<h3 id=\"kak-ispolzovat-otlozhennuyu-repliku-dlya-vosstanovleniya-dannyh\">C\u00f3mo usar una r\u00e9plica retrasada para la recuperaci\u00f3n de datos<\/h3>\n<p><\/p>\n<p>Supongamos que tenemos un cl\u00faster de bases de datos en producci\u00f3n y una r\u00e9plica con ocho horas de retraso. Veamos c\u00f3mo recuperar datos usando el ejemplo de <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-com\/gl-infra\/production\/issues\/509\">eliminaci\u00f3n accidental de etiquetas<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Cuando nos enteramos del problema, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/9.3\/functions-admin.html\">suspendimos la recuperaci\u00f3n desde el archivo<\/a><\/noindex> para la r\u00e9plica retrasada:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">SELECT pg_xlog_replay_pause();<\/code><\/pre>\n<p><\/p>\n<p>Con la pausa, no corrimos el riesgo de que la r\u00e9plica repitiera la consulta <code>ELIMINAR<\/code>. Es algo \u00fatil si necesitas tiempo para aclarar todo.<\/p>\n<p><\/p>\n<p>La clave es que la r\u00e9plica retrasada debe llegar al momento justo antes de la consulta <code>ELIMINAR<\/code>. Sab\u00edamos aproximadamente el tiempo f\u00edsico de la eliminaci\u00f3n. Eliminamos <code>recovery_min_apply_delay<\/code> y a\u00f1adimos <code>recovery_target_time<\/code> en <code>recovery.conf<\/code>. As\u00ed, la r\u00e9plica llega al momento deseado sin retrasos:<\/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>Con las marcas de tiempo, es mejor reducir, para no fallar. Sin embargo, cuanto m\u00e1s reduzcas, m\u00e1s datos perder\u00e1s. Nuevamente, si pasamos la consulta <code>ELIMINAR<\/code>, todo se eliminar\u00e1 nuevamente y tendr\u00e1s que empezar desde el principio (o incluso tomar una copia de seguridad fr\u00eda para PITR).<\/p>\n<p><\/p>\n<p>Reiniciamos la instancia de Postgres diferida y los segmentos WAL se repitieron hasta el tiempo indicado. Se puede rastrear el progreso en esta etapa con la consulta:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">SELECT\n  -- ubicaci\u00f3n actual en WAL\n  pg_last_xlog_replay_location(),\n  -- marca de tiempo de la transacci\u00f3n actual (estado de la r\u00e9plica)\n  pg_last_xact_replay_timestamp(),\n  -- tiempo f\u00edsico actual\n  now(),\n  -- la cantidad de tiempo que a\u00fan debe aplicarse hasta que se alcance 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>Si la marca de tiempo ya no cambia, la recuperaci\u00f3n est\u00e1 completa. Se puede configurar la acci\u00f3n <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/recovery-target-settings.html\"><code>recovery_target_action<\/code><\/a><\/noindex>, para cerrar, avanzar o pausar la instancia despu\u00e9s del reinicio (por defecto se pausa).<\/p>\n<p><\/p>\n<p>La base de datos ha regresado al estado anterior a la desafortunada consulta. Ahora se puede, por ejemplo, exportar datos. Exportamos los datos eliminados sobre la etiqueta y todas las relaciones con tareas y solicitudes de fusi\u00f3n y los transferimos a la base de datos activa. Si las p\u00e9rdidas son grandes, se puede simplemente avanzar la r\u00e9plica y utilizarla como principal. Pero entonces se perder\u00e1n todos los cambios realizados despu\u00e9s del punto hasta donde recuperamos.<\/p>\n<p><\/p>\n<p>En lugar de marcas de tiempo, es mejor usar los ID de transacciones. Es \u00fatil registrar estos ID, por ejemplo, para los operadores DDL (tipo <code>DROP TABLE<\/code>), mediante <code>log_statements = 'ddl'<\/code>. Si tuvi\u00e9ramos el ID de transacci\u00f3n, tomar\u00edamos <code>recovery_target_xid<\/code> y ejecutar\u00edamos todo hasta la transacci\u00f3n anterior a la consulta. <code>ELIMINAR<\/code>.<\/p>\n<p><\/p>\n<p>Regresar al trabajo es muy sencillo: elimine todos los cambios de <code>recovery.conf<\/code> y reinicie Postgres. Pronto habr\u00e1 una vez m\u00e1s un retraso de ocho horas en la r\u00e9plica, y estaremos listos para futuros problemas.<\/p>\n<p><\/p>\n<h3 id=\"preimuschestva-dlya-vosstanovleniya\">Ventajas de la recuperaci\u00f3n<\/h3>\n<p><\/p>\n<p>Con una r\u00e9plica diferida en lugar de una copia de seguridad fr\u00eda, no es necesario restaurar todo el snapshot del archivo durante horas. Por ejemplo, necesitamos cinco horas para recuperar toda la copia de seguridad base de 2 TB. Y luego adem\u00e1s habr\u00e1 que aplicar todo el WAL diario para restaurar al estado necesario (en el peor de los casos).<\/p>\n<p><\/p>\n<p>Una r\u00e9plica diferida es mejor que una copia de seguridad fr\u00eda por dos razones:<\/p>\n<p><\/p>\n<ol>\n<li>No es necesario extraer toda la copia de seguridad base del archivo.<\/li>\n<li>Hay una ventana fija de ocho horas de segmentos WAL que deben ser repetidos.<\/li>\n<\/ol>\n<p><\/p>\n<p>Adem\u00e1s, estamos verificando constantemente si se puede hacer PITR desde el WAL, y notar\u00edamos r\u00e1pidamente da\u00f1os u otros problemas con el archivo WAL, siguiendo el retraso de la r\u00e9plica diferida.<\/p>\n<p><\/p>\n<p>En este ejemplo, tardamos 50 minutos en recuperar, es decir, la velocidad fue de 110 GB de datos WAL por hora (el archivo todav\u00eda estaba en <noindex><a rel=\"nofollow\" href=\"https:\/\/aws.amazon.com\/s3\/\">AWS S3<\/a><\/noindex>). En total, resolvimos el problema y restauramos los datos en 1,5 horas.<\/p>\n<p><\/p>\n<h3 id=\"itogi-gde-prigoditsya-otlozhennaya-replika-a-gde-net\">Conclusiones: d\u00f3nde puede ser \u00fatil la replicaci\u00f3n retrasada (y d\u00f3nde no)<\/h3>\n<p><\/p>\n<p>Utiliza la replicaci\u00f3n retrasada como un medio de primeros auxilios si accidentalmente has perdido datos y has notado este problema dentro del retraso configurado.<\/p>\n<p><\/p>\n<blockquote><p>Pero ten en cuenta: la replicaci\u00f3n no es una copia de seguridad.<\/p><\/blockquote>\n<p>Las copias de seguridad y la replicaci\u00f3n tienen diferentes objetivos. Una copia de seguridad fr\u00eda ser\u00e1 \u00fatil si accidentalmente hiciste <code>ELIMINAR<\/code> o <code>DROP TABLE<\/code>. Hacemos una copia de seguridad desde un almacenamiento fr\u00edo y restauramos el estado anterior de la tabla o de toda la base de datos. Pero en este caso, la consulta <code>DROP TABLE<\/code> se reproduce casi instant\u00e1neamente en todas las r\u00e9plicas del cl\u00faster de trabajo, por lo que la replicaci\u00f3n normal aqu\u00ed no ayudar\u00e1. La replicaci\u00f3n en s\u00ed misma mantiene la base de datos disponible cuando se entregan servidores individuales y distribuye la carga.<\/p>\n<p><\/p>\n<p>Incluso con una r\u00e9plica retrasada, a veces necesitamos mucho la copia de seguridad fr\u00eda en un lugar seguro, si de repente ocurre una falla en el centro de datos, un da\u00f1o oculto u otros eventos que no notar\u00e1s de inmediato. Aqu\u00ed la replicaci\u00f3n por s\u00ed sola no es suficiente.<\/p>\n<p><\/p>\n<p><strong>Nota<\/strong>. En <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/\">GitLab.com<\/a><\/noindex> actualmente solo protegemos contra la p\u00e9rdida de datos a nivel de sistema y no restauramos los datos a nivel de usuario.<\/p>\n<p>Fuente: <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\/es\/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=\"es_ES\" \/>\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\/es\/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\udd47C\u00f3mo utilizamos la replicaci\u00f3n retrasada para recuperaci\u00f3n de desastres con PostgreSQL | ProHoster","description":".","canonical_url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/kak-my-ispolzovali-otlozhennuyu-replikatsiyu-dlya-avarijnogo-vosstanovleniya-s-postgresql","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"es_ES","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\/es\/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\/es\/wp-json\/wp\/v2\/posts\/30356","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=30356"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/30356\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/22360"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=30356"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=30356"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=30356"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}