pg_dump y pg_restore son las herramientas oficiales de PostgreSQL para exportar una base de datos a un archivo y cargarla en otro servidor. Funcionan entre versiones distintas, así que también sirven para actualizar de versión mayor moviendo los datos a un servidor nuevo. En esta guía migrarás una base de datos desde un servidor de origen a un servidor de destino con Ubuntu 24.04, usando volcado y restauración en paralelo, y comprobarás que los datos han llegado completos.
Requisitos previos
- Un servidor de origen con PostgreSQL y la base de datos a migrar. En los ejemplos se llama
appdby su propietario es el rolappuser. - Un servidor de destino con Ubuntu 24.04 LTS y PostgreSQL instalado, por ejemplo un VPS de CubePath. Su versión debe ser igual o superior a la del origen.
- Un usuario no root con privilegios
sudoen ambos servidores. - Espacio libre en disco en ambos servidores de al menos el tamaño de la base de datos (el volcado suele ocupar bastante menos gracias a la compresión).
- Acceso SSH del servidor de origen al de destino para copiar el volcado.
Los comandos se ejecutan como el usuario de sistema postgres, que en Debian y Ubuntu puede conectarse a su servidor local sin contraseña.
Formatos de volcado
pg_dump admite cuatro formatos. Para migraciones, el formato directorio es la mejor opción porque es el único que permite volcar en paralelo y, como el formato custom, admite restauración paralela y selectiva.
| Formato | Opción | Se restaura con | Volcado paralelo | Restauración paralela |
|---|---|---|---|---|
| SQL plano | -Fp | psql | No | No |
| Custom | -Fc | pg_restore | No | Sí |
| Directorio | -Fd | pg_restore | Sí | Sí |
| Tar | -Ft | pg_restore | No | No |
Paso 1: Comprobar las versiones
pg_dump puede leer servidores de versiones anteriores, pero no posteriores. Usa siempre el pg_dump de la versión del servidor de destino (o superior). Consulta la versión del servidor de origen:
sudo -u postgres psql -c "SELECT version();"
version
---------------------------------------------------------------------------
PostgreSQL 14.13 (Ubuntu 14.13-0ubuntu0.22.04.1) on x86_64-pc-linux-gnu ...
En el destino, Ubuntu 24.04 incluye PostgreSQL 16. Comprueba la versión de las herramientas cliente:
pg_dump --version
pg_dump (PostgreSQL) 16.10 (Ubuntu 16.10-0ubuntu0.24.04.1)
Si el destino tiene una versión más reciente que el origen (por ejemplo 14 en origen y 16 en destino), instala en el servidor de origen el cliente de la versión del destino desde el repositorio oficial de PostgreSQL (PGDG), así el volcado lo genera un pg_dump que entiende ambas versiones:
sudo apt install -y postgresql-common
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
sudo apt install -y postgresql-client-16
Cambia 16 por la versión mayor del destino. Para asegurarte de usar ese binario, en el paso 4 llama a pg_dump con su ruta completa, /usr/lib/postgresql/16/bin/pg_dump. Si ambos servidores tienen la misma versión, no necesitas nada de esto.
Paso 2: Revisar la base de datos de origen
Antes de migrar, anota el tamaño de la base de datos y el número de filas de las tablas principales para compararlos después:
sudo -u postgres psql -d appdb -c "SELECT pg_size_pretty(pg_database_size('appdb'));"
pg_size_pretty
----------------
12 GB
Revisa también las extensiones instaladas, ya que deben estar disponibles en el destino:
sudo -u postgres psql -d appdb -c "\dx"
Si aparece alguna extensión que no sea de las incluidas con PostgreSQL (por ejemplo postgis o timescaledb), instala su paquete en el servidor de destino antes de restaurar.
Paso 3: Exportar roles y objetos globales
pg_dump vuelca una sola base de datos y no incluye los roles ni sus contraseñas, que son globales al servidor. Expórtalos con pg_dumpall:
sudo -u postgres pg_dumpall --globals-only -f /var/lib/postgresql/globals.sql
El archivo contiene sentencias CREATE ROLE y ALTER ROLE. Ábrelo y elimina los roles que no quieras llevar al destino:
sudo -u postgres nano /var/lib/postgresql/globals.sql
Notasi el servidor de origen es un servicio gestionado sin acceso de superusuario, añade
--no-role-passwordsy define las contraseñas a mano en el destino.
Paso 4: Volcar la base de datos en paralelo
Crea el volcado en formato directorio con varios procesos. Usa como máximo tantos trabajos como núcleos tenga el servidor de origen, y ten en cuenta que cada trabajo abre una conexión adicional:
sudo -u postgres pg_dump \
--format=directory \
--jobs=4 \
--verbose \
--file=/var/lib/postgresql/appdb.dir \
appdb
Al terminar, comprueba el tamaño del volcado y que su índice se lee sin errores:
sudo du -sh /var/lib/postgresql/appdb.dir
sudo -u postgres pg_restore --list /var/lib/postgresql/appdb.dir | head -n 15
3.1G /var/lib/postgresql/appdb.dir
;
; Archive created at 2026-09-25 10:12:03 UTC
; dbname: appdb
; TOC Entries: 412
; Compression: gzip
; Dump Version: 1.15-0
; Format: DIRECTORY
...
Consejoel volcado es una fotografía consistente del momento en que empieza, pero los cambios que se hagan después no se incluyen. Para una migración definitiva, detén las escrituras de la aplicación antes de este paso.
Paso 5: Copiar el volcado al servidor de destino
Copia el directorio y el archivo de roles al destino con rsync, sustituyendo your_user y your_server_ip:
sudo rsync -a --info=progress2 \
/var/lib/postgresql/appdb.dir /var/lib/postgresql/globals.sql \
your_user@your_server_ip:/tmp/
En el servidor de destino, mueve los archivos a un directorio del usuario postgres:
sudo mv /tmp/appdb.dir /tmp/globals.sql /var/lib/postgresql/
sudo chown -R postgres:postgres /var/lib/postgresql/appdb.dir /var/lib/postgresql/globals.sql
Paso 6: Restaurar roles y crear la base de datos
En el servidor de destino, carga los roles:
sudo -u postgres psql -f /var/lib/postgresql/globals.sql
Verás un error role "postgres" already exists, que es normal y se puede ignorar. Comprueba que el rol de la aplicación existe:
sudo -u postgres psql -c "\du appuser"
Crea la base de datos vacía con el mismo propietario que en el origen:
sudo -u postgres createdb --owner=appuser appdb
Paso 7: Restaurar en paralelo
Restaura el volcado con varios trabajos. Aquí conviene usar tantos como núcleos tenga el servidor de destino, porque la creación de índices se reparte entre ellos:
sudo -u postgres pg_restore \
--dbname=appdb \
--jobs=4 \
--exit-on-error \
--verbose \
/var/lib/postgresql/appdb.dir
--exit-on-error detiene la restauración en el primer error en lugar de continuar y dejar una base de datos a medias sin que te enteres. Si el rol propietario no existe en el destino y no quieres crearlo, sustituye esta opción por --no-owner --role=appuser para que todo quede a nombre de appuser.
Al terminar, actualiza las estadísticas del planificador, que no se incluyen en el volcado:
sudo -u postgres vacuumdb --analyze-in-stages --dbname=appdb
Paso 8: Verificar la migración
Compara el tamaño y el número de filas con lo que anotaste en el paso 2. Para un conteo exacto en las tablas importantes, usa count(*) en ambos servidores:
sudo -u postgres psql -d appdb -c "SELECT count(*) FROM pedidos;"
Para una vista general de todas las tablas, esta consulta muestra el número de filas estimado tras el ANALYZE:
sudo -u postgres psql -d appdb -c "SELECT relname, n_live_tup FROM pg_stat_user_tables ORDER BY n_live_tup DESC LIMIT 10;"
relname | n_live_tup
--------------+------------
pedidos | 4812330
lineas | 1920410
clientes | 210944
...
Comprueba por último que la aplicación puede conectarse con su usuario:
psql "host=127.0.0.1 dbname=appdb user=appuser" -c "SELECT current_user, current_database();"
Restaurar solo una parte del volcado
Un volcado en formato directorio o custom permite restaurar objetos concretos sin repetir la exportación.
Para restaurar una sola tabla con sus datos:
sudo -u postgres pg_restore --dbname=appdb --table=clientes /var/lib/postgresql/appdb.dir
Para un control fino, genera la lista de contenido, edítala comentando con ; las líneas que no quieras y restaura usando esa lista:
sudo -u postgres pg_restore --list /var/lib/postgresql/appdb.dir > /tmp/appdb.list
nano /tmp/appdb.list
sudo -u postgres pg_restore --dbname=appdb --use-list=/tmp/appdb.list /var/lib/postgresql/appdb.dir
Otras opciones útiles de pg_dump para volcados parciales son --schema-only (solo estructura), --data-only (solo datos), --schema=nombre y --exclude-table=nombre.
Solución de problemas
pg_dump: error: aborting because of server version mismatch. El pg_dump es más antiguo que el servidor. Instala el cliente de la versión correcta como en el paso 1.
FATAL: sorry, too many clients already durante el volcado. Cada trabajo de --jobs abre una conexión. Reduce el número de trabajos o aumenta max_connections en el origen.
ERROR: role "appuser" does not exist al restaurar. No cargaste los roles del paso 6. Cárgalos, o restaura con --no-owner --role=appuser.
ERROR: extension "postgis" is not available. Falta el paquete de la extensión en el destino. Instálalo (por ejemplo postgresql-16-postgis-3), borra la base de datos con dropdb appdb, vuelve a crearla y repite la restauración.
Conclusión
Has migrado una base de datos PostgreSQL entre servidores con un volcado en formato directorio, restaurado en paralelo junto con sus roles y verificado el resultado. El mismo procedimiento sirve para cambiar de versión mayor. Como siguientes pasos, puedes automatizar volcados periódicos con un temporizador de systemd, reducir la ventana de corte de futuras migraciones con replicación lógica (CREATE PUBLICATION y CREATE SUBSCRIPTION) o configurar copias continuas con archivado de WAL.
