<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Keyla noelia lopez ojeda</title>
    <description>The latest articles on DEV Community by Keyla noelia lopez ojeda (@keylalopezz).</description>
    <link>https://dev.to/keylalopezz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4187978%2F79d4dc22-7290-43ab-bffc-62e9283be99f.jpg</url>
      <title>DEV Community: Keyla noelia lopez ojeda</title>
      <link>https://dev.to/keylalopezz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/keylalopezz"/>
    <language>en</language>
    <item>
      <title>Completo, incremental y PITR en PostgreSQL 17: guía práctica con restauración verificada</title>
      <dc:creator>Keyla noelia lopez ojeda</dc:creator>
      <pubDate>Fri, 16 Oct 2026 07:31:26 +0000</pubDate>
      <link>https://dev.to/keylalopezz/completo-incremental-y-pitr-en-postgresql-17-guia-practica-con-restauracion-verificada-37pl</link>
      <guid>https://dev.to/keylalopezz/completo-incremental-y-pitr-en-postgresql-17-guia-practica-con-restauracion-verificada-37pl</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Resumen&lt;/strong&gt; — Hay muchas formas de respaldar una base de datos, y cada una responde a un riesgo distinto. En este artículo comparo los &lt;strong&gt;respaldos lógicos y físicos&lt;/strong&gt;, el &lt;strong&gt;completo, el diferencial y el incremental&lt;/strong&gt;, y la &lt;strong&gt;recuperación a un punto en el tiempo (PITR)&lt;/strong&gt;, usando PostgreSQL 17, que por primera vez trae &lt;strong&gt;backups incrementales nativos&lt;/strong&gt;. Todo con comandos que ejecuté y con restauraciones que realmente comprobé.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repositorio:&lt;/strong&gt; &lt;a href="https://github.com/AdrianSalasEPIS/pg-backup-guardian" rel="noopener noreferrer"&gt;https://github.com/AdrianSalasEPIS/pg-backup-guardian&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;App publicada:&lt;/strong&gt; &lt;a href="https://pg-backup-guardian.onrender.com" rel="noopener noreferrer"&gt;https://pg-backup-guardian.onrender.com&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Video:&lt;/strong&gt; &lt;a href="https://youtu.be/hWiH6ANFUmQ" rel="noopener noreferrer"&gt;https://youtu.be/hWiH6ANFUmQ&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/hWiH6ANFUmQ" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Antes de elegir: ¿de qué te quieres proteger?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Riesgo&lt;/th&gt;
&lt;th&gt;Ejemplo&lt;/th&gt;
&lt;th&gt;Estrategia adecuada&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Error humano&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;DELETE FROM clientes;&lt;/code&gt; sin &lt;code&gt;WHERE&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;PITR (volver al segundo anterior)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Corrupción o fallo del disco&lt;/td&gt;
&lt;td&gt;El servidor no arranca&lt;/td&gt;
&lt;td&gt;Respaldo físico + WAL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pérdida del proveedor o la cuenta&lt;/td&gt;
&lt;td&gt;Cuenta cloud suspendida&lt;/td&gt;
&lt;td&gt;Copia lógica &lt;strong&gt;fuera&lt;/strong&gt; del proveedor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Migración o cambio de versión&lt;/td&gt;
&lt;td&gt;Pasar de PostgreSQL 16 a 17&lt;/td&gt;
&lt;td&gt;Respaldo lógico (&lt;code&gt;pg_dump&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ransomware&lt;/td&gt;
&lt;td&gt;Archivos cifrados por un atacante&lt;/td&gt;
&lt;td&gt;Copias inmutables y desconectadas&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;No hay un único "mejor backup": hay una &lt;strong&gt;combinación&lt;/strong&gt; que cubre tus riesgos con un costo razonable.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Trabajamos con &lt;strong&gt;PostgreSQL&lt;/strong&gt; en lugar de MS SQL Server: es libre, multiplataforma y trae todas las herramientas de respaldo incluidas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  2. Lógico vs. físico
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Lógico (&lt;code&gt;pg_dump&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;Físico (&lt;code&gt;pg_basebackup&lt;/code&gt;)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Qué copia&lt;/td&gt;
&lt;td&gt;Sentencias / datos (SQL o formato custom)&lt;/td&gt;
&lt;td&gt;Los archivos del clúster, bloque a bloque&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alcance&lt;/td&gt;
&lt;td&gt;Una base, un esquema o una tabla&lt;/td&gt;
&lt;td&gt;El clúster completo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Portabilidad&lt;/td&gt;
&lt;td&gt;Alta: otra versión u otro sistema operativo&lt;/td&gt;
&lt;td&gt;Misma versión mayor y arquitectura&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Velocidad en bases grandes&lt;/td&gt;
&lt;td&gt;Lenta&lt;/td&gt;
&lt;td&gt;Rápida&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Permite PITR&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Sí, junto con el archivado de WAL&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Lógico: una base, formato custom comprimido&lt;/span&gt;
pg_dump &lt;span class="nt"&gt;-Fc&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; biblioteca &lt;span class="nt"&gt;-f&lt;/span&gt; biblioteca.dump
pg_restore &lt;span class="nt"&gt;-d&lt;/span&gt; biblioteca_restaurada biblioteca.dump

&lt;span class="c"&gt;# Físico: todo el clúster&lt;/span&gt;
pg_basebackup &lt;span class="nt"&gt;-h&lt;/span&gt; localhost &lt;span class="nt"&gt;-U&lt;/span&gt; postgres &lt;span class="nt"&gt;-D&lt;/span&gt; /backups/full &lt;span class="nt"&gt;-c&lt;/span&gt; fast &lt;span class="nt"&gt;-P&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Completo, diferencial e incremental
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Completo:&lt;/strong&gt; copia todo. Es el más simple de restaurar, pero el más pesado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diferencial:&lt;/strong&gt; copia lo que cambió &lt;strong&gt;desde el último completo&lt;/strong&gt;. Para restaurar: completo + último diferencial.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Incremental:&lt;/strong&gt; copia lo que cambió &lt;strong&gt;desde el último respaldo de cualquier tipo&lt;/strong&gt;. Es el más liviano; para restaurar se necesita el completo + &lt;strong&gt;toda&lt;/strong&gt; la cadena de incrementales.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Domingo   Lunes      Martes     Miércoles
[COMPLETO] [INC 1]   [INC 2]    [INC 3]      → restaurar el miércoles = C + I1 + I2 + I3
[COMPLETO] [DIF 1]   [DIF 2]    [DIF 3]      → restaurar el miércoles = C + D3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hasta PostgreSQL 16 los incrementales requerían herramientas externas (pgBackRest, Barman). &lt;strong&gt;PostgreSQL 17 los trae de serie.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Práctica: backup incremental nativo en PostgreSQL 17
&lt;/h2&gt;

&lt;p&gt;En el repositorio hay un script (&lt;code&gt;scripts/demo_incremental.ps1&lt;/code&gt;) que ejecuta todo el ciclo. Estos son los pasos y lo que obtuvimos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paso 0: activar el resumen de WAL&lt;/strong&gt; (necesario para saber qué bloques cambiaron):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;SYSTEM&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;summarize_wal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;pg_reload_conf&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Paso 1: datos iniciales y respaldo completo&lt;/strong&gt; (100 000 filas):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pg_basebackup &lt;span class="nt"&gt;-h&lt;/span&gt; localhost &lt;span class="nt"&gt;-U&lt;/span&gt; postgres &lt;span class="nt"&gt;-D&lt;/span&gt; full &lt;span class="nt"&gt;-c&lt;/span&gt; fast &lt;span class="nt"&gt;-P&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Paso 2: cambios&lt;/strong&gt; (+50 000 filas) y &lt;strong&gt;respaldo incremental&lt;/strong&gt; a partir del manifiesto del completo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pg_basebackup &lt;span class="nt"&gt;-h&lt;/span&gt; localhost &lt;span class="nt"&gt;-U&lt;/span&gt; postgres &lt;span class="nt"&gt;-D&lt;/span&gt; incr1 &lt;span class="nt"&gt;-c&lt;/span&gt; fast &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="nt"&gt;--incremental&lt;/span&gt; full/backup_manifest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Respaldo&lt;/th&gt;
&lt;th&gt;Tamaño&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Completo&lt;/td&gt;
&lt;td&gt;86,6 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Incremental&lt;/td&gt;
&lt;td&gt;31,4 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;El incremental pesó &lt;strong&gt;alrededor de un tercio&lt;/strong&gt; del completo, y gran parte de ese tamaño son los archivos WAL que todo respaldo físico incluye. En una base grande con pocos cambios diarios, la diferencia es mucho mayor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paso 3: reconstruir y verificar.&lt;/strong&gt; Un incremental no se puede arrancar solo; &lt;code&gt;pg_combinebackup&lt;/code&gt; lo une con el completo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pg_combinebackup full incr1 &lt;span class="nt"&gt;-o&lt;/span&gt; combined
pg_verifybackup combined          &lt;span class="c"&gt;# → "copia de seguridad verificada correctamente"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Paso 4: la prueba de verdad&lt;/strong&gt;, levantar el clúster reconstruido en otro puerto y contar filas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pg_ctl &lt;span class="nt"&gt;-D&lt;/span&gt; combined &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s2"&gt;"-p 5433"&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; start
psql &lt;span class="nt"&gt;-p&lt;/span&gt; 5433 &lt;span class="nt"&gt;-d&lt;/span&gt; demo_incremental &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"SELECT count(*) FROM ventas;"&lt;/span&gt;   &lt;span class="c"&gt;# → 150000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esta es la salida real del script de principio a fin:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4di04weuvxw7examepil.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4di04weuvxw7examepil.png" alt="Salida del demo: respaldo completo de 86,6 MB, incremental de 31,4 MB, pg_verifybackup correcto y 150 000 filas restauradas"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. PITR: volver a cualquier segundo del pasado
&lt;/h2&gt;

&lt;p&gt;La recuperación a un punto en el tiempo combina un &lt;strong&gt;respaldo físico base&lt;/strong&gt; con el &lt;strong&gt;archivo continuo de WAL&lt;/strong&gt; (el registro de cada cambio). En un servidor propio se configura así:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;# postgresql.conf
&lt;/span&gt;&lt;span class="py"&gt;wal_level&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;replica&lt;/span&gt;
&lt;span class="py"&gt;archive_mode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;on&lt;/span&gt;
&lt;span class="py"&gt;archive_command&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'copy "%p" "D:\\wal_archive\\%f"'&lt;/span&gt;     &lt;span class="c"&gt;# en Linux: cp %p /wal_archive/%f
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para recuperar hasta justo antes de un error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;# postgresql.conf de la copia restaurada (+ archivo vacío recovery.signal)
&lt;/span&gt;&lt;span class="py"&gt;restore_command&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'copy "D:\\wal_archive\\%f" "%p"'&lt;/span&gt;
&lt;span class="py"&gt;recovery_target_time&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'2026-10-16 10:29:59-05'&lt;/span&gt;
&lt;span class="py"&gt;recovery_target_action&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'promote'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En la nube no tuvimos que montar nada de esto: &lt;strong&gt;Neon&lt;/strong&gt; conserva el historial WAL y permite crear una &lt;em&gt;branch&lt;/em&gt; de la base en cualquier instante dentro de la ventana de retención de su plan (en nuestro proyecto, con el plan gratuito, la ventana es de &lt;strong&gt;6 horas&lt;/strong&gt;). Es PITR como servicio. Por eso no basta solo con él: si el error se detecta al día siguiente, la ventana ya pasó, y ahí entra el respaldo lógico diario.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Cómo lo combinamos en nuestro proyecto
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capa&lt;/th&gt;
&lt;th&gt;Herramienta&lt;/th&gt;
&lt;th&gt;Frecuencia&lt;/th&gt;
&lt;th&gt;RPO aproximado&lt;/th&gt;
&lt;th&gt;Para qué&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;PITR&lt;/td&gt;
&lt;td&gt;Historial WAL de Neon&lt;/td&gt;
&lt;td&gt;Continuo&lt;/td&gt;
&lt;td&gt;segundos&lt;/td&gt;
&lt;td&gt;Errores humanos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lógico completo cifrado&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pg_dump&lt;/code&gt; + GPG en GitHub Actions&lt;/td&gt;
&lt;td&gt;Diario&lt;/td&gt;
&lt;td&gt;24 h&lt;/td&gt;
&lt;td&gt;Independencia del proveedor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Físico + incremental&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pg_basebackup --incremental&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Bajo demanda&lt;/td&gt;
&lt;td&gt;según la cadena&lt;/td&gt;
&lt;td&gt;Bases grandes, restauración rápida&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Y la regla que aplicamos a todas: &lt;strong&gt;un backup no cuenta hasta que se restauró&lt;/strong&gt;. El pipeline de nuestra app restaura cada dump diario en un PostgreSQL desechable y compara las filas de cada tabla antes de marcarlo como válido.&lt;/p&gt;

&lt;p&gt;La app publicada muestra cada estrategia con lo que &lt;strong&gt;protege&lt;/strong&gt; y, sobre todo, lo que &lt;strong&gt;no protege&lt;/strong&gt;. Esa segunda columna es la que explica por qué hay que combinarlas:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkrja9l3ijv0gtelp0ii5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkrja9l3ijv0gtelp0ii5.png" alt="Tarjetas de estrategias en la app: qué protege y qué no protege cada una"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Además, la app tiene un &lt;strong&gt;laboratorio de recuperación&lt;/strong&gt; donde se puede provocar un desastre real (un &lt;code&gt;DELETE&lt;/code&gt; sin &lt;code&gt;WHERE&lt;/code&gt;) y restaurar en segundos, con la huella de cada tabla verificada:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foy0jlayc1qxmcgawdwob.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foy0jlayc1qxmcgawdwob.png" alt="Laboratorio de recuperación después de restaurar: los datos vuelven a coincidir con el punto de restauración"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Checklist para tu propia estrategia
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Definí RPO y RTO con el negocio (¿cuántos datos y cuánto tiempo puedo perder?).&lt;/li&gt;
&lt;li&gt;[ ] Tengo al menos una copia &lt;strong&gt;fuera&lt;/strong&gt; del servidor y del proveedor (regla 3-2-1).&lt;/li&gt;
&lt;li&gt;[ ] Las copias que salen de mi infraestructura están &lt;strong&gt;cifradas&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;[ ] Las herramientas tienen la &lt;strong&gt;misma versión&lt;/strong&gt; que el servidor.&lt;/li&gt;
&lt;li&gt;[ ] La restauración se &lt;strong&gt;prueba automáticamente&lt;/strong&gt; y alguien se entera si falla.&lt;/li&gt;
&lt;li&gt;[ ] Hay una &lt;strong&gt;política de retención&lt;/strong&gt; escrita (cuántos días o copias se guardan).&lt;/li&gt;
&lt;li&gt;[ ] El procedimiento de restauración está documentado paso a paso.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Enlaces
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repositorio:&lt;/strong&gt; &lt;a href="https://github.com/AdrianSalasEPIS/pg-backup-guardian" rel="noopener noreferrer"&gt;https://github.com/AdrianSalasEPIS/pg-backup-guardian&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App en la nube:&lt;/strong&gt; &lt;a href="https://pg-backup-guardian.onrender.com" rel="noopener noreferrer"&gt;https://pg-backup-guardian.onrender.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Video:&lt;/strong&gt; &lt;a href="https://youtu.be/hWiH6ANFUmQ" rel="noopener noreferrer"&gt;https://youtu.be/hWiH6ANFUmQ&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Artículo complementario de mi compañero Adrian Salas: &lt;em&gt;Respaldos que sí se pueden restaurar&lt;/em&gt; — &lt;a href="https://dev.to/adriansalasepis/respaldos-que-si-se-pueden-restaurar-estrategia-automatizada-para-postgresql-con-github-actions-3glj"&gt;https://dev.to/adriansalasepis/respaldos-que-si-se-pueden-restaurar-estrategia-automatizada-para-postgresql-con-github-actions-3glj&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Referencias
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;PostgreSQL Global Development Group. (2024). &lt;em&gt;Continuous archiving and point-in-time recovery (PITR)&lt;/em&gt;. &lt;a href="https://www.postgresql.org/docs/17/continuous-archiving.html" rel="noopener noreferrer"&gt;https://www.postgresql.org/docs/17/continuous-archiving.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PostgreSQL Global Development Group. (2024). &lt;em&gt;pg_basebackup&lt;/em&gt;. &lt;a href="https://www.postgresql.org/docs/17/app-pgbasebackup.html" rel="noopener noreferrer"&gt;https://www.postgresql.org/docs/17/app-pgbasebackup.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PostgreSQL Global Development Group. (2024). &lt;em&gt;pg_combinebackup&lt;/em&gt;. &lt;a href="https://www.postgresql.org/docs/17/app-pgcombinebackup.html" rel="noopener noreferrer"&gt;https://www.postgresql.org/docs/17/app-pgcombinebackup.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Neon. (s. f.). &lt;em&gt;Branching and point-in-time restore&lt;/em&gt;. &lt;a href="https://neon.tech/docs" rel="noopener noreferrer"&gt;https://neon.tech/docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Keyla Noelia López Ojeda — Estudiante de Ingeniería de Sistemas, Universidad Privada de Tacna. Proyecto del curso Base de Datos II.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>database</category>
      <category>backup</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
