Prácticas recomendadas para la migración de Oracle a PostgreSQL: una lista de verificación para administradores y arquitectos de bases de datos

En resumen La mayoría de las migraciones de Oracle a PostgreSQL no fallan por las herramientas — fallan por pasos omitidos.
Esta lista de verificación cubre todas las fases, desde la evaluación previa a la migración hasta el corte: las trampas de tipos de datos que causan pérdida silenciosa de datos, las diferencias de secuencia y NULL que rompen las aplicaciones después de la puesta en marcha, los pasos de prueba que se eliminan cuando los plazos se acortan, y las decisiones de corte que determinan si se puede revertir si algo sale mal.


La migración de Oracle a PostgreSQL parecía sencilla sobre el papel.

El esquema era sencillo: cincuenta tablas, sin particiones, PL/SQL ligero.

El equipo ejecutó ora2pg, los datos se cargaron limpiamente, los recuentos de filas coincidían.

Salieron en vivo un sábado por la mañana.

El lunes, la cola de asistencia estaba llena.

Todas las marcas de tiempo del sistema indicaban medianoche.

Las columnas DATE de Oracle habían sido mapeadas a DATE de PostgreSQL - que almacena sólo la fecha.

Dos años de datos temporales, descartados silenciosamente.

Sin error.

No hay advertencia.

Ese único error -un valor por defecto erróneo en la configuración de la migración- se puede evitar.

Entonces, cada modo de falla en esta lista también.



¿Cuál es la causa más común de los fallos de migración de Oracle a PostgreSQL?

La causa más común no es la complejidad técnica, sino las suposiciones incontroladas.

Los equipos asumen que PostgreSQL maneja los tipos de datos, la semántica de NULL y la sintaxis SQL de la misma manera que Oracle.

No es así.

Las diferencias son lo bastante pequeñas como para pasarlas por alto durante el desarrollo y lo bastante grandes como para interrumpir la producción.

La lista de comprobación que figura a continuación se ha elaborado a partir de estos patrones de fracaso.

Cada artículo existe porque alguien se lo saltó y lo pagó después.


Fase 1: Evaluación previa a la migración

La evaluación debe cubrir cinco áreas: funciones específicas de Oracle en uso, cada columna DATE que debe mapearse a TIMESTAMP, uso de cadenas vacías frente a NULL en la aplicación, un recuento completo de objetos PL/SQL y una búsqueda de SQL de dialecto Oracle en la base de código.
Si omites alguno de estos, encontrarás la brecha a mitad del proyecto, cuando sea costoso de arreglar.

La fase de evaluación determina el alcance y el coste de todo lo que viene después.
Saltársela es la forma más rápida de superar el presupuesto y perder la fecha de entrada en funcionamiento.

Auditoría de las funciones específicas de Oracle en uso
Verificar particionamiento, colas avanzadas, actualización rápida de vistas materializadas, Oracle Text y Workspace Manager.
Cada una de ellas requiere una decisión arquitectónica, no sólo un cambio de sintaxis.
Algunos tienen equivalentes PostgreSQL.
Algunos requieren rediseño.
Identifíquelos antes de que comience el proyecto, no una vez finalizada la conversión del esquema 80%.

Mapear cada columna Oracle DATE a TIMESTAMP siempre
Oracle DATE almacena tanto la fecha como la hora.
PostgreSQL DATE almacena solo la fecha.
El mapeo de Oracle DATE a PostgreSQL DATE descarta silenciosamente el componente de tiempo de cada valor en esa columna.
No hay ningún error ni advertencia: los datos se cargan limpiamente y el tiempo desaparece.
Todas las columnas Oracle DATE deben mapearse a PostgreSQL TIMESTAMP en la configuración de ora2pg, sin excepción.

Auditoría de cadena vacía frente al uso de NULL
Oracle trata una cadena vacía ('') como NULL.
PostgreSQL las trata como valores distintos.
Una aplicación que inserta '' se espera que un NULL se comporte de manera diferente después de la migración.
Consultar el esquema de origen en busca de columnas con restricciones NOT NULL y comprobar el código de la aplicación en busca de inserciones de cadenas vacías antes de que comience la migración.

Contar y clasificar todos los objetos PL/SQL
Ejecute el informe de evaluación ora2pg (ora2pg -t SHOW_REPORT) para obtener un recuento de objetos y una estimación del coste de migración.
Registre el número de procedimientos almacenados, funciones, paquetes, disparadores y cuerpos de paquetes.
Este es el principal motor del esfuerzo y el costo de migración.
Un esquema sin PL/SQL ni funciones específicas de Oracle puede migrar en días.
Un esquema con cincuenta procedimientos almacenados y diez paquetes lleva semanas.

Identificación de SQL específico de Oracle en el código de la aplicación
Buscar en la base de código de la aplicación: ROWNUM, DE DUAL, NVL(, DECODE(, (+), CONECTAR POR, FECHA_SISTEMA, ADD_MONTHS, TRUNC(, TO_DATE(.
Cada incidencia es un cambio de aplicación necesario tras la migración de la base de datos.
Conocer el volumen antes de que comience el proyecto evita sorpresas en el alcance a mitad de camino.

Secuencia de inventario Valores CACHE y uso de CURRVAL
Las secuencias de Oracle tienen un valor predeterminado de CACHE 20.
Las secuencias de PostgreSQL tienen como valor predeterminado CACHE 1.
Las inserciones de alto rendimiento se comportarán de manera diferente.
Identifique también cada lugar del código de la aplicación que llame a VALOR ACTUAL - PostgreSQL maneja el estado de secuencia local de sesión de forma diferente, y la solución requiere el uso de REGRESANDO o lastval().


Fase 2: Conversión de esquemas

ENCAUSAR
Establece un valor de CACHE realista en la secuencia DDL generada.
Para la mayoría de las cargas de trabajo OLTP, CACHE 20 o superior es apropiado.
PostgreSQL CACHE 1 significa una escritura en disco en cada llamada de secuencia - esto es seguro pero lento a escala.

Columnas booleanas
Oracle no tiene un tipo de datos BOOLEAN nativo.
Las aplicaciones normalmente almacenan valores booleanos como CHAR(1) ('Y'/'N') o NÚMERO(1) (1/0).
PostgreSQL tiene un tipo BOOLEAN nativo.
Usar ora2pg MODIFICAR_TIPO para convertir estas columnas en BOLEANO en lugar de arrastrar la solución provisional de Oracle a la nueva base de datos.
Actualizar el código de la aplicación para usar verdadero/falso en lugar de 'Y'/'N' o 1/0.

Caso identificador
Oracle almacena los identificadores no entrecomillados en mayúsculas.
PostgreSQL almacena los identificadores no entrecomillados en minúsculas.
Nunca entrecomille identificadores en PostgreSQL a menos que el nombre contenga caracteres especiales o mayúsculas y minúsculas que deban ser preservados.
Los identificadores entre comillas en PostgreSQL distinguen entre mayúsculas y minúsculas — "Empleado" y empleado son objetos diferentes.
El enfoque más seguro es dejar que ora2pg convierta todo a identificadores sin comillas en minúsculas y actualizar el código de la aplicación para que coincida.

Particionamiento
El particionamiento de listas, rangos y hash de Oracle se asigna directamente al particionamiento declarativo de PostgreSQL.
El particionamiento por intervalos de Oracle (creación automática de particiones de rango) no tiene un equivalente directo - impleméntelo con una partición de rango y un trabajo programado para añadir futuras particiones.
El particionamiento compuesto de Oracle (por ejemplo, range-hash) requiere un diseño manual en PostgreSQL.
Identifique la estrategia de particionamiento y pruébela en PostgreSQL antes de migrar los datos.

Tipos de índice
Los índices de mapa de bits de Oracle no tienen un equivalente en PostgreSQL.
Identifique cada índice Bitmap en el esquema fuente y decida si un índice B-tree estándar, un índice parcial o un índice BRIN consigue el mismo plan de consulta.
No saltes este paso; los índices faltantes son una de las causas más comunes de problemas de rendimiento posteriores a la migración.


¿Oracle DATE Realmente Necesita Ser Mapeado a TIMESTAMP?

Sí, siempre.

Oracle DATE almacena tanto la fecha como la hora.

PostgreSQL DATE almacena solo la fecha.

Mapear un Oracle DATE a un PostgreSQL DATE descarta silenciosamente el componente de tiempo de cada valor, sin errores ni advertencias.
Configurar MODIFICAR_TIPO fecha TIMESTAMP en la configuración de ora2pg y aplicarlo a todas las columnas DATE en el esquema.


Fase 3: Migración de datos

Desactive las comprobaciones de activación de FK antes de cargar, cargue en orden (DDL → datos → secuencias), restablezca cada secuencia después de la carga utilizando setval(), valide los recuentos de filas para cada tabla y verifique datos en columnas de tipo DATE, numéricas y convertidas.
Omitir cualquiera de estos pasos puede causar corrupción silenciosa de datos o fallos en la inserción después de la puesta en marcha.

Desactivar las comprobaciones de disparadores de FK antes de cargar
ora2pg exporta los datos de la tabla en orden alfabético, no en orden de dependencia de clave externa.
A menudo, una tabla secundaria aparece antes que su matriz en el archivo de datos, lo que provoca violaciones de FK en la carga.
Cargar datos dentro de una sesión con SET session_replication_role = replica para desactivar las comprobaciones de activación de FK y, a continuación, restablecer DEFAULT inmediatamente después de que se complete la carga.

Cargar en la secuencia correcta
Cargar en este orden: DDL de tablas → datos → secuencias.
Las tablas deben existir antes de poder cargar los datos.
Los datos deben cargarse antes de que se restablezcan los valores de secuencia; COPY omite por completo las secuencias, dejándolas en su valor INICIAL independientemente de los ID que se cargaron.

Restablecer secuencias después de la carga de datos
Después de cargar los datos, cada secuencia sigue en su valor START.
El siguiente INSERT intentará utilizar un valor de secuencia que ya existe en la tabla como ID cargado.
Ejecutar setval() para que cada secuencia avance más allá del ID con mayor carga antes de que la aplicación salga en vivo.
El ora2pg SECUENCIA export genera este script — ejecútalo como el paso final.

Validar el recuento de filas para cada tabla
Después de la carga, compare los recuentos de filas entre Oracle y PostgreSQL para cada tabla.
Una discrepancia significa que un error de copia se omitió silenciosamente.
Compruebe la salida de psql para ERROR líneas durante la carga — COPY informa de los errores fila por fila y continúa por defecto.

Verificar datos en columnas de alto riesgo
Tras validar el recuento de filas, compruebe manualmente los valores de las columnas DATE/TIMESTAMP, las columnas numéricas de alta precisión y cualquier columna que haya sido objeto de conversión de tipo.
El recuento automatizado de filas confirma la exhaustividad; las comprobaciones aleatorias confirman la corrección.

¿Mediante la migración y no estás seguro de haberlo cubierto todo?
Ofrezco una evaluación de la migración con una tarifa fija que revisa el esquema, la configuración y el plan de transición y proporciona un registro de riesgos por escrito antes de la puesta en marcha.
Ver qué cubre la evaluación

Fase 4: Cambios en la aplicación

Todas las construcciones SQL del dialecto de Oracle deben sustituirse: ROWNUM → LIMIT, FROM DUAL eliminado, NVL → COALESCE, DECODE → CASE, (+) outer joins → ANSI LEFT JOIN, CONNECT BY → WITH RECURSIVE, SYSDATE → NOW(), y CURRVAL sustituido por lastval() o REGRESANDO.
PostgreSQL rechazará SQL del dialecto de Oracle en tiempo de ejecución — no son opcionales.

OracleEquivalente de PostgreSQL
ROWNUM <= nLÍMITE n
buscar sólo las primeras n filasbuscar sólo las primeras n filas (ANSI, funciona en ambos)
DE DUALQuitar — usar desnudo SELECCIONAR valor
NVL(a, b)COALESCE(a, b)
DECODE(col, v1, r1, v2, r2, default)CASO col CUANDO v1 ENTONCES r1 CUANDO v2 ENTONCES r2 SINO default FIN
col1 (+) = col2col1 LEFT JOIN col2
CONECTAR A PRIORICON RECURSIVE
FECHA_SISTEMAAHORA() o HORA_ACTUAL
VALOR ACTUALlastval() o DEVOLVIENDO id
ADD_MONTHS(d, n)d + INTERVAL 'n meses'
TRUNC(fecha)DATE_TRUNC('día', fecha)

Más allá de la sintaxis, compruebe las conversiones de tipo implícitas que Oracle acepta y que PostgreSQL rechaza.
Oracle hará un "cast" silencioso '123' a un número en una comparación numérica.
PostgreSQL arrojará un error de no coincidencia de tipo.
Identifíquelos en la aplicación y añada calcos explícitos.


Fase 5: Pruebas

Ejecutar pruebas de regresión con la base de datos migrada
Cada función que toque el esquema migrado debe ser probada contra PostgreSQL antes del cutover.
Si la aplicación tiene una suite de pruebas existente, ejecútala en su totalidad.
Si no lo hace, esta es la fase en la que la ausencia de cobertura de pruebas se vuelve costosa: las pruebas funcionales manuales son la única alternativa.

Establecer una línea de base de rendimiento antes de la transición
Ejecute el mismo conjunto de consultas representativas tanto en Oracle como en PostgreSQL.
Recopilar planes de ejecución de PostgreSQL utilizando EXPLICAR (ANALIZAR, BUFERS).
El planificador de consultas de PostgreSQL toma decisiones diferentes a las de Oracle.
Índices faltantes, estadísticas desactualizadas y estrategias de unión incorrectas se muestran aquí, antes de que aparezcan en producción.

Prueba con carga realista
Una consulta que funciona bien de forma aislada puede comportarse de manera diferente bajo carga concurrente.
Realiza una prueba de carga contra PostgreSQL utilizando volúmenes de datos reales o representativos antes de tomar una decisión de continuar o no.
pg_bench proporciona pruebas básicas de rendimiento; es preferible realizar pruebas de carga a nivel de aplicación contra el esquema migrado si existe la herramienta.

Validación de casos extremos de manipulación de NULL
Prueba cada consulta que filtra por NULL, insertando NULL o comparando columnas anulables.
La semántica NULL es consistente entre Oracle y PostgreSQL en SQL estándar, pero el código de aplicación escrito para el comportamiento de cadena vacía como NULL de Oracle producirá resultados incorrectos.

Prueba de los ID generados por secuencias en inserciones simultáneas
Ejecute inserciones concurrentes que dependan de claves primarias generadas por secuencias.
Verifica que no haya colisiones y que los saltos de secuencia estén dentro de los límites aceptables para la aplicación.


Fase 6: Transición

Decida la estrategia de transición antes de que comience el trabajo técnico
Hay dos opciones: transición de ventana de mantenimiento (la aplicación se desconecta durante la transición) o transición sin tiempo de inactividad (la replicación lógica mantiene PostgreSQL sincronizado durante la transición).
La migración durante la ventana de mantenimiento es más simple, económica y confiable.
Para la mayoría de los sistemas internos o que no están de cara al consumidor, una ventana de mantenimiento de dos horas en horas valle es aceptable.
El corte a cero añade complejidad y costes significativos: utilícelo sólo cuando el SLA lo requiera realmente.

Escribir un plan de reversión
Defina exactamente qué requiere la reversión a Oracle: cuánto tiempo lleva, quién la ejecuta y cuál será el estado de los datos en ese momento.
Un plan de reversión que no ha sido escrito no existe.
Si algo sale mal después de la transición y el equipo tiene que improvisar un desmantelamiento bajo presión, el resultado será peor que si el plan se hubiera escrito y ensayado.

Criterios de aprobación/rechazo por escrito
Antes de la noche de corte, acuerden por escrito las condiciones bajo las cuales procederá el corte y las condiciones bajo las cuales revertirá.
Las decisiones de "ir/no ir" tomadas bajo presión de tiempo en medio de una ventana de mantenimiento no son fiables.

Hacer una simulación de la migración en staging
Ejecuta el procedimiento completo de corte —incluida la reversión— en un entorno de staging al menos una vez antes de la producción.
La simulación de prueba sacará a la luz lagunas procedimentales que la preparación técnica pasó por alto.

Plan de comunicación
Identifique quién necesita ser notificado, en qué etapa, por qué canal y quién tiene la autoridad para aprobar el rollback.
Documenta eso antes de que se abra la ventana de corte.


Preguntas frecuentes

¿Cuál es el error más común en una migración de Oracle a PostgreSQL?

Mapeo de columnas Oracle DATE a PostgreSQL DATE en lugar de TIMESTAMP.
Oracle DATE almacena tanto la fecha como la hora.
PostgreSQL DATE almacena solo la fecha.
La migración se completa sin errores, y cada valor de tiempo en esas columnas se establece silenciosamente a la medianoche.
Siempre mapea Oracle DATE a PostgreSQL TIMESTAMP.

¿Necesito realizar pruebas de rendimiento antes de la migración?

Sí, siempre.
El planificador de consultas de PostgreSQL toma decisiones diferentes a las de Oracle.
Los índices que existían en Oracle pueden no haber sido creados en PostgreSQL.
Una consulta que se ejecuta en 200 ms en Oracle puede ejecutarse en 20 segundos en PostgreSQL sin el índice adecuado.
Establezca una línea de base de rendimiento antes de la transición para que no haya sorpresas el día de la puesta en marcha.

¿Cuál es el método de transición más seguro para una base de datos Oracle de producción?

Una interrupción durante una ventana de mantenimiento, donde la aplicación se desconecta brevemente durante el cambio, es la opción más segura para la mayoría de los sistemas.
Elimina la complejidad de mantener dos bases de datos sincronizadas y proporciona al equipo un punto de conmutación limpio y determinista.
Es posible realizar una transición sin tiempo de inactividad mediante replicación lógica, pero añade costes y riesgos significativos.
Úselo solo cuando el SLA realmente no pueda tolerar una ventana de mantenimiento.

¿Puedo revertir después del corte si algo sale mal?

Sí, pero solo si el plan de reversión se redactó antes de que se abriera la ventana de corte.
Una reversión requiere que el entorno de Oracle todavía esté intacto, que el estado de los datos se comprenda y que el procedimiento se haya ensayado.
Si ninguna de estas condiciones existe, revertir se convierte en una recuperación improvisada bajo presión.
Siempre escribe y ensaya el procedimiento de reversión antes del traspaso a producción.

¿PostgreSQL maneja NULL de la misma manera que Oracle?

Para la semántica estándar de NULL de SQL — sí.
La diferencia está en las cadenas vacías: Oracle trata '' como NULL, PostgreSQL las trata como valores distintos.
El código de la aplicación que inserta '' esperando que satisfaga una restricción NOT NULL, o que consulta NULL esperando que coincida con cadenas vacías, se comportará de manera diferente en PostgreSQL.
Auditoría de este patrón durante la fase de evaluación.


En resumen

Una migración de Oracle a PostgreSQL tiene éxito o falla en la preparación.
Las herramientas son gratuitas, están bien documentadas y son confiables.
Los fallos provienen de suposiciones no comprobadas: Oracle DATE mapeado al tipo incorrecto, secuencias dejadas en su valor START, SQL de aplicación que Oracle aceptó silenciosamente y PostgreSQL rechaza explícitamente.

Esta lista de comprobación abarca los modos de fallo que aparecen con más frecuencia en las migraciones reales.
Trabaje fase por fase -evaluación, conversión de esquemas, migración de datos, cambios en la aplicación, pruebas, transición- y ninguna de ellas debería sorprenderle el día de la puesta en marcha.

Guarda esta página — y si necesitas ayuda para aplicarla en producción, ponerse en contacto

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *