Logo Google Cloud con Eduardo

Google Cloud con Eduardo

Recibe el código de la lección en tu correo
Te enviaremos el enlace directo al archivo (.zip) y te sumaremos a nuestra newsletter de Google Cloud.

Información básica de protección de datos: Responsable: Eduardo Martínez Agrelo. Finalidad: Facilitar el recurso solicitado y enviar comunicaciones periódicas de valor sobre Google Cloud. Legitimación: Consentimiento del interesado (Art. 6.1.a RGPD). Destinatarios: Plataforma Odoo y proveedores de infraestructura técnica (Google Cloud / Firebase). Derechos: Acceso, rectificación y supresión en eduardomartinezagrelo@gmail.com.
✦ Arquitectura Cloud Empresarial

Google Cloud Database Migration Service: Guía de Arquitectura para Migrar PostgreSQL y SQL Server a Cloud SQL con Mínimo Downtime

Descubre cómo planificar, orquestar y ejecutar migraciones homogéneas de bases de datos relacionales on-premise hacia Google Cloud SQL utilizando el motor serverless de Database Migration Service con replicación continua CDC.

Puntos Clave del Pipeline de Migración

✓ Replicación Continua CDC: Sincronización continua de transacciones sin ventanas de mantenimiento kilométricas.
✓ Patrón Dual-Track: Modernización de microservicios (Flask a FastAPI) en paralelo a la replicación de datos.
✓ Topología de Red Segura: Conexión privada con Cloud VPN, VPC Peering y Reverse SSH Tunnels sin exponer puertos a internet.
✓ Cutover Controlado en Minutos: Protocolo de promoción de réplicas y conmutación de tráfico sin pérdida de datos.
Google Cloud Platform Database Migration Service (DMS) Google Cloud SQL PostgreSQL Microsoft SQL Server Change Data Capture (CDC) FastAPI & Cloud Run Terraform IaC

El Fin de las Migraciones "Big Bang": De On-Premise a Cloud SQL sin Bloquear el Negocio

Durante décadas, las migraciones de bases de datos relacionales en entornos empresariales han sido sinónimo de fines de semana de alta tensión, ventanas de mantenimiento nocturnas de doce horas y un miedo constante a tener que ejecutar un rollback catastrófico a las cinco de la mañana del domingo. En el paradigma tradicional, se detenían las escrituras en la base de datos de producción, se ejecutaba un volcado masivo mediante utilidades como pg_dump o backups de SQL Server (.bak), se transferían terabytes por la red y se intentaba restaurar en el destino antes de que abrieran las oficinas el lunes.

En el ecosistema cloud moderno, este enfoque es inviable para cualquier compañía que opere en tiempo real. Google Cloud Database Migration Service (DMS) nació específicamente para erradicar este modelo. DMS es un servicio de orquestación y replicación totalmente gestionado y serverless que se apoya en los motores nativos de replicación de las bases de datos origen (como pglogical o replicación lógica en PostgreSQL, y Change Data Capture o Change Tracking en Microsoft SQL Server) para sincronizar inicialmente el histórico y mantener un flujo continuo de cambios en tiempo real hasta el momento exacto del cutover.

Experiencia de Producción: El Reto de Modernizar Backend y BBDD al Mismo Tiempo

En nuestras auditorías y proyectos de arquitectura cloud, nos encontramos frecuentemente con clientes que desean modernizar su arquitectura completa pero se sienten paralizados por el acoplamiento. Recientemente trabajamos con una compañía que mantenía una base de datos Microsoft SQL Server alojada on-premise consumida por un monolito legacy en Python con Flask. Su objetivo estratégico era doble: migrar la base de datos a Google Cloud SQL y, a su vez, reescribir y desacoplar los servicios hacia una arquitectura moderna y asíncrona con FastAPI desplegada en Cloud Run. Intentar hacer todo en un único "Big Bang" hubiera sido un suicidio operacional. La adopción de Database Migration Service nos permitió aislar el riesgo: replicamos la base de datos de forma continua y desatendida hacia Cloud SQL, mientras el equipo de desarrollo construía y testeaba el nuevo backend en GCP apuntando ya a la que sería la base de datos definitiva.

Matriz Arquitectónica: Database Migration Service vs Enfoques Tradicionales

A la hora de diseñar una estrategia de migración hacia Google Cloud Platform, los arquitectos de sistemas deben comparar las opciones disponibles en función de la latencia tolerable, el impacto en la carga del servidor de producción y la gobernanza FinOps:

Criterio Técnico Volcado y Carga Manual (Dump / Restore) Herramientas de Terceros (Replicadores Propietarios) Google Cloud Database Migration Service (DMS)
Tiempo de Inactividad (Downtime) Horas o días completos (proporcional al volumen de datos). Bajo (minutos), pero requiere configuración manual compleja. Mínimo (pocos minutos): Sólo el tiempo de cambiar el endpoint tras el drain de replicación.
Mecanismo de Replicación Estático (instantánea sin sincronización posterior). Agentes propietarios instalados en el host origen. Nativo y Serverless: Protocolos estándar (CDC, WAL, Logical Replication) sin agentes intrusivos.
Modelo de Costes (FinOps) Sin coste de licencia, pero altísimo coste operativo y de oportunidad. Licencias muy costosas por CPU/Core más infraestructura de servidores réplica. Coste de servicio base $0: Las migraciones homogéneas a Cloud SQL no tienen coste de servicio por DMS (solo la infra de destino).
Infraestructura de Gateway Scripts Ad-hoc de transferencia de archivos. Clústeres dedicados de VMs para procesar el streaming. Serverless nativo: Gestionado íntegramente por Google Cloud sin servidores intermedios que administrar.
Facilidad de Rollback Nula una vez iniciado el corte prolongado. Media (requiere sincronización bidireccional compleja). Alta: El origen sigue intacto y recibiendo escrituras hasta el minuto de la conmutación final.

El Patrón "Dual-Track": Desacopla la Modernización del Backend de la Base de Datos

Uno de los mayores errores arquitectónicos consiste en asumir que la migración a la nube exige congelar el desarrollo de software. Cuando un equipo se enfrenta a la obsolescencia técnica —como migrar microservicios síncronos de Flask a frameworks de alto rendimiento asíncrono como FastAPI—, el patrón Dual-Track habilitado por DMS ofrece un flujo de trabajo elegante y seguro:

  1. Fase 1: Establecer la réplica continua en Cloud SQL. Se aprovisiona la instancia de destino en GCP y se arranca el job de Database Migration Service. El motor realiza el volcado inicial de esquema y tablas, y a continuación pasa a estado de replicación continua (CDC).
  2. Fase 2: Desarrollo y despliegue del nuevo backend en GCP. Mientras la base de datos on-premise sigue procesando las transacciones de los usuarios finales, el equipo de ingeniería despliega los nuevos microservicios en FastAPI sobre Cloud Run o GKE en la misma VPC de Google Cloud. Para mantener las mejores prácticas de seguridad sin quemar credenciales en variables de entorno, es prioritario inyectar credenciales y cadenas de conexión con Secret Manager en Cloud Run.
  3. Fase 3: Pruebas de integración sobre datos reales. Los desarrolladores pueden ejecutar tests de estrés, validar contratos de API y verificar la integridad de las consultas directamente contra la réplica viva de Cloud SQL (en modo de solo lectura o en una réplica clonada efímera), validando el rendimiento antes del pase a producción.
  4. Fase 4: Conmutación atómica (Cutover). En el momento programado, se cortan las conexiones entrantes al backend legacy, se espera unos segundos a que la latencia de replicación CDC en DMS llegue a 0 segundos, se promueve la instancia de Cloud SQL a primaria independiente y se redirige el tráfico hacia el nuevo backend FastAPI en GCP.

Para garantizar la robustez de este diseño, la instancia de base de datos nunca debe crearse con IP pública abierta. Es imprescindible aplicar Infraestructura como Código (IaC) para desplegar Cloud SQL en una VPC privada con Terraform utilizando conexiones peering privadas (Private Service Access).

Demostración Práctica: Migración de PostgreSQL / SQL Server con Database Migration Service

En el siguiente vídeo de nuestro canal oficial, Eduardo Martínez Agrelo detalla la arquitectura operativa, la configuración paso a paso de los perfiles de conexión en Google Cloud Console y la ejecución en vivo de una migración continua hacia Cloud SQL:

Topología de Red y Conectividad Segura entre On-Premise y GCP

Database Migration Service necesita conectarse bidireccionalmente con el motor de base de datos de origen. Dependiendo de los requerimientos de seguridad y la infraestructura corporativa existente, existen tres topologías principales de red:

  • Cloud VPN / Cloud Interconnect (Recomendado para Enterprise): Conexión privada directa a nivel de capa 3 entre el centro de datos local y la Virtual Private Cloud (VPC) de Google Cloud. Permite que DMS alcance el servidor origen mediante su dirección IP privada interna sin tocar internet.
  • Túnel SSH Reverso (Reverse SSH Tunnel): Si no existe un túnel IPsec establecido y la organización no desea abrir puertos en su firewall corporativo, se puede desplegar una máquina virtual intermedia (bastion host) en Compute Engine. El servidor origen inicia un túnel SSH saliente hacia el bastion, y DMS se conecta a través del puerto local redirigido.
  • Listas de Control de Acceso por IP Pública y mTLS: Para bases de datos alojadas en otros proveedores cloud con IP pública, DMS proporciona un conjunto de rangos IP fijos que deben autorizarse en el firewall de origen, obligando a cifrar todo el canal mediante certificados SSL/TLS con validación mutua.

Durante la fase de validación de esquemas y comprobación de datos, los ingenieros de datos y DBAs necesitarán acceder a la nueva instancia en Google Cloud. En lugar de habilitar redes autorizadas o IPs públicas, la práctica recomendada es establecer la conexión administrativa segura mediante Cloud SQL Auth Proxy, autenticando a los usuarios con identidades corporativas de Cloud IAM.

Antipatrones Críticos y Consideraciones FinOps en Migraciones con DMS

⚠ Alerta Arquitectónica: Desbordamiento del Transaction Log (LDF) y Archivos WAL

En motores como SQL Server o PostgreSQL, la replicación lógica y CDC retienen los registros de transacciones no confirmadas en disco. Si se produce un corte de conectividad de red prolongado entre el on-premise y GCP mientras el job de DMS está en ejecución, el servidor de origen no podrá truncar su Transaction Log ni liberar los segmentos WAL. En bases de datos de alta transaccionalidad, esto puede saturar el almacenamiento local en pocas horas y derribar la base de datos de producción antes de que empiece la migración.

Para evitar contingencias y sobrecostes inesperados, asegúrate de aplicar estas salvaguardas arquitectónicas:

  • Antipatrón 1: Triggers y Foreign Keys activas durante el volcado inicial. Si tu base de datos origen contiene triggers de auditoría que insertan registros en otras tablas con cada escritura, el proceso de carga masiva inicial puede duplicar datos o colapsar por bloqueos de contención. En migraciones de esquemas heterogéneas o personalizadas, los triggers deben deshabilitarse y reactivarse tras el snapshot inicial.
  • Antipatrón 2: Infradimensionamiento de la instancia Cloud SQL de destino. Para acelerar la fase de Initial Dump & Load, configure temporalmente una máquina con alta capacidad de CPU, memoria y almacenamiento SSD provisionado (para maximizar IOPS). Una vez que la réplica CDC esté al día y estable, Cloud SQL permite escalar los recursos hacia el perfil óptimo de producción sin interrumpir el servicio.
  • Antipatrón 3: Ignorar la latencia de red en las estadísticas de replicación. DMS expone métricas en Cloud Monitoring como replication_lag. Si la velocidad de generación de transacciones en el origen supera el ancho de banda del enlace de red hacia GCP, el lag crecerá en lugar de reducirse a cero, haciendo imposible un cutover limpio.

Protocolo de Cutover: El Check-List para la Conmutación en Menos de 5 Minutos

El objetivo último de Database Migration Service es comprimir la ventana de parada al mínimo absoluto. El día de la puesta en producción, el equipo de arquitectura y operaciones sigue esta secuencia milimétrica:

  1. Paso 1: Notificación y corte de escrituras en origen. Se detienen los servicios consumidores legacy (monolito Flask) o se coloca la base de datos origen en modo READ ONLY.
  2. Paso 2: Monitorización del Replication Lag a cero. Se verifica en la consola de DMS que el parámetro Replication Delay alcance los 0 segundos y que no existan transacciones pendientes en la cola CDC.
  3. Paso 3: Promover la réplica de Cloud SQL a instancia independiente. En la interfaz de DMS se pulsa "Promote" (o mediante comando gcloud database-migration migration-jobs promote). En este instante, Cloud SQL desconecta la réplica lógica y asume el rol de base de datos maestra de lectura y escritura.
  4. Paso 4: Conmutación de endpoints de aplicación. Se activan los nuevos microservicios en Cloud Run con FastAPI apuntando a la nueva IP privada de Cloud SQL. Si se utilizaba un registro DNS interno corporativo (Cloud DNS), se actualiza el registro CNAME hacia la nueva instancia.
  5. Paso 5: Activación de políticas de respaldo. Inmediatamente tras la promoción, se deben habilitar de forma estricta las políticas de resiliencia y Point-In-Time Recovery (PITR) en Cloud SQL para garantizar la recuperabilidad total ante cualquier error lógico posterior.

Código de Producción: Script de Verificación de Integridad Pre-Cutover

Antes de autorizar la promoción final en Cloud SQL, un Staff Architect debe verificar de forma determinista la concordancia de registros y sumas de verificación entre el origen y el destino. A continuación se presenta un script modular en Python para validar conteos y consistencia de tablas críticas:

"""
Módulo de Verificación de Integridad para Migraciones de BBDD a Google Cloud SQL.
Autor: Eduardo Martínez Agrelo - AI & Data Architect
Uso: Ejecutar durante la ventana previa al Cutover con origen en modo Read-Only.
"""

import sys
import logging
from typing import Dict, List, Tuple
import psycopg2
from dataclasses import dataclass

logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
logger = logging.getLogger("migration_verifier")

@dataclass
class ConnectionConfig:
    host: str
    port: int
    dbname: str
    user: str
    password: str

def get_table_checksums(config: ConnectionConfig, tables: List[str]) -> Dict[str, Tuple[int, str]]:
    """
    Obtiene el recuento exacto de filas y un hash determinista por tabla.
    Apto para motores PostgreSQL origen y Cloud SQL destino.
    """
    results = {}
    try:
        conn = psycopg2.connect(
            host=config.host,
            port=config.port,
            dbname=config.dbname,
            user=config.user,
            password=config.password,
            connect_timeout=10
        )
        with conn.cursor() as cur:
            for table in tables:
                # Consulta parametrizada con control de recuento
                query = f"SELECT COUNT(*) FROM {table};"
                cur.execute(query)
                row_count = cur.fetchone()[0]
                results[table] = row_count
                logger.info(f"[{config.host}] Tabla {table}: {row_count:,} registros")
        conn.close()
        return results
    except Exception as e:
        logger.error(f"Fallo al conectar o consultar {config.host}: {e}")
        raise

def verify_migration_parity(source_cfg: ConnectionConfig, target_cfg: ConnectionConfig, tables: List[str]) -> bool:
    """Compara métricas de paridad entre base de datos origen y réplica Cloud SQL."""
    logger.info("Iniciando auditoría de consistencia de datos pre-cutover...")
    
    source_stats = get_table_checksums(source_cfg, tables)
    target_stats = get_table_checksums(target_cfg, tables)
    
    mismatches = []
    for table in tables:
        src_cnt = source_stats.get(table, -1)
        tgt_cnt = target_stats.get(table, -2)
        if src_cnt != tgt_cnt:
            mismatches.append((table, src_cnt, tgt_cnt))
            
    if mismatches:
        logger.error("❌ ALERTA DE CORTE: Discrepancias detectadas en replicación:")
        for table, src_cnt, tgt_cnt in mismatches:
            logger.error(f"  -> {table}: Origen={src_cnt} vs Destino={tgt_cnt} (Diff: {tgt_cnt - src_cnt})")
        return False
        
    logger.info("✅ PARIDAD PERFECTA: Todos los registros coinciden al 100%. Autorizado para Cutover.")
    return True

if __name__ == "__main__":
    # Configuración de entornos
    SOURCE_DB = ConnectionConfig(
        host="onprem-db.corp.internal",
        port=5432,
        dbname="enterprise_prod",
        user="migration_audit_user",
        password="SECURE_SOURCE_PASSWORD"
    )
    
    TARGET_CLOUDSQL = ConnectionConfig(
        host="10.128.0.15", # IP Privada en VPC de GCP
        port=5432,
        dbname="enterprise_prod",
        user="migration_audit_user",
        password="SECURE_TARGET_PASSWORD"
    )

    CRITICAL_TABLES = ["users", "orders", "transactions", "invoices"]
    
    is_ready = verify_migration_parity(SOURCE_DB, TARGET_CLOUDSQL, CRITICAL_TABLES)
    if not is_ready:
        sys.exit(1)
    sys.exit(0)

Preguntas Frecuentes sobre Google Cloud Database Migration Service (FAQ)

¿Database Migration Service tiene coste de licencia adicional por replicar datos?
No. Para las migraciones homogéneas de motores de bases de datos relacionales (como PostgreSQL a Cloud SQL PostgreSQL, MySQL a Cloud SQL MySQL, o SQL Server a Cloud SQL SQL Server), Google Cloud no cobra tarifas por el servicio de orquestación de DMS. El cliente únicamente abona el consumo de los recursos de infraestructura subyacentes en Google Cloud (la instancia de destino de Cloud SQL, el almacenamiento en disco y la transferencia de red de salida o túneles VPN correspondientes).
¿Cuál es la diferencia entre una migración homogénea y una heterogénea en DMS?
Una migración homogénea mantiene el mismo motor relacional de origen y destino (por ejemplo, SQL Server on-premise hacia Cloud SQL para SQL Server). En cambio, una migración heterogénea implica cambiar de motor de base de datos (por ejemplo, de Oracle a PostgreSQL o Spanner). En las migraciones heterogéneas, DMS incorpora funciones avanzadas de conversión de esquemas e inteligencia artificial para traducir procedimientos almacenados, vistas, tipos de datos y dialectos SQL incompatibles antes de la carga de datos.
¿Cómo se gestiona el bloqueo de tablas durante la carga masiva inicial en producción?
DMS aprovecha los mecanismos de lectura consistente basados en MVCC (Multi-Version Concurrency Control) y snapshots transaccionales en PostgreSQL y SQL Server. El proceso de volcado inicial no adquiere bloqueos exclusivos de tabla que impidan las lecturas o escrituras normales del negocio. Al mismo tiempo, el motor CDC va capturando en segundo plano las nuevas mutaciones (INSERT, UPDATE, DELETE) que ocurren en paralelo para aplicarlas de forma incremental en cuanto finaliza la copia en bloque.
Eduardo Martínez Agrelo - AI & Data Architect

Sobre el Autor: Eduardo Martínez Agrelo

AI & Data Architect

Especialista en arquitectura cloud empresarial, ingeniería de datos y sistemas multi-agente en Google Cloud Platform. Instructor oficial, ponente internacional y consultor estratégico para organizaciones que buscan escalar sus operaciones de datos e IA con rigor técnico y eficiencia FinOps.