Este es el cuarto post de la serie dedicada a Oracle GoldenGate. En los anteriores hemos visto conceptos teóricos y hemos solventando dos casos de uso:

En el post relativo a la replicación unidireccional resolvimos el objetivo de Negocio de dotar de vistas de lectura en Postgresql como primer paso para eliminar el modelo actual en Oracle, dejando únicamente las acciones de escritura en este motor.

En este post vamos a continuar el caso de uso con el objetivo de incluir acciones de escritura sobre Postgresql y dotar al sistema de una replicación bidireccional y un comportamiento activo-activo para:

A partir de ahí, podremos evolucionar totalmente cada modelo por separado.

Sistema activo-activo

Como se ha comentado anteriormente, el objetivo principal del post es conseguir un sistema de replicación bidireccional en el que ambas bases de datos estén sincronizadas en todo momento y, de esta forma, disponer de un sistema activo-activo. Para ello, se implementarán dos procesos similares pero con diferente sentido:

Cuando hablamos de replicación unidireccional en anteriores posts, la “fuente de la verdad” estaba en la base de datos Oracle. En este post, al poder realizar acciones de escritura en ambas fuentes, “la fuente de la verdad” podría ser cualquiera de ellas, dependiendo de la estrategia de aplicaciones que elijamos.

Diseñando el proceso de replicación

Al igual que hemos hecho en los anteriores posts, vamos a diseñar el proceso de replicación para que la implementación sea mucho más sencilla y tengamos todo en cuenta desde el inicio.

¿Qué “GoldenGates” necesitaremos?

Vamos a necesitar los mismos que usamos en el escenario de replicación unidireccional, es decir, Oracle GoldenGate for Oracle y Oracle GoldenGate for Postgresql.

La arquitectura queda de la siguiente manera:

Definiendo las etapas del proceso

Al ser una ampliación del caso unidireccional, tendremos las dos etapas de este caso y sumaremos la etapa de replicación de datos de Postgresql a Oracle:

Teniendo en cuenta estas etapas, vamos a definir los elementos que intervendrán en cada una de ellas para pasar posteriormente a su implementación:

ETAPA TIPO ELEMENTO UBICACIÓN FUNCIÓN NOMBRE IMPLE.
CARGA INICIAL EXTRACT GG Classic Extraer de Oracle el conjunto de datos de inicio a replicar einiload
CARGA INICIAL REPLICAT GG Postgresql Replica los cambios en Postgresql correspondientes a los datos extraídos riniload
CDC Oracle -> Postgresql EXTRACT GG Classic Extraer, de forma continua, los cambios realizados en Oracle y crear el trail local ecdcora
CDC Oracle -> Postgresql DATA PUMP GG Classic Procesar el trail local y generar el trail remoto para enviar al destino pcdcora
CDC Oracle -> Postgresql REPLICAT GG Postgresql Procesar el trail remoto (recibido desde GG Classic) y aplicar los cambios en Postgresql rcdcora
CDC Postgresql -> Oracle EXTRACT GG Postgresql Extraer, de forma continua, los cambios realizados en Postgresql y crear el trail local ecdcpsql
CDC Postgresql -> Oracle DATA PUMP GG Postgresql Procesar el trail local y generar el trail remoto para enviar al destino pcdpsql
CDC Postgresql -> Oracle REPLICAT GG Classic Procesar el trail remoto (recibido desde GG Postgresql) y aplicar los cambios en Oracle rcdpsql

La siguiente imagen muestra el proceso completo, identificando los diferentes elementos que intervienen en él:

Bucle de cambios de replicación

Una situación típica que se puede producir es la de generar un bucle de cambios con determinadas acciones de escritura:

Por ejemplo, si insertamos un dato en origen:

  1. Se produce un cambio en la base de datos de origen. El cambio es detectado y propagado al destino.
  2. En el destino, se aplica la inserción en la base de datos. Se considera esta acción como un nuevo cambio, propagándose de nuevo hacia el origen.
  3. Se intenta insertar de nuevo en origen.
  4. ...

Para gestionar esta situación, lo que vamos a hacer es que GoldenGate no tenga en cuenta los cambios efectuados en la base de datos por su propio usuario de base de datos, “oggadm1” en nuestro caso. Solo tendrá en cuenta los cambios de base de datos que se hayan realizado por usuarios diferentes a “oggadm1”, que serán los usuarios que utilicen las aplicaciones que se conectan a la base de datos.

Sincronizando las secuencias

Hasta ahora, en el escenario activo-pasivo, los datos siempre viajan desde Oracle a Postgresql, marcando Oracle el valor de las secuencias. Como en Postgresql no se iban a insertar datos, no era necesario mantener un sistema de secuencias en Postgresql para generar los IDs de los clientes.

En el escenario activo-activo sí vamos a realizar acciones de escritura en Postgresql y, por tanto, vamos a poder insertar nuevos clientes en esta fuente. Cuando hemos creado el modelo de datos de Postgresql, creamos una secuencia para cada esquema (particulares y empresas).

Este modelo no es adecuado para el caso de uso que estamos tratando (replicación bidireccional), ya que no están sincronizadas con las secuencia que genera el ID de cliente en Oracle.

Al no estar sincronizadas, se podrían producir colisiones de secuencias y errores en la replicación, ya que la secuencia podría generar un ID que ya existe en el otro lado.

Para solventar este problema podemos optar por varias estrategias:

Manos a la obra: implementando el proceso de replicación

Durante los siguientes puntos vamos a pasar a la práctica. Para que el post sea más legible, el detalle de cada paso lo encontraremos en el fichero Readme del repositorio asociado.

Creando la infraestructura base

Lo primero que tenemos que hacer es crear la infraestructura que soportará el caso de uso. Lo haremos sobre AWS, y está compuesta principalmente por:

El detalle de estos pasos lo encontraremos en el apartado del Readme correspondiente a la creación de la infraestructura.

Preparando las bases de datos para la replicación

Al igual que hemos hecho en los anteriores posts de la serie, tenemos que preparar las bases de datos, Oracle y Postgresql, para la replicación. Además, crearemos un usuario propio para GoldenGate (oggadm1) y le daremos los privilegios necesarios.

Este usuario, como veremos más adelante, cobra especial importancia en el caso de bidireccionalidad para evitar bucles de cambios.

Para ejecutar este paso, iremos al apartado “preparación de las bases de datos para la replicación” del fichero Readme.

Instalando Oracle GoldenGate

Una vez que tenemos las bases de datos preparadas y las máquinas virtuales EC2 listas, tenemos que instalar las dos versiones de Oracle GoldenGate: la correspondiente al lado origen (para Oracle) y la correspondiente al lado destino (para Postgresql).

Instalando Oracle GoldenGate Classic para Oracle

La instalación de GoldenGate para Oracle es similar a la realizada en el post relacionado con la replicación unidireccional.

El único punto a tener en cuenta es que ahora la comunicación va a ser bidireccional y, por tanto, debemos abrir los puertos para permitir la conexión desde la máquina EC2 que albergará GoldenGate para Postgresql.

Los pasos para instalar y configurar Oracle GoldenGate Classic para Oracle se encuentran en el apartado correspondiente a dicha tarea en el fichero Readme del repositorio.

Instalando Oracle GoldenGate for Postgresql

De forma similar al apartado anterior, para instalar y configurar Oracle GoldenGate Classic para Postgresql tenemos que seguir los pasos indicados en el apartado correspondiente del fichero Readme.

En este punto, ya tenemos instalados y configurados todos los elementos de la infraestructura necesarios para poder implementar un proceso de replicación:

Implementando el proceso de replicación bidireccional

Vamos a pasar a implementar el proceso de replicación que hemos diseñado. En el diseño, hemos establecido tres etapas:

  1. Carga inicial, que sincronizará los datos de Oracle en Postgresql.
  2. CDC de Oracle a Postgresql.
  3. CDC de Postgresql a Oracle.

Los puntos 1 y 2 nos va a permitir tener un sistema de replicación unidireccional, ya implementado anteriormente en el segundo post de la serie, y que permite replicar datos de Oracle a Postgresql de manera continua. La fuente de la verdad sería Oracle.

En el momento en que abordemos el punto 3, el flujo de datos pasa de ser de un sentido a ser bidireccional. Por lo tanto, dependiendo de la estrategia de aplicaciones, la fuente de la verdad podría ser tanto Oracle como Postgresql, ya que vamos a permitir escrituras en ambas.

Vamos a ver cómo implementar cada etapa:

Carga inicial

La etapa de carga inicial es idéntica a la implementada en el post de replicación unidireccional. Para realizar la implementación, tenemos que seguir las instrucciones detalladas en apartado asociado a la carga inicial del fichero Readme.

Una vez creados los elementos asociados a la carga inicial, estamos en el siguiente punto:

Proceso de CDC (Oracle a Postgresql)

Al igual que sucede con la carga inicial, el proceso de CDC de Oracle a Postgresql es similar al implementado en el post asociado a la replicación unidireccional. Para crear estos elementos, seguimos los pasos indicados en el apartado asociado al proceso de replicación del fichero Readme.

Finalizada esta implementación, tenemos el proceso de replicación unidireccional Oracle a Postgresql completo:

Probando el proceso de replicación de Oracle a Postgresql

Llegados a este punto, y antes de continuar con la replicación bidireccional, tenemos que lanzar la carga inicial y probar que el proceso de replicación en un sentido (Oracle a Postgresql) funciona correctamente y que, antes de iniciar la replicación bidireccional, tenemos ambas fuentes sincronizadas.

En este post no vamos a entrar en profundidad en las pruebas que ya hicimos. En este post, simplemente vamos a probar que la carga inicial propaga los datos a las tablas de Postgresql y que, realizando una modificación en Oracle, se propaga a Postgresql.

Para ello, seguimos los pasos marcados en el apartado de pruebas del proceso unidireccional del fichero readme.

Proceso de CDC (Postgresql a Oracle)

Como ya tenemos ambas fuentes sincronizadas, podemos pasar a implementar la replicación bidireccional, permitiendo escrituras en ambas fuentes.

Dentro de la implementación de este proceso se incluyen unas pequeñas modificaciones de los elementos ya realizados para evitar:

Sincronizando las secuencias en las fuentes

Como se ha comentado en el apartado de diseño, para evitar que las secuencias se solapen vamos a actuar tanto en origen (Oracle) como en destino (Postgresql) realizando una acción muy sencilla: en un lado, vamos a hacer que todos los valores devueltos por la secuencia que genera el ID de los clientes sean pares, y en el otro lado, que sean impares. De este modo nunca van a coincidir.

Para realizar estos cambios, sigue los pasos indicados en el siguiente apartado del fichero readme.

Evitando el bucle de replicación

Este es otro punto que debemos tener en cuenta en la replicación bidireccional. La solución también es sencilla: vamos a modificar el extract del lado origen, en GoldenGate Classic para Oracle, para decir que no tenga en cuenta los cambios que se hayan realizado con el usuario “oggadm1”.

Sigue los pasos mostrados en el fichero readme para realizar este cambio.

Implementando el proceso de replicación de Postgresql a Oracle

Llegados a este punto ya podemos abordar el proceso de replicación en sentido Postgresql a Oracle, dotando al sistema de una replicación bidireccional. La implementación es sencilla, similar a la que hemos realizado para el sentido inicial.

Puedes encontrar los detalles para abordar la implementación en el correspondiente apartado del fichero readme.

Una vez hecho esto, ya tenemos el proceso completo:

Probando el proceso de replicación bidireccional

Ya tenemos todo implementado y solo nos falta probar que la información viaja en ambos sentidos. Para ello vamos a realizar acciones de escritura en los dos lados del sistema, Oracle y Postgresql:

Para realizar estas pruebas sigue las instrucciones indicadas en el fichero readme.

Destruyendo la infraestructura

Una vez terminado el caso de uso, podemos proceder a la destrucción de la infraestructura que hemos creado en AWS. Para ello, realizamos los pasos explicados en el apartado correspondiente a la destrucción del entorno del fichero readme.

Conclusión

En este post hemos visto cómo se puede usar Oracle GoldenGate para replicar datos de manera bidireccional, manteniendo dos fuentes totalmente sincronizadas y tratando dos problemas comunes como son la sincronización de secuencias y los bucles de replicación.

Además, hemos visto dos modelos de sincronización diferentes:

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.

Suscríbete

Estamos comprometidos.

Tecnología, personas e impacto positivo.