11. Copia de seguridad, restauración y actualizaciones
Secciones
Ajustes de lectura
Ninguna voz para este idioma en este navegador.
Más voces
Código y términos técnicos en inglés
Desactivado: la voz de la página lo lee todo, sin pausa entre dos voces.
Ninguna voz para este idioma en este navegador.
Más voces
Más voces: Microsoft Edge ofrece voces naturales en línea, y Windows (Configuración › Hora e idioma › Voz), macOS y Android instalan otras.
Los scripts de la lección son ops/11-backup.sh y ops/11-upgrade.sh, y los ejercicios están en ops/11-exercises.sh. Como en la lección 10, arrancan pequeños clústeres dentro del contenedor del curso, y check.sh ops compara su salida con los archivos de los mismos nombres en expected:
bash server.sh sh < ops/11-backup.sh| SQL Server | PostgreSQL |
|---|---|
BACKUP DATABASE, un archivo .bak |
pg_dump, un volcado lógico de una base de datos; pg_basebackup, una copia física del clúster |
logins en master |
roles, volcados por pg_dumpall --globals-only |
| copia de seguridad diferencial | copia de seguridad incremental (pg_basebackup --incremental), combinada con pg_combinebackup |
| copias de seguridad del registro | archivado del WAL (archive_command) |
RESTORE … WITH STOPAT, STOPATMARK |
recovery_target_time, recovery_target_name, recovery_target_xid |
RESTORE VERIFYONLY |
pg_verifybackup |
| actualización en el sitio con el programa de instalación | un clúster nuevo, y pg_upgrade desde el antiguo |
Volcados lógicos
Sección titulada «Volcados lógicos»Un clúster con el esquema del curso, cuyos segmentos de WAL terminados se archivan; los ajustes se explican más abajo (líneas 21-33):
say "node1: every finished WAL segment is copied to /tmp/archive, and the WAL summarizer runs for incremental backups"initdb -D node1 --auth=trust > /dev/nullmkdir archivecat >> node1/postgresql.conf <<'EOF'shared_buffers = 32MBarchive_mode = onarchive_command = 'test ! -f /tmp/archive/%f && cp %p /tmp/archive/%f'summarize_wal = onEOFpg_ctl -D node1 -l node1.log -o "-p 5433" -w start > /dev/null || exit 1psql -X -q -p 5433 -c 'CREATE DATABASE learn' -c 'CREATE ROLE reader NOLOGIN'psql -X -q -p 5433 -d learn -c '\o /dev/null' -c '\i /course/sql/schema.sql' -c 'GRANT USAGE ON SCHEMA ci TO reader'sql 5433 -c "$counts"-- node1: every finished WAL segment is copied to /tmp/archive, and the WAL summarizer runs for incremental backups runs | jobs | steps------+------+------- 125 | 315 | 2204(1 row)pg_dump escribe una base de datos como el SQL que la vuelve a crear, a partir de una única instantánea, mientras otras sesiones siguen trabajando. Su formato custom, --format=custom, va comprimido y permite a pg_restore elegir qué restaurar y trabajar en paralelo (líneas 35-43):
say "A logical dump in the custom format, its table of contents, and a restore with two parallel jobs"pg_dump -p 5433 -d learn --format=custom --file=learn.dump# Cada línea de la lista empieza con un ID de volcado y dos IDs de objeto, quitados aquípg_restore --list learn.dump | grep ' TABLE DATA ' | sed -E 's/^[0-9]+; [0-9]+ [0-9]+ //'psql -X -q -p 5433 -c 'CREATE DATABASE learn_copy'pg_restore -p 5433 -d learn_copy --jobs=2 learn.dumppsql -X -p 5433 -d learn_copy -c "$counts"# Los roles pertenecen al clúster, no a una base de datos: pg_dump los omite, pg_dumpall --globals-only los escribepg_dumpall -p 5433 --globals-only | grep -E '^(CREATE|ALTER) ROLE reader'-- A logical dump in the custom format, its table of contents, and a restore with two parallel jobsTABLE DATA ci jobs postgresTABLE DATA ci runs postgresTABLE DATA ci steps postgresTABLE DATA ga iconic_chords postgresTABLE DATA ga package_refs postgresTABLE DATA ga project_refs postgresTABLE DATA ga projects postgres runs | jobs | steps------+------+------- 125 | 315 | 2204(1 row)
CREATE ROLE reader;ALTER ROLE reader WITH NOSUPERUSER INHERIT NOCREATEROLE NOCREATEDB NOLOGIN NOREPLICATION NOBYPASSRLS;pg_restore --listimprime la tabla de contenidos del volcado, una línea por objeto. Guardada en un archivo y editada, se puede volver a pasar con--use-listpara restaurar solo algunos objetos, en el orden elegido.--jobs=2restaura con dos conexiones: los datos de varias tablas, y después sus índices, al mismo tiempo. Necesita el formato custom o el formato directorio.- Un volcado no contiene los roles, que pertenecen al clúster: el
GRANTareaderestá, el rol no.pg_dumpall --globals-onlyescribe los roles y los tablespaces.
Un volcado es una copia en un momento dado. Lo que ocurrió después se pierde, y restaurar una base de datos grande significa volver a cargar todos sus datos y reconstruir cada índice.
Copias base y copias incrementales
Sección titulada «Copias base y copias incrementales»Una copia de seguridad física copia los archivos del clúster, como un standby de la lección 10 sin la replicación. pg_basebackup escribe un backup_manifest junto a ellos, con un checksum por archivo. Desde PostgreSQL 17, una copia posterior puede copiar solo lo que ha cambiado desde ese manifiesto (líneas 45-54):
say "A full base backup, with its manifest, then new work on node1"pg_basebackup -p 5433 -D base -c fastls base/backup_manifestpsql -X -q -p 5433 -d learn -c "UPDATE ci.runs SET conclusion = 'failure' WHERE run_id = (SELECT min(run_id) FROM ci.runs)"
say "An incremental backup holds only the blocks changed since the manifest it is given"pg_basebackup -p 5433 -D incremental -c fast --incremental=base/backup_manifestdu -sk --exclude=pg_wal base incremental | awk '{ size[$2] = $1 } END { print "without WAL, the incremental backup is", (size["incremental"] * 3 < size["base"] ? "less" : "more"), "than a third of the full one" }'pg_combinebackup base incremental -o combinedpg_verifybackup combined-- A full base backup, with its manifest, then new work on node1base/backup_manifest
-- An incremental backup holds only the blocks changed since the manifest it is givenwithout WAL, the incremental backup is less than a third of the full onebackup successfully verified--incrementalnecesitasummarize_wal = onen el servidor: el WAL summarizer registra qué bloques cambió cada tramo de WAL.- Sin su WAL, la copia incremental ocupa menos de un tercio de la completa: entre las dos solo se ejecutó un
UPDATE. - Una copia incremental no se puede arrancar directamente.
pg_combinebackup«is used to reconstruct a synthetic full backup from an incremental backup and the earlier backups upon which it depends». pg_verifybackupcomprueba el resultado contra su manifiesto, y que el WAL que necesita se puede analizar.
La documentación añade una advertencia: «PostgreSQL has no built-in mechanism to figure out which backups are still needed as a basis for restoring later incremental backups» (archivado continuo). Borrar una copia completa rompe todas las copias incrementales construidas sobre ella.
Archivado del WAL y recuperación a un momento dado
Sección titulada «Archivado del WAL y recuperación a un momento dado»Una copia base más cada segmento de WAL escrito desde entonces basta para reproducir el clúster hasta cualquier momento: la recuperación a un momento dado. En node1, archive_mode = on y archive_command copian cada segmento terminado en /tmp/archive. %p es la ruta del segmento y %f su nombre; test ! -f se niega a sobrescribir un archivo ya archivado, el propio ejemplo de la documentación. En producción, el archivo está en otra máquina.
Un punto de restauración con nombre, y después un error (líneas 56-61):
say "Later: a named restore point, then a mistake"sql 5433 -c "SELECT pg_create_restore_point('before_truncate') IS NOT NULL AS restore_point"sql 5433 -c "TRUNCATE ci.runs CASCADE"wal=$(psql -X -Atq -p 5433 -c 'SELECT pg_walfile_name(pg_switch_wal())')until_true 5433 postgres "SELECT last_archived_wal >= '$wal' FROM pg_stat_archiver"sql 5433 -c "$counts"-- Later: a named restore point, then a mistake restore_point--------------- t(1 row)
NOTICE: truncate cascades to table "jobs"NOTICE: truncate cascades to table "steps"TRUNCATE TABLE runs | jobs | steps------+------+------- 0 | 0 | 0(1 row)pg_create_restore_pointescribe un nombre en el WAL, como una transacción marcada para elSTOPATMARKde SQL Server.TRUNCATE … CASCADEvacía las tres tablas de CI.pg_switch_wal()termina el segmento en curso, para que se archive ahora en lugar de cuando se llene;pg_stat_archiverindica cuándo.
La recuperación, en node2, desde la copia combinada (líneas 63-78):
say "Point-in-time recovery on node2: the combined backup, the archived WAL, and a target"cp -r combined node2chmod 700 node2cat >> node2/postgresql.conf <<'EOF'archive_mode = offrestore_command = 'cp /tmp/archive/%f %p'recovery_target_name = 'before_truncate'recovery_target_action = 'promote'EOFtouch node2/recovery.signalpg_ctl -D node2 -l node2.log -o "-p 5434" -w start > /dev/null || exit 1until_true 5434 postgres "SELECT NOT pg_is_in_recovery()"grep -o 'recovery stopping at restore point "[a-z_]*"' node2.logsql 5434 -c "$counts"sql 5434 -c "SELECT conclusion FROM ci.runs ORDER BY run_id LIMIT 1"sql 5434 -c "SELECT substr(pg_walfile_name(pg_current_wal_lsn()), 1, 8) AS timeline"-- Point-in-time recovery on node2: the combined backup, the archived WAL, and a targetrecovery stopping at restore point "before_truncate" runs | jobs | steps------+------+------- 125 | 315 | 2204(1 row)
conclusion------------ failure(1 row)
timeline---------- 00000002(1 row)recovery.signalarranca el servidor en recuperación.restore_commandrecupera los segmentos archivados, lo inverso dearchive_command.recovery_target_namedetiene la reproducción en el punto de restauración;recovery_target_time,recovery_target_xidyrecovery_target_lsnson los otros objetivos.recovery_target_action = 'promote'abre el servidor a las escrituras cuando llega allí.- Las tres tablas han vuelto, con el
UPDATEhecho entre las dos copias:failure. El servidor recuperado continúa en la timeline 2, como tras una promoción en la lección 10. archive_mode = offennode2: la copia no debe escribir sus segmentos en el archivo denode1.
Una actualización mayor con pg_upgrade
Sección titulada «Una actualización mayor con pg_upgrade»El programa de instalación de SQL Server actualiza una instancia en el sitio. Las versiones mayores de PostgreSQL cambian el formato de los catálogos del sistema, así que una actualización crea un clúster nuevo con el initdb de la nueva versión, y pg_upgrade traslada a él las bases de datos: vuelca y restaura el esquema, y reutiliza los archivos de datos, cuyo formato rara vez cambia entre versiones mayores. Las versiones menores, de 18.5 a 18.6, solo necesitan los nuevos binarios.
ops/11-upgrade.sh necesita los binarios de PostgreSQL 17 junto a los de 18. La imagen ya usa el repositorio apt del proyecto PostgreSQL, así que check.sh los instala como root antes de ejecutar el script:
# Necesita los binarios de PostgreSQL 17 en el contenedor del curso, instalados antes como root (check.sh lo hace):# docker exec pg sh -c 'apt-get update -qq && apt-get install -qq -y --no-install-recommends postgresql-17'Un clúster de PostgreSQL 17 con las ejecuciones, sus estadísticas, y las estadísticas extendidas de la lección 5 (líneas 14-36):
say "A PostgreSQL 17 cluster, with a table, its statistics, and extended statistics"$old/initdb -D pg17 --auth=trust > /dev/null$old/pg_ctl -D pg17 -l pg17.log -o "-p 5436" -w start > /dev/null || exit 1psql -X -q -p 5436 -c 'CREATE DATABASE learn'sql 5436 -q <<'EOF'CREATE SCHEMA ci;CREATE TABLE ci.runs ( run_id bigint PRIMARY KEY, workflow_name text NOT NULL, event text NOT NULL, conclusion text, head_branch text NOT NULL, created_at timestamptz NOT NULL);INSERT INTO ci.runsSELECT r."databaseId", r."workflowName", r.event, r.conclusion, r."headBranch", r."createdAt"FROM jsonb_to_recordset(pg_read_file('/course/data/runs.json')::jsonb) AS r( "databaseId" bigint, "workflowName" text, event text, conclusion text, "headBranch" text, "createdAt" timestamptz);CREATE STATISTICS ci.runs_workflow_event (dependencies) ON workflow_name, event FROM ci.runs;ANALYZE ci.runs;EOF# Solo la versión mayor: la menor cambia con los paquetes de Debiansql 5436 -c "SELECT current_setting('server_version_num')::int / 10000 AS version, current_setting('data_checksums') AS checksums"statistics="SELECT (SELECT count(*) FROM pg_stats WHERE schemaname = 'ci') AS column_stats, (SELECT count(*) FROM pg_stats_ext WHERE statistics_schemaname = 'ci') AS extended_stats"sql 5436 -c "$statistics"$old/pg_ctl -D pg17 -m fast -w stop > /dev/null-- A PostgreSQL 17 cluster, with a table, its statistics, and extended statistics version | checksums---------+----------- 17 | off(1 row)
column_stats | extended_stats--------------+---------------- 6 | 1(1 row)La tabla es más sencilla que la de schema.sql, que usa una columna generada virtual, nueva en 18. El script imprime solo la versión mayor: la menor sigue a los paquetes de Debian.
Un primer intento, con --check, que solo ejecuta las comprobaciones (líneas 38-42):
say "A new 18 cluster: initdb 18 turns data checksums on, 17 left them off"$new/initdb -D pg18 --auth=trust > /dev/null$new/pg_upgrade --old-bindir=$old --new-bindir=$new --old-datadir=pg17 --new-datadir=pg18 --check 2>&1 | grep -v '^$'rm -rf pg18$new/initdb -D pg18 --auth=trust --no-data-checksums > /dev/null-- A new 18 cluster: initdb 18 turns data checksums on, 17 left them offPerforming Consistency Checks-----------------------------Checking cluster versions okold cluster does not use data checksums but the new one doesFailure, exitinginitdb 18 activa los checksums de datos por defecto, y 17 no lo hacía. Las notas de versión indican la salida: «Checksums can be disabled with the new initdb option --no-data-checksums. pg_upgrade requires matching cluster checksum settings». El clúster nuevo se vuelve a crear sin ellos.
La actualización (líneas 44-51):
say "The upgrade: --swap moves the old data directory into the new cluster, so the 17 cluster can't be started again"$new/pg_upgrade --old-bindir=$old --new-bindir=$new --old-datadir=pg17 --new-datadir=pg18 --swap 2>&1 | grep -v '^$'$new/pg_ctl -D pg18 -l pg18.log -o "-p 5436" -w start > /dev/null || exit 1sql 5436 -c "SELECT current_setting('server_version_num')::int / 10000 AS version, count(*) AS runs FROM ci.runs"# Las estadísticas de columna pasaron; las estadísticas extendidas nosql 5436 -c "$statistics"$new/vacuumdb -p 5436 --all --analyze-only --missing-stats-only 2>&1sql 5436 -c "$statistics"Performing Consistency Checks-----------------------------Checking cluster versions okChecking database connection settings okChecking database user is the install user okChecking for prepared transactions okChecking for contrib/isn with bigint-passing mismatch okChecking for valid logical replication slots okChecking for subscription state okChecking data type usage okChecking for objects affected by Unicode update okChecking for not-null constraint inconsistencies okCreating dump of global objects okCreating dump of database schemas okChecking for presence of required libraries okChecking database user is the install user okChecking for prepared transactions okChecking for new cluster tablespace directories okIf pg_upgrade fails after this point, you must re-initdb thenew cluster before continuing.Performing Upgrade------------------Setting locale and encoding for new cluster okAnalyzing all rows in the new cluster okFreezing all rows in the new cluster okDeleting files from new pg_xact okCopying old pg_xact to new server okSetting oldest XID for new cluster okSetting next transaction ID and epoch for new cluster okDeleting files from new pg_multixact/offsets okCopying old pg_multixact/offsets to new server okDeleting files from new pg_multixact/members okCopying old pg_multixact/members to new server okSetting next multixact ID and offset for new cluster okResetting WAL archives okSetting frozenxid and minmxid counters in new cluster okRestoring global objects in the new cluster okRestoring database schemas in the new cluster okAdding ".old" suffix to old "global/pg_control" okBecause "swap" mode was used, the old cluster can no longer besafely started.Swapping data directories okSetting next OID for new cluster okSync data directory to disk okCreating script to delete old cluster okChecking for extension updates okUpgrade Complete----------------Some statistics are not transferred by pg_upgrade.Once you start the new server, consider running these two commands: /usr/lib/postgresql/18/bin/vacuumdb --all --analyze-in-stages --missing-stats-only /usr/lib/postgresql/18/bin/vacuumdb --all --analyze-onlyRunning this script will delete the old cluster's data files: ./delete_old_cluster.sh version | runs---------+------ 18 | 125(1 row)
column_stats | extended_stats--------------+---------------- 6 | 0(1 row)
vacuumdb: vacuuming database "learn"vacuumdb: vacuuming database "postgres"vacuumdb: vacuuming database "template1" column_stats | extended_stats--------------+---------------- 6 | 1(1 row)pg_upgradecomprueba, vuelca el esquema antiguo, lo restaura en el clúster nuevo, y después trae los IDs de transacción y los archivos de datos.--swap, nuevo en PostgreSQL 18, mueve los directorios de datos del clúster antiguo al nuevo en lugar de copiar o enlazar archivos; la documentación dice que «can outperform--link,--clone,--copy, and--copy-file-range, especially on clusters with many relations». El precio está en la salida: «the old cluster can no longer be safely started». Sin una copia de seguridad, no hay vuelta atrás.- También nuevo en 18,
pg_upgrade«will transfer most optimizer statistics from the old cluster to the new cluster»: las seis estadísticas de columna están, y el servidor puede planificar bien desde su primera consulta. Las estadísticas extendidas no. vacuumdb --analyze-only --missing-stats-only, otra opción de PostgreSQL 18, analiza solo lo que no tiene estadísticas, y recupera las estadísticas extendidas. El propio consejo depg_upgradees ejecutarlo primero con--analyze-in-stages.
En Aurora
Sección titulada «En Aurora»Por verificar: nada de esta sección se ejecutó en AWS. Aurora gestiona las copias de seguridad por sí mismo, y sus restauraciones crean clústeres nuevos.
- Copias de seguridad continuas. «Aurora automated backups are continuous and incremental, so you can quickly restore to any point within the backup retention period», que va «from 1–35 days», un día por defecto; «you can’t disable automated backups on Aurora» (copias de seguridad). No hay
archive_commandque configurar: «Amazon Aurora uploads log records for DB clusters to Amazon S3 continuously» (recuperación a un momento dado). - La recuperación a un momento dado crea un DB cluster nuevo, como
node2era aquí un clúster nuevo. El último momento restaurable «is typically within 5 minutes of the current time». Las instantáneas manuales conservan los datos más allá del periodo de retención: «Aurora DB cluster snapshots don’t expire». - Sin rebobinado para PostgreSQL. Backtrack, que rebobina un clúster en el sitio, es solo para Aurora MySQL (Backtrack).
- Clones. «Aurora uses a copy-on-write protocol to create a clone», que comparte el almacenamiento con su origen hasta que uno de los dos lo modifica; «you can create up to 15 clones with copy-on-write protocol», en la misma región (clonación). Un clon es la forma barata de probar una restauración o una actualización con datos reales.
- Volcados y exportaciones.
pg_dumpypg_restorefuncionan desde una máquina cliente; solo encontré el procedimiento de AWS en la guía de RDS for PostgreSQL, no en la de Aurora. La extensiónaws_s3exporta el resultado de una consulta directamente a S3 conaws_s3.query_export_to_s3. - Las actualizaciones mayores usan pg_upgrade. «To safely upgrade the DB instances that make up your cluster, Aurora PostgreSQL uses the pg_upgrade utility» (actualizaciones de versión mayor). Antes: «Drop logical replication slots. The upgrade process can’t proceed if the Aurora PostgreSQL DB cluster is using any logical replication slots». Aurora toma una instantánea cuyo nombre lleva el prefijo
preupgrade. - Estadísticas: una contradicción que comprobar. La misma página dice «Optimizer statistics aren’t transferred during a major version upgrade, so you need to regenerate all statistics», mientras que
pg_upgrade18 las transfiere, como mostró esta lección. Si una actualización a Aurora PostgreSQL 18 las conserva no está documentado: ejecutaANALYZEde todos modos. - Los Blue/Green Deployments copian un clúster en un entorno green mantenido sincronizado con replicación lógica, donde se ejecuta la actualización, y después conmutan; «the switchover typically takes under a minute with no data loss» (descripción general). Los límites son los de la replicación lógica: «Data definition language (DDL) statements, such as CREATE TABLE and CREATE SCHEMA, aren’t replicated from the blue environment to the green environment» (consideraciones). La tabla de versiones se detiene en Aurora PostgreSQL 17.
- Las versiones menores se pueden aplicar con zero-downtime patching (ZDP), donde «application sessions are maintained except for those with dropped connections», con una caída del rendimiento que «typically lasts only for a few seconds or at most, approximately one minute» (actualizaciones menores).
Puntos clave
Sección titulada «Puntos clave»pg_dumpcopia una base de datos en un momento dado; los roles vienen depg_dumpall --globals-only.- El formato custom permite a
pg_restoreelegir objetos y restaurar en paralelo. - Las copias base tienen manifiestos; las copias incrementales necesitan
summarize_wal, las copias de las que dependen, ypg_combinebackup. - El archivado del WAL más una copia base da la recuperación a un momento dado: hasta una hora, un punto con nombre, una transacción o un LSN.
- Una actualización mayor es un clúster nuevo: los checksums deben coincidir,
--swapes rápido y sin vuelta atrás, y 18 conserva la mayoría de las estadísticas. - En Aurora, las copias de seguridad son continuas, las restauraciones y los clones crean clústeres nuevos, y las actualizaciones siguen ejecutando
pg_upgrade.
Ejercicios
Sección titulada «Ejercicios»Las soluciones están en ops/11-exercises.sh, sobre un clúster como node1 (líneas 19-28).
- Alguien borra todas las filas de
ga.iconic_chords. Recupera las filas de esa tabla desde un volcado en formato custom, sin tocar las demás tablas.
Solución
say "Exercise 1: the iconic chords are deleted by mistake; only that table's data comes back from the dump"pg_dump -p 5433 -d learn --format=custom --file=learn.dumpsql 5433 -c "DELETE FROM ga.iconic_chords"pg_restore -p 5433 -d learn --data-only --table=iconic_chords learn.dumpsql 5433 -c "SELECT count(*) AS chords FROM ga.iconic_chords"-- Exercise 1: the iconic chords are deleted by mistake; only that table's data comes back from the dumpDELETE 17 chords-------- 17(1 row)--table selecciona la tabla y --data-only restaura sus filas en la tabla existente, sin intentar crearla de nuevo. Las filas son las del volcado: lo que cambió en esa tabla después del volcado se pierde, algo que la recuperación a un momento dado evita.
- Tras una copia base, un
UPDATEmarca la última ejecución comocancelled, y después una transacción borra todos los pasos. Recupera una copia que tenga elUPDATEpero no elDELETE, usando el ID de la transacción como objetivo.
Solución
say "Exercise 2: a recovery that stops before the transaction of a DELETE, found by its ID"pg_basebackup -p 5433 -D base -c fastsql 5433 -q -c "UPDATE ci.runs SET conclusion = 'cancelled' WHERE run_id = (SELECT max(run_id) FROM ci.runs)"xid=$(psql -X -Atq -p 5433 -d learn -c "BEGIN" -c "DELETE FROM ci.steps" -c "SELECT pg_current_xact_id()" -c "COMMIT" | sed -n 1p)wal=$(psql -X -Atq -p 5433 -c 'SELECT pg_walfile_name(pg_switch_wal())')until_true 5433 postgres "SELECT last_archived_wal >= '$wal' FROM pg_stat_archiver"cp -r base node2chmod 700 node2cat >> node2/postgresql.conf <<EOFarchive_mode = offrestore_command = 'cp /tmp/archive/%f %p'recovery_target_xid = '$xid'recovery_target_inclusive = offrecovery_target_action = 'promote'EOFtouch node2/recovery.signalpg_ctl -D node2 -l node2.log -o "-p 5434" -w start > /dev/null || exit 1until_true 5434 postgres "SELECT NOT pg_is_in_recovery()"grep -o 'recovery stopping before commit of transaction' node2.logsql 5434 -c "SELECT (SELECT count(*) FROM ci.steps) AS steps, (SELECT conclusion FROM ci.runs ORDER BY run_id DESC LIMIT 1) AS last_run"-- Exercise 2: a recovery that stops before the transaction of a DELETE, found by its IDrecovery stopping before commit of transaction steps | last_run-------+----------- 2204 | cancelled(1 row)pg_current_xact_id() da el ID de la transacción desde dentro de ella. recovery_target_xid se detiene en el commit de esa transacción, y recovery_target_inclusive = off se detiene justo antes: los pasos están, y la ejecución está cancelled. En la práctica, rara vez se conoce el ID de una transacción errónea; una hora sacada de los logs de la aplicación, con recovery_target_time, es el objetivo habitual.
Fuentes
Sección titulada «Fuentes»- Documentación de PostgreSQL 18: copia de seguridad y restauración, volcado SQL, archivado continuo y PITR,
pg_dump,pg_restore,pg_dumpall,pg_basebackup,pg_combinebackup,pg_verifybackup, ajustes del WAL y objetivos de recuperación, funciones de control de copias de seguridad,pg_upgrade, actualizar un clúster,vacuumdb, notas de versión de PostgreSQL 18, notas de versión de PostgreSQL 17; el repositorio apt - SQL Server: descripción general de las copias de seguridad, restaurar a un momento dado, elegir un método de actualización
- AWS: copias de seguridad, recuperación a un momento dado, Backtrack, clonación, importar con pg_dump en RDS, exportar a S3, actualizaciones de versión mayor, actualizaciones de versión menor, descripción general de blue/green, consideraciones y versiones, todas consultadas el 2026-09-16