CLI AI

pg_dump y pg_restore sin la trampa de versiones

2026-07-23

pg_dump -h host -U postgres -d shop -Fc -f shop.dump toma un volcado comprimido que pg_restore -d shop_copy shop.dump devuelve a su sitio. Antes de que nada de eso funcione, el cliente debe ser al menos tan nuevo como el servidor: un pg_dump más antiguo se niega en redondo, y ese único error es la razón más común de que la copia nunca llegue a hacerse.

1. El error que lo detiene todo

clai
$ clai haz un volcado de la base shop del servidor pg17→ pg_dump -h pg17 -U postgres -d shoppg_dump: error: aborting because of server version mismatchpg_dump: detail: server version: 17.10; pg_dump version: 16.14 (Debian 16.14-1.pgdg13+1)

Ningún flag arregla esto. Hace falta un cliente de la versión adecuada: el paquete postgresql-client-17, o directamente la misma imagen de contenedor que el servidor. Al revés no hay problema: un cliente más nuevo vuelca un servidor más antiguo sin quejarse.

2. Un volcado en formato custom, no un .sql

clai
$ clai vuelca la base shop a un archivo binario→ pg_dump -h pg17 -U postgres -d shop -Fc -f shop.dump

-Fc escribe un archivo comprimido que pg_restore puede abrir de forma selectiva y cargar en paralelo con -j. Un .sql normal no hace ni lo uno ni lo otro: entra por psql entero y en orden.

3. Mira dentro antes de restaurar

clai
$ clai muestra qué hay dentro del volcado→ pg_restore -l shop.dump218; 1259 16386 TABLE public orders postgres217; 1259 16385 SEQUENCE public orders_id_seq postgres3427; 0 0 SEQUENCE OWNED BY public orders_id_seq postgres3271; 2604 16389 DEFAULT public orders id postgres3420; 0 16386 TABLE DATA public orders postgres

Es el índice del archivo. Guárdalo en un fichero, borra las líneas que no quieras y devuélveselo con -L: así se hacen las restauraciones selectivas de verdad.

4. Restaurar en otra base de datos

clai
$ clai restaura el volcado en la base shop_copy→ pg_restore -h pg17 -U postgres -d shop_copy shop.dump

La base tiene que existir antes — createdb shop_copy — porque pg_restore no la crea sin -C. Cuando sale bien no dice absolutamente nada, así que verifica con un select count(*).

5. Una tabla, solo datos

clai
$ clai exporta solo la tabla orders sin el esquema→ pg_dump -h pg17 -U postgres -d shop -t orders --data-only -f orders-data.sql

-t reduce el volcado a un objeto y --data-only quita el CREATE TABLE. Útil cuando la tabla de destino ya existe con la misma forma y solo faltan las filas.

6. Restaurar sobre una base que no está vacía

clai
$ clai restaura el volcado sobre la base existente→ pg_restore -h pg17 -U postgres -d shop_copy --clean --if-exists shop.dump

Sin --clean, el mismo volcado falla la segunda vez con pg_restore: error: could not execute query: ERROR: relation "orders" already exists. --clean elimina los objetos antes de recrearlos e --if-exists calla los borrados de lo que aún no existe.

Gotchas

  • Un cliente más antiguo no vuelca un servidor más nuevo. Verificado: pg_dump 16.14 contra un servidor 17.10 se detiene de inmediato. Mantén el cliente al menos tan nuevo como el servidor; con contenedores lo fácil es lanzar pg_dump desde la misma imagen del servidor.
  • pg_restore -t añade, no reemplaza. Restaurar una tabla en una base donde ya tiene filas da ERROR: duplicate key value violates unique constraint "orders_pkey". Primero truncate, después restore.
  • pg_restore sale con 0 incluso tras errores. Verificado: ante un conflicto de claves imprimió el error y aun así devolvió código 0. En scripts añade --exit-on-error, o una restauración rota parecerá exitosa.

Related questions

¿Cómo vuelco solo el esquema? pg_dump --schema-only da la estructura sin filas. --data-only es la imagen especular.

¿Qué restaura un volcado .sql? psql -d base -f dump.sql. pg_restore solo entiende los formatos -Fc, -Fd y -Ft; el texto plano no está entre ellos.

¿Cómo acelero una restauración grande? pg_restore -j 4 carga datos y construye índices en paralelo. Solo funciona con los formatos custom y directory.

See also

CliAI escribe las líneas de volcado y restauración con los flags correctos y las muestra antes de que ninguna toque tu base de datos. Instálalo en una línea.