What is the best backup tool for PostgreSQL?

Copiar Bases y Tablas en PostgreSQL

★★★★★Valoración: 4.48 (1472 votos)

En el mundo de la gestión de bases de datos, la necesidad de crear copias de seguridad, entornos de prueba, o simplemente duplicar estructuras y datos es recurrente. PostgreSQL, siendo uno de los sistemas de bases de datos relacionales más potentes y flexibles, ofrece diversas herramientas y comandos para realizar estas tareas de copia de manera eficiente. Ya sea que necesites duplicar una base de datos completa en el mismo servidor para realizar pruebas sin afectar el entorno de producción, o transferir una base de datos a otro servidor para migración o replicación, PostgreSQL te brinda las opciones adecuadas. De igual manera, copiar tablas específicas es una tarea común para análisis o reestructuración de datos. A continuación, exploraremos los métodos clave para lograrlo.

Índice de Contenido

Copiar una Base de Datos PostgreSQL en el Mismo Servidor

Una de las operaciones más comunes es la de duplicar una base de datos dentro del mismo servidor PostgreSQL. Esto es particularmente útil para crear entornos de desarrollo o prueba basados en datos de producción, o para experimentar con cambios de esquema sin arriesgar la base de datos original. PostgreSQL simplifica enormemente esta tarea mediante el uso de la cláusula TEMPLATE dentro de la sentencia CREATE DATABASE.

La sintaxis básica para copiar una base de datos existente (sourcedb) a una nueva base de datos (targetdb) es la siguiente:

CREATE DATABASE targetdb WITH TEMPLATE sourcedb;

Este comando crea una nueva base de datos llamada targetdb que es una copia exacta de la base de datos sourcedb en el momento en que se ejecuta el comando. La copia incluye todos los esquemas, tablas, datos, índices, secuencias, etc., de la base de datos origen.

Por ejemplo, si deseas crear una copia de una base de datos de ejemplo llamada dvdrental para usarla en pruebas, podrías ejecutar:

CREATE DATABASE dvdrental_test WITH TEMPLATE dvdrental;

La duración de esta operación dependerá directamente del tamaño de la base de datos origen y de las capacidades del hardware del servidor.

Manejando Conexiones Activas

Un obstáculo común al intentar copiar una base de datos usando el método TEMPLATE es que la base de datos origen no puede tener conexiones activas al momento de la copia. Si existen sesiones conectadas a la base de datos origen, PostgreSQL generará un error similar a este:

ERROR: source database "dvdrental" is being accessed by other users
DETAIL: There is 1 other session using the database.

Para identificar las conexiones activas a una base de datos específica, puedes consultar la vista del sistema pg_stat_activity:

SELECT pid, usename, client_addr
FROM pg_stat_activity
WHERE datname = 'dvdrental';

Esta consulta te mostrará el ID del proceso (pid), el nombre de usuario (usename) y la dirección IP del cliente (client_addr) para cada conexión activa a la base de datos especificada.

Una vez identificadas las conexiones, puedes optar por pedir a los usuarios que se desconecten o, si es necesario y tienes los permisos adecuados, puedes terminarlas forzosamente utilizando la función pg_terminate_backend(). Es crucial ser extremadamente cuidadoso al usar esta función en entornos de producción, ya que puede interrumpir operaciones en curso:

SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'dvdrental';

Este comando termina todas las sesiones activas conectadas a la base de datos dvdrental. Después de asegurarte de que no hay conexiones activas, puedes intentar nuevamente el comando CREATE DATABASE WITH TEMPLATE.

El método TEMPLATE es rápido y eficiente para copias locales, siempre que puedas gestionar las conexiones activas.

Copiar una Base de Datos PostgreSQL entre Servidores Diferentes

Copiar una base de datos de un servidor PostgreSQL a otro es una tarea más compleja que la copia local, ya que implica la transferencia de datos a través de una red. PostgreSQL ofrece herramientas de línea de comandos robustas, principalmente pg_dump y psql, para facilitar este proceso. La elección del método dependerá en gran medida del tamaño de la base de datos y de la calidad de la conexión de red entre los servidores.

Método 1: Usando pg_dump y psql (Dump y Restauración)

Este es el método más flexible y recomendado para bases de datos grandes o cuando la conexión de red es lenta o inestable. Consiste en exportar la base de datos origen a un archivo (un "dump"), transferir ese archivo al servidor de destino y luego restaurarlo en una nueva base de datos en el servidor de destino.

Los pasos generales son los siguientes:

Paso 1: Exportar la base de datos origen a un archivo (dump).

En el servidor de origen, utiliza el comando pg_dump. La sintaxis básica es:

pg_dump -U usuario_origen -d base_datos_origen -f archivo_dump.sql

Donde:

  • -U usuario_origen: Especifica el usuario de PostgreSQL para conectarse a la base de datos origen.
  • -d base_datos_origen: Especifica el nombre de la base de datos a exportar.
  • -f archivo_dump.sql: Especifica el nombre del archivo donde se guardará la salida.

Puedes añadir otras opciones útiles, como -h para especificar el host si no estás en el servidor local, o -O para omitir la restauración de la propiedad de los objetos (útil si el usuario en el servidor de destino es diferente).

Ejemplo para la base de datos dvdrental:

pg_dump -U postgres -O dvdrental -f dvdrental.sql

Esto creará un archivo llamado dvdrental.sql en el directorio actual.

Paso 2: Copiar el archivo dump al servidor de destino.

Utiliza herramientas estándar del sistema operativo como scp (Secure Copy Protocol) o rsync para transferir el archivo dvdrental.sql desde el servidor de origen al servidor de destino. Por ejemplo:

scp dvdrental.sql usuario_destino@servidor_destino:/ruta/en/destino/

Paso 3: Crear una nueva base de datos en el servidor de destino.

Conéctate al servidor de destino (usando psql o cualquier cliente) y crea una base de datos vacía que servirá como destino para la restauración:

CREATE DATABASE base_datos_destino;

Es recomendable que el nombre sea el mismo que el de origen si vas a reemplazarla, o uno nuevo si es una copia paralela.

Paso 4: Restaurar el archivo dump en la nueva base de datos del servidor de destino.

En el servidor de destino, utiliza el comando psql para ejecutar el script SQL contenido en el archivo dump. Asegúrate de estar en el directorio donde copiaste el archivo o especifica la ruta completa.

psql -U usuario_destino -d base_datos_destino -f archivo_dump.sql

Donde:

  • -U usuario_destino: Especifica el usuario de PostgreSQL para conectarse a la base de datos destino.
  • -d base_datos_destino: Especifica el nombre de la base de datos donde se restaurarán los datos.
  • -f archivo_dump.sql: Especifica el archivo dump a restaurar.

Ejemplo para restaurar dvdrental.sql en la base de datos dvdrental del servidor de destino:

psql -U postgres -d dvdrental -f dvdrental.sql

Este método es robusto porque la transferencia del archivo dump puede ser reanudada en algunos casos (dependiendo de la herramienta usada) y no requiere una conexión persistente y de alta velocidad durante todo el proceso de copia.

Método 2: Copia Directa con Tubería (Pipe)

Si la base de datos no es extremadamente grande y la conexión de red entre los servidores es rápida y confiable, puedes realizar la copia de forma más directa utilizando una tubería (pipe) entre pg_dump en el origen y psql en el destino. Esto evita la necesidad de crear un archivo intermedio.

La sintaxis general es:

pg_dump -h host_origen -U usuario_origen base_datos_origen | psql -h host_destino -U usuario_destino base_datos_destino

Donde:

  • -h host_origen: Host del servidor de origen.
  • -U usuario_origen: Usuario para conectar al servidor de origen.
  • base_datos_origen: Base de datos a copiar del origen.
  • |: El operador de tubería que dirige la salida estándar de pg_dump a la entrada estándar de psql.
  • -h host_destino: Host del servidor de destino.
  • -U usuario_destino: Usuario para conectar al servidor de destino.
  • base_datos_destino: Base de datos donde se restaurarán los datos en el destino. (Nota: Esta base de datos debe existir previamente en el destino).

Ejemplo para copiar la base de datos dvdrental desde localhost a un servidor remoto:

pg_dump -C -h localhost -U postgres dvdrental | psql -h remoto -U postgres dvdrental

La opción -C (--create) en pg_dump es útil aquí porque añade el comando CREATE DATABASE al script de salida, lo que permite que psql cree la base de datos en el destino si no existe (aunque a menudo es más seguro crearla manualmente antes). Sin embargo, si la base de datos ya existe en el destino, -C puede causar errores si no se combina con otras opciones como --clean (que borraría objetos existentes, ¡usar con precaución!). Por simplicidad y seguridad, a menudo se crea la base de datos destino *antes* de ejecutar este comando pipe, omitiendo -C.

Este método es rápido para copias directas, pero es sensible a interrupciones de red durante el proceso.

Comparativa de Métodos de Copia entre Servidores

MétodoTamaño BDConexiónArchivo IntermedioComplejidadResiliencia
Dump y Restauración (pg_dump -f y psql -f)GrandeLenta/InestableSíMediaAlta (transferencia de archivo separada)
Copia Directa (pg_dump | psql)Pequeña/MedianaRápida/EstableNoBajaBaja (sensible a interrupciones)

Cómo Copiar una Tabla en PostgreSQL

Además de copiar bases de datos completas, es frecuente la necesidad de duplicar solo una tabla específica, ya sea con todos sus datos o un subconjunto de ellos. PostgreSQL proporciona una sintaxis sencilla y poderosa para esto utilizando la sentencia CREATE TABLE ... AS.

Método 1: Copiar Estructura y Datos Completos

La forma más directa de copiar una tabla completa, incluyendo su estructura y todos los datos que contiene, es usando CREATE TABLE ... AS TABLE:

CREATE TABLE nueva_tabla AS TABLE tabla_origen;

Este comando crea una nueva tabla llamada nueva_tabla y la llena con todas las filas y columnas de tabla_origen. Es importante notar que este método copia la estructura y los datos, pero no copia los índices, las restricciones (como claves primarias, claves foráneas, restricciones CHECK) ni los valores por defecto definidos en la tabla origen.

Método 2: Copiar Estructura y Datos con Filtro

Si solo necesitas copiar un subconjunto de los datos de la tabla origen, puedes hacerlo especificando una consulta SELECT con una cláusula WHERE:

CREATE TABLE nueva_tabla AS SELECT * FROM tabla_origen WHERE condicion;

Aquí, condicion es cualquier expresión booleana válida que filtra las filas de tabla_origen. Solo las filas que satisfagan esta condición serán copiadas a nueva_tabla.

Por ejemplo, para copiar solo los clientes activos de una tabla clientes:

CREATE TABLE clientes_activos AS SELECT * FROM clientes WHERE estado = 'activo';

Similar al método anterior, CREATE TABLE AS SELECT copia la estructura resultante de la consulta y los datos, pero no copia índices, restricciones o valores por defecto de la tabla origen. Para duplicar completamente una tabla con todas sus propiedades (índices, restricciones, etc.), se necesitarían pasos adicionales como obtener la definición de la tabla (usando pg_dump -s para la tabla específica) y ejecutarla, y luego insertar los datos.

El comando CREATE TABLE AS es una herramienta muy útil para crear rápidamente copias de tablas para análisis temporal o para crear tablas de agregación, pero siempre teniendo en cuenta que no replica todas las propiedades de la tabla original.

¿Por Qué Copiar Bases de Datos o Tablas?

Existen múltiples escenarios donde la copia de datos es fundamental:

  • Desarrollo y Pruebas: Crear copias de la base de datos de producción para desarrollar nuevas funcionalidades o probar cambios sin afectar el entorno real.
  • Copias de Seguridad: Aunque pg_dump se usa a menudo para exportar datos para copias de seguridad, una copia completa de la base de datos puede servir como un punto de restauración rápido.
  • Migración: Mover una base de datos a un servidor diferente o a una versión más reciente de PostgreSQL.
  • Informes y Análisis: Copiar datos o tablas específicas a un entorno separado para ejecutar consultas analíticas pesadas sin impactar el rendimiento de la base de datos principal.
  • Archivado: Mover datos antiguos o menos utilizados a tablas separadas o bases de datos de archivo.

Comprender y dominar los métodos de copia es una habilidad esencial para cualquier persona que trabaje con PostgreSQL.

Consideraciones Adicionales

  • Permisos: Para realizar la mayoría de estas operaciones, necesitarás permisos adecuados, a menudo de superusuario o al menos permisos para crear bases de datos y tablas, y seleccionar datos.
  • Espacio en Disco: Asegúrate de tener suficiente espacio libre en disco tanto en el servidor de origen (si creas un archivo dump) como en el servidor de destino para alojar la copia de la base de datos o tabla.
  • Consistencia: Los métodos CREATE DATABASE WITH TEMPLATE y pg_dump crean una instantánea consistente de la base de datos en el momento de la copia (asumiendo que no hay transacciones de larga duración que puedan interferir en el caso de pg_dump o conexiones activas para TEMPLATE). CREATE TABLE AS es transaccional para la creación de la tabla y la inserción de datos, garantizando la consistencia de la copia en el momento de la ejecución.
  • Objetos no Copiados por CREATE TABLE AS: Recuerda siempre que CREATE TABLE AS no copia índices, restricciones (PK, FK, UNIQUE, CHECK), valores por defecto, reglas, triggers, información de propiedad o permisos de la tabla origen. Si necesitas replicar todos estos elementos, el enfoque de dump/restore (pg_dump -s tabla_origen para la estructura y luego pg_dump -a tabla_origen para los datos, o simplemente pg_dump tabla_origen y restaurar) es más adecuado.

Preguntas Frecuentes (FAQ)

¿Puedo copiar una base de datos con conexiones activas usando CREATE DATABASE WITH TEMPLATE?
No. Este método requiere que no haya conexiones activas a la base de datos origen. Debes esperar a que las conexiones finalicen o terminarlas manualmente (con precaución).
¿pg_dump copia usuarios y roles?
Por defecto, pg_dump exporta la definición de la base de datos, incluyendo esquemas, tablas, datos, etc., pero no los roles globales o definiciones de usuarios. Estos generalmente deben gestionarse por separado (por ejemplo, usando pg_dumpall -g para roles globales).
¿La copia con CREATE TABLE AS incluye los valores por defecto de las columnas?
No. CREATE TABLE AS copia la estructura de las columnas y los datos existentes, pero no replica las definiciones de valores por defecto de las columnas ni otras propiedades a nivel de columna o tabla.
¿Cómo copio una tabla con sus índices y restricciones?
El método más seguro es usar pg_dump para exportar solo la definición de la tabla (pg_dump -s -t nombre_tabla base_datos) y luego restaurarla, seguido de un dump de solo los datos (pg_dump -a -t nombre_tabla base_datos) y restaurarlo. O simplemente exportar la tabla completa (pg_dump -t nombre_tabla base_datos) y restaurarla.
¿Qué pasa con las secuencias asociadas a columnas SERIAL con CREATE TABLE AS?
CREATE TABLE AS copia el *valor actual* de la secuencia para cada fila, pero no crea una nueva secuencia ni asocia una columna SERIAL a ella en la nueva tabla. Si la tabla copiada tiene columnas SERIAL, deberás crear manualmente una nueva secuencia y asociarla a la columna correspondiente en la tabla copiada si necesitas que funcione como una columna auto-incremental.

En resumen, PostgreSQL ofrece herramientas potentes y flexibles para satisfacer diversas necesidades de copia de datos. Ya sea una copia rápida local con TEMPLATE, una migración robusta entre servidores con pg_dump y psql, o la duplicación selectiva de tablas con CREATE TABLE AS, comprender estos métodos te permitirá gestionar eficazmente tus bases de datos y flujos de trabajo.

Si quieres conocer otros artículos parecidos a Copiar Bases y Tablas en PostgreSQL puedes visitar la categoría Bases de datos.

Ivan

Soy un entusiasta de la tecnología con especialización en bases de datos, particularmente en MySQL. A través de mis tutoriales detallados, busco desmitificar los conceptos complejos y proporcionar soluciones prácticas a los desafíos cotidianos relacionados con la gestión de datos

Aprende mas sobre MySQL

Subir