Reglas de seguridad para migraciones
Los trabajos de despliegue de migraciones deben fallar rápidamente ante la contención de bloqueos y nunca bloquear el tráfico de la aplicación de forma ilimitada. Codifica tiempos de espera y DDL por fases en las reglas del equipo.
Receta
-- Primeras líneas de cada archivo de migración de producción
SET lock_timeout = '5s';
SET statement_timeout = '0'; -- permitir CONCURRENTLY de larga duración
SET idle_in_transaction_session_timeout = '60s';# Envoltorio del trabajo de despliegue
flyway migrate || { echo "la migración falló - la aplicación NO avanzó"; exit 1; }Cuándo usar esto: Plantilla CI para migraciones SQL, retroceso de incidentes tras acumulación de bloqueos, estandarización de Flyway/Liquibase.
Ejemplo de trabajo
SET lock_timeout = '3s';
BEGIN;
CREATE TABLE app.new_feature (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
name text NOT NULL
);
COMMIT;-- Archivo separado: executeInTransaction=false (Flyway)
SET lock_timeout = '10s';
SET statement_timeout = '0';
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_new_feature_name
ON app.new_feature (name);Reglas del pipeline de despliegue:
- El fallo de la migración bloquea el despliegue de la aplicación (misma etapa del pipeline o anterior)
- Alerta ante
lock timeouten los registros de migración - Comprobación de índice inválido post-despliegue:
SELECT indexrelid::regclass
FROM pg_index
WHERE NOT indisvalid;Análisis detallado
Matriz de tiempos de espera
| Configuración | Predeterminado de migración | Propósito |
|---|---|---|
lock_timeout | 3s-10s | Abortar si no se puede adquirir un bloqueo |
statement_timeout | 0 para CONCURRENTLY; 30s para DDL de prueba | Matar sentencias descontroladas |
idle_in_transaction_session_timeout | 60s | Prevenir sesiones de migración colgadas |
Orden de DDL consciente de bloqueos
ADD COLUMNnullable (rápido)- Relleno (en lotes, trabajo separado)
CREATE INDEX CONCURRENTLYADD CONSTRAINT NOT VALIDVALIDATE CONSTRAINTfuera de horas picoDROP COLUMNsolo después de la fase de contrato de la aplicación
Reglas del trabajo de despliegue
- Conexión única de migración (no Flyway paralelo en la misma base de datos)
- Sin migración durante mantenimiento superpuesto que también reinicie Postgres
- Prueba de humo de diferencia de esquema después de la migración
- Despliegue hacia adelante documentado; sin manipulación de la tabla de historial
Trampas comunes
- Zero lock_timeout - La migración espera horas detrás de una consulta analítica de fin de semana. Solución: Establece siempre
lock_timeoutexplícito. - Mismo statement_timeout para todo SQL - CONCURRENTLY se interrumpe a los 30s en una tabla enorme. Solución: Divide los archivos; deshabilita txn para procesos largos.
- Éxito de migración + índice inválido - Las consultas de la aplicación ignoran el índice roto, tormenta de escaneo secuencial. Solución: Consulta de validez post-despliegue en CI.
- Despliegue de la aplicación antes de la migración - La aplicación antigua accede a una columna que falta. Solución: Migrar primero o expandir el orden compatible.
- Ejecutar migraciones desde el portátil - Omite la verificación de permisos de CI. Solución: Migración a producción solo a través del pipeline.
Alternativas
| Alternativa | Usar cuándo | No usar cuándo |
|---|---|---|
| Herramienta de cambio de esquema en línea (clase gh-ost) | Hábitos de MySQL | CONCURRENTLY nativo de Postgres es suficiente |
| Ventana de mantenimiento | Inicio de tabla pequeña | Servicio con SLA |
| Ejecución manual de DBA | Caso único regulado | Entorno de despliegue continuo |
Preguntas frecuentes
¿Reintentar después de un tiempo de espera de bloqueo?
Sí, con retroceso exponencial en el trabajo de despliegue, después de confirmar que no quedan objetos INVALID parciales no transaccionales.
¿lock_timeout en el código de la aplicación también?
Las aplicaciones usan tiempos de espera más cortos para las consultas; las migraciones usan un rol y un trabajo separados; no copies los valores ciegamente.
¿Quién establece los tiempos de espera: DBA o desarrollador?
El DBA publica la plantilla; el desarrollador la copia en cada archivo de migración a través de un linter o fragmento.
Relacionado
- DDL sin tiempo de inactividad - DDL por fases
- Mejores prácticas de migraciones - lista completa
- Estrategia de reversión - ADR solo hacia adelante
Versiones de pila: Esta página se escribió para PostgreSQL 18.4 (estable 18, mantenimiento 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x y PostGIS 3.5+.