Detección y resolución manual de conflictos

Obtenga información sobre la configuración manual de la detección y resolución de conflictos (CDR) mediante parámetros específicos. La detección y resolución de conflictos son necesarias en las configuraciones activo-activo, donde Oracle GoldenGate debe mantener la sincronización de datos entre varias bases de datos que contienen los mismos juegos de datos.

Visión General de la Función CDR de Oracle GoldenGate

La detección y resolución de conflictos (CDR) de Oracle GoldenGate tiene dos partes: Detección de conflictos y Resolución de conflictos. Antes de comenzar con la resolución de conflictos, es importante investigar y completar la detección de conflictos.

Oracle GoldenGate Conflict Detection and Resolution (CDR) proporciona rutinas básicas de resolución de conflictos que:

Para utilizar la detección y resolución de conflictos (CDR), la base de datos de destino debe residir en un sistema Windows, Linux o UNIX. No está soportado para bases de datos en la plataforma NonStop.

CDR soporta tipos de datos escalares como:

Esto significa que estos tipos de columna se pueden utilizar con el parámetro COMPARECOLS y como columna de resolución en las opciones USEMIN y USEMAX del parámetro RESOLVECONFLICT. Solo se pueden utilizar columnas NUMERIC para la opción USEDELTA de RESOLVECONFLICT. Para USEMAX, USEMIN, solo están soportados TIMESTAMP y NUMBER.

La resolución de conflictos no se realiza cuando Replicat funciona en modo BATCHSQL. Si se produce un conflicto en el modo BATCHSQL, Replicat vuelve al modo GROUPTRANSOPS y, a continuación, al modo de transacción única. La detección de conflictos se produce en los tres modos.

Configuración de los archivos de parámetros de Oracle GoldenGate para la resolución de conflictos

Se necesitan los siguientes parámetros para admitir la detección y resolución de conflictos.

  1. Utilice la opción COMPARECOLS del parámetro MAP del archivo de parámetros de Replicat para especificar las columnas que se van a utilizar con los valores anteriores en la cláusula WHERE de Replicat. Los valores anteriores se comparan con los valores actuales de la base de datos destino para detectar conflictos de actualización y supresión. (Por defecto, Replicat solo utiliza la clave primaria en la cláusula WHERE; puede que no sea suficiente para la detección de conflictos).

  2. Utilice la opción RESOLVECONFLICT del parámetro MAP para especificar rutinas de resolución de conflictos para diferentes operaciones y tipos de conflictos. Puede utilizar RESOLVECONFLICT varias veces en una sentencia MAP para especificar diferentes resoluciones para diferentes tipos de conflicto. Sin embargo, no puede utilizar RESOLVECONFLICT varias veces para el mismo tipo de conflicto. Utilizar procedimientos de resolución de conflictos idénticos en todas las bases de datos, de modo que el mismo conflicto produzca el mismo resultado final. Un método de resolución de conflictos podría no funcionar para cada conflicto que pudiera ocurrir. Es posible que necesite crear varias rutinas que se puedan llamar en un orden lógico de prioridad para minimizar el riesgo de fallo.

Nota: Se debe tener en cuenta más cuando una tabla tiene una clave primaria y índices únicos adicionales o claves únicas. Las rutinas automatizadas proporcionadas con los parámetros COMPARECOLS y RESOLVECONFLICT requieren una forma coherente de identificar de forma única cada fila. Si no se identifica de forma coherente una fila, se producirá un error durante la resolución de conflictos. En estas situaciones, las claves únicas adicionales se deben desactivar o puede utilizar la función SQLEXEC para manejar el error devuelto y resolver el conflicto.

Para obtener información detallada sobre estos parámetros, consulte Referencia de parámetros y funciones para Oracle GoldenGate. Consulte los ejemplos que comienzan en el Ejemplo 1 de CDR: Todos los tipos de conflicto con USEMAX, OVERWRITE, DISCARD para obtener más información sobre estos parámetros.

Disponibilidad de los valores de columna necesarios para extraer

Para utilizar CDR, se deben registrar los siguientes valores de columna para que Extract pueda escribirlos en la pista.

Para obtener información detallada sobre estos parámetros y comandos, consulte la Referencia de parámetros y funciones para Oracle GoldenGate. Consulte los ejemplos que comienzan en el Ejemplo 1 de CDR: Todos los tipos de conflicto con USEMAX, OVERWRITE, DISCARD para obtener más información sobre cómo funcionan estos parámetros con CDR.

Visualización de estadísticas de CDR

La función CDR proporciona los siguientes métodos para ver los resultados de la resolución de conflictos.

Aquí hay diferentes técnicas que puede utilizar para ver las estadísticas de CDR.

Archivo de Informe

Replicat escribe estadísticas de CDR en el archivo de informe:

Total CDR conflicts        7
    CDR resolutions succeeded       6
    CDR resolutions failed          1
    CDR INSERTROWEXISTS conflicts   1
    CDR UPDATEROWEXISTS conflicts   4
    CDR UPDATEROWMISSING conflicts
    CDR DELETEROWEXISTS conflicts      1
    CDR DELETEROWMISSING conflicts     1

Línea de Comandos

Puede ver las estadísticas de CDR desde la línea de comandos mediante el comando STATS REPLICAT con la opción REPORTCDR:

STATS REPLICAT *group*, REPORTCDR

Funciones de conversión de columnas

Las siguientes estadísticas de CDR se pueden recuperar y asignar a una tabla de excepciones o se pueden utilizar en otros parámetros de Oracle GoldenGate que aceptan la entrada de las funciones de conversión de columna, según corresponda.

Para recuperar estas estadísticas, utilice la función de conversión de columna @GETENV con el tipo de información STATS o DELTASTATS. Los resultados se basan en la sesión actual de Replicat. Si Replicat se detiene y se reinicia, restablece las estadísticas.

Puede devolver estas estadísticas para una tabla o un juego de tablas comodín específicos:

@GETENV ('STATS','TABLE','SCHEMA.TABLNAME','CDR_CONFLICTS')
@GETENV ('STATS','TABLE','SCHEMA.TABLNAME','CDR_RESOLUTIONS_SUCCEEDED')
@GETENV ('STATS','TABLE','SCHEMA.TABLNAME','CDR_RESOLUTIONS_FAILED')

Puede devolver estas estadísticas para todas las tablas de todas las sentencias MAP del archivo de parámetros Replicat:

@GETENV ('STATS','CDR_CONFLICTS')
@GETENV ('STATS','CDR_RESOLUTIONS_SUCCEEDED')
@GETENV ('STATS','CDR_RESOLUTIONS_FAILED')

El tipo de información 'STATS' de los ejemplos anteriores se puede sustituir por 'DELTASTATS' para devolver los recuentos solicitados desde la última ejecución de 'DELTASTATS'. Para obtener más información sobre @GETENV, consulte @GETENV.

Ejemplo 1 de CDR: Todos los tipos de conflicto con USEMAX, OVERWRITE, DISCARD

Este ejemplo resuelve todos los tipos de conflicto mediante las resoluciones USEMAX, OVERWRITE y DISCARD.

Tabla utilizada en este ejemplo

En los ejemplos se presuponen bases de datos Oracle idénticas.

CREATE TABLE hr.emp_tgt(
    name varchar2(30) primary key,
    phone varchar2(10),
    address varchar2(100),
    salary number,
    balance number,
    comment varchar2(100),
    last_mod_time timestamp);

En la base de datos origen, todas las columnas se registran de forma adicional:

ADD TRANDATA hr.emp_src, COLS (name, phone, address, salary, balance, comment, last_mod_time);

Sentencia MAP con especificaciones de resolución de conflictos

MAP fin.src, TARGET fin.tgt,
    COMPARECOLS (ON UPDATE ALL, ON DELETE ALL),
    RESOLVECONFLICT (UPDATEROWEXISTS, (DEFAULT, USEMAX (last_mod_time)),
    RESOLVECONFLICT (INSERTROWEXISTS, (DEFAULT, USEMAX (last_mod_time)),
    RESOLVECONFLICT (DELETEROWEXISTS, (DEFAULT, OVERWRITE)),
    RESOLVECONFLICT (UPDATEROWMISSING, (DEFAULT, OVERWRITE)),
    RESOLVECONFLICT (DELETEROWMISSING, (DEFAULT, DISCARD)),
    );

Descripción de la sentencia MAP

A continuación, se describe la sentencia MAP:

INSERTROWEXISTS con la Resolución USEMAX

Para este ejemplo, la resolución USEMAX se ilustra con las imágenes antes y después aplicables para el registro en la pista y en la base de datos. Muestra cómo resolver una inserción en la que existe la fila en el origen y el destino, pero algunos o todos los valores de fila son diferentes.

Tabla 10 INSERTROWEXISTS Conflicto con la Resolución USEMAX

Imagen SQL Comentarios
Antes de la imagen en pista
None (row was inserted on the source).
No disponible
Después de la imagen en pista
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=100 comment=NULL last_mod_time='9/1/10 3:00'

last_mod_time='9/1/10 3:00 es la imagen posterior de la columna de resolución. Dado que hay una imagen posterior, se utilizará para determinar la resolución.

Imagen de base de datos de destino
name='Mary' phone='111111' address='Ralston' salary=200 balance=500 comment='aaa' last_mod_time='9/1/10 1:00'
last_mod_time='9/1/10 1:00 es la imagen actual de la columna de resolución en el destino con la que se compara el valor de la columna de resolución en la pista.
INSERT inicial aplicado por Replicat que detecta el conflicto

Variables de enlace SQL:

1)'Mary' 2)'1234567890' 3)'Oracle Pkwy' 4)100 5)100 6)NULL 7)'9/1/10 3:00'
Este SQL devuelve un conflicto de unicidad en 'Mary'.
UPDATE aplicado por Replicat para resolver el conflicto

Variables de enlace SQL:

1)'1234567890' 2)'Oracle Pkwy' 3)100 4)100 5)NULL 6)'9/1/10 3:00' 7)'Mary' 8)'9/1/10 3:00'
Puesto que se ha especificado USEMAX para INSERTROWEXISTS, Replicat convierte la inserción en una actualización y compara el valor de last_mod_time en el registro de pista con el valor de la base de datos. El valor del registro es mayor, por lo que las imágenes posteriores de las columnas del archivo de pista se aplican al destino.

ACTUALIZADORES con la Resolución USEMAX

Para este ejemplo, la resolución USEMAX se ilustra con las imágenes antes y después aplicables para el registro en la pista y en la base de datos. Muestra cómo resolver una actualización en la que la fila existe en el origen y el destino, pero algunos o todos los valores de fila son diferentes.

Tabla 11 Conflicto UPDATEROWEXISTS con la Resolución USEMAX

Imagen SQL Comentarios
Antes de la imagen en pista
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=100 comment=NULL last_mod_time='9/1/10 3:00'
last_mod_time='9/1/10 3:00 es la imagen anterior de la columna de resolución.
Después de la imagen en pista
phone='222222' address='Holly' last_mod_time='9/1/10 5:00'
last_mod_time='9/1/10 5:00 es la imagen posterior de la columna de resolución. Dado que hay una imagen posterior, se utilizará para determinar la resolución.
Imagen de base de datos de destino
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=600 comment='com' last_mod_time='9/1/10 6:00'
last_mod_time='9/1/10 6:00 es la imagen actual de la columna de resolución en el destino con la que se compara el valor de la columna de resolución en la pista.
UPDATE inicial aplicado por Replicat que detecta el conflicto

Variables de enlace SQL:

1)'222222' 2)'Holly' 3)'9/1/10 5:00' 4)'Mary' 5)'1234567890' 6)'Oracle Pkwy' 7)100 8)100 9)NULL 10)'9/1/10 3:00'

Este SQL devuelve un error sin datos porque los valores de balance, comment y last_mod_time son diferentes en el destino.

Todas las columnas se utilizan en la cláusula WHERE porque la sentencia COMPARECOLS está definida en ALL.

UPDATE aplicado por Replicat para resolver el conflicto

Variables de enlace SQL:

1)'Mary' 2)'222222' 3)'Holly' 4)100 5)100 6)NULL 7)'9/1/10 5:00' 8)'Mary' 9)'9/1/10 5:00'
Puesto que el valor posterior de last_mod_time en el registro de pista es menor que el valor actual en la base de datos, se retiene el valor de la base de datos. Replicat aplica la operación con una cláusula WHERE que contiene la clave primaria más un valor last_mod_time definido en menos de 9/1/10 5:00. Ninguna fila coincide con este criterio, por lo que la sentencia falla con un error de "datos no encontrados", pero Replicat ignora el error porque se espera que falle una resolución USEMAX si no se cumple la condición.

ACTUALIZACIÓN con resolución OVERWRITE

Para este ejemplo, la resolución OVERWRITE se ilustra con las imágenes antes y después aplicables para el registro en la pista y en la base de datos. Muestra cómo resolver el caso en el que falta la fila de destino. La resolución lógica, y la que se utiliza, es sobrescribir la fila en el destino para que ambas bases de datos vuelvan a estar sincronizadas.

Tabla 12 ACTUALIZACIÓN Conflicto con resolución OVERWRITE

Imagen SQL Comentarios
Antes de la imagen en pista
name='Jane' phone='333' address='Oracle Pkwy' salary=200 balance=200 comment=NULL last_mod_time='9/1/10 7:00'
No disponible
Después de la imagen en pista
phone='4444' address='Holly' last_mod_time='9/1/10 8:00'
 
Imagen de base de datos de destino
None (row for Jane is missing)
 
UPDATE inicial aplicado por Replicat que detecta el conflicto

Variables de enlace SQL:

1)'4444' 2)'Holly' 3)'9/1/10 8:00' 4)'Jane' 5)'333' 6)'Oracle Pkwy' 7)200 8)200 9)NULL 10)'9/1/10 7:00'
Este SQL devuelve un error sin datos. Todas las columnas se utilizan en la cláusula WHERE porque la sentencia COMPARECOLS está definida en ALL.
INSERT aplicado por Replicat para resolver el conflicto

Variables de enlace SQL:

1)'Jane' 2)'4444' 3)'Holly' 4)200 5)200 6)NULL 7)'9/1/10 8:00'
La actualización se convierte en una inserción porque OVERWRITE es la resolución. Si está disponible, se utiliza la imagen posterior de una columna; de lo contrario, se utiliza la imagen anterior.

DELETEROWEXISTS con resolución OVERWRITE

Para este ejemplo, la resolución OVERWRITE se ilustra con las imágenes antes y después aplicables para el registro en la pista y en la base de datos. Muestra cómo resolver el caso en el que se suprimió la fila de origen pero existe la fila de destino. En este caso, la resolución OVERWRITE aplica la supresión al destino.

Tabla 13 DELETEROWEXISTS Conflicto con la resolución OVERWRITE

Imagen SQL Comentarios
Antes de la imagen en pista
name='Mary' phone='222222' address='Holly' salary=100 balance=100 comment=NULL last_mod_time='9/1/10 5:00'
No disponible
Después de la imagen en pista
None
No disponible
Imagen de base de datos de destino
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=600 comment=com last_mod_time='9/1/10 7:00'
La fila existe en el destino, pero las columnas phone, address, balance, comment y last_mod_time son diferentes de la imagen anterior en la pista.
DELETE inicial aplicado por Replicat que detecta el conflicto

Variables de enlace SQL:

1)'Mary' 2)'222222' 3)'Holly' 4)100 5)100d 6)NULL 7)'9/1/10 5:00'

Todas las columnas se utilizan en la cláusula WHERE porque la sentencia COMPARECOLS está definida en ALL.

Se produce un error sin datos debido a la diferencia entre los valores anterior y actual.

DELETE aplicado por Replicat para resolver el conflicto

Variables de enlace SQL:

1)'Mary'
Debido a que OVERWRITE es la resolución. DELETE se aplica solo mediante la clave primaria (para evitar un error de integridad).

DELETEROWMISS con resolución DISCARD

Para este ejemplo, la resolución DISCARD se ilustra con las imágenes antes y después aplicables para el registro en la pista y en la base de datos. Muestra cómo resolver el caso en el que falta la fila de destino. En el caso de una supresión en el origen, es aceptable que la fila de destino no exista (de todas formas, tendría que suprimirse), por lo que la resolución es desechar la operación DELETE que está en la pista.

Tabla 14 DELETEROWMSING Conflicto con la Resolución DISCARD

Imagen SQL Comentarios
Antes de la imagen en pista
name='Jane' phone='4444' address='Holly' salary=200 balance=200 comment=NULL last_mod_time='9/1/10 8:00'
No disponible
Después de la imagen en pista
None
No disponible
Imagen de base de datos de destino
None (row missing)
No disponible
DELETE inicial aplicado por Replicat que detecta el conflicto

Variables de enlace SQL:

1)'Jane' 2)'4444' 3)'Holly' 4)200 5)200 6)NULL 7)'9/1/10 8:00'
Este SQL devuelve un error sin datos. Todas las columnas se utilizan en la cláusula WHERE porque la sentencia COMPARECOLS está definida en ALL.
SQL aplicado por Replicat para resolver el conflicto
None
Debido a que DISCARD se especifica como resolución para DELETEROWMISSING, la supresión de la pista pasa al archivo de desecho.

Ejemplo 2 de CDR: UPDATEROWEXISTS con USEDELTA y USEMAX

Este ejemplo resuelve la condición en la que existe una fila de destino en UPDATE pero las columnas no de clave son diferentes y utiliza dos tipos de resolución diferentes para manejar esta condición en función de la columna afectada.

Tabla utilizada en este ejemplo

En los ejemplos se presuponen bases de datos Oracle idénticas.

CREATE TABLE tgt(
    name varchar2(30) primary key,
    phone varchar2(10),
    address varchar2(100),
    salary number,
    balance number,
    comment varchar2(100),
    last_mod_time timestamp);

En la base de datos origen, todas las columnas se registran de forma adicional:

ADD TRANDATA scott.src, COLS (name, phone, address, salary, balance, comment, last_mod_time);

Sentencia MAP

MAP fin.src, TARGET fin.tgt,
    COMPARECOLS
    (ON UPDATE KEYINCLUDING (address, phone, salary, last_mod_time),
    ON DELETE KEYINCLUDING (address, phone, salary, last_mod_time)),
    RESOLVECONFLICT (
    UPDATEROWEXISTS,
    (delta_res_method, USEDELTA, COLS (salary)),
    (DEFAULT, USEMAX (last_mod_time)));

Descripción de la sentencia MAP

Para un conflicto UPDATEROWEXISTS, en el que exista una fila de destino en UPDATE pero las columnas no de clave sean diferentes, utilice dos resoluciones diferentes en función de la columna:

Por COMPARECOLS, utilice la clave primaria (columna name ) más las columnas address, phone, salary y last_mod_time como columnas de comparación para la detección de conflictos para las operaciones UPDATE y DELETE. (Las columnas balance y comment no se comparan).

Nota: Como alternativa a USEMAX, puede utilizar la resolución USEMAXEQ para aplicar una condición >=. Para obtener más información, consulte Referencia de parámetros y funciones para Oracle GoldenGate.

Manejo de Errores

Para obtener un ejemplo del manejo de errores en una tabla de excepciones, consulte Configuración de los Archivos de Parámetros de Oracle GoldenGate para el Manejo de Errores.

Tabla 15 UPDATEROWEXISTS con USEDELTA y USEMAX

Imagen SQL Comentarios
Antes de la imagen en pista
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=100 comment=NULL last_mod_time='9/1/10 3:00'

last_mod_time='9/1/10 3:00 es la imagen anterior de la columna de resolución para la resolución USEMAX.

salary=100 es la imagen anterior para la resolución USEDELTA.

Después de la imagen en pista
phone='222222' address='Holly' salary=200 comment='new' last_mod_time='9/1/10 5:00'
last_mod_time='9/1/10 5:00 es la imagen posterior de la columna de resolución para USEMAX. Dado que hay una imagen posterior, se utilizará para determinar la resolución.
Imagen de base de datos de destino
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=600 balance=600 comment='com' last_mod_time='9/1/10 4:00'

last_mod_time='9/1/10 4:00 es la imagen actual de la columna de resolución en el destino con la que se compara el valor de la columna de resolución en la pista.

salary=600 es la imagen actual de la columna de destino para la resolución USEDELTA.

UPDATE inicial aplicado por Replicat que detecta el conflicto

Variables de enlace SQL:

1)'222222' 2)'Holly' 3)200 4)'new' 5)'9/1/10 5:00' 6)'Mary' 7)'1234567890' 8)'Oracle Pkwy' 9)100 10)'9/1/10 3:00'
Este SQL devuelve un error sin datos porque los valores de salary y last_mod_time son diferentes. (Los valores de comment y balance también son diferentes, pero estas columnas no se comparan).
UPDATE aplicado por Replicat para resolver el conflicto para salary, mediante USEDELTA.

Variables de enlace SQL:

1)200 2)100 3)'Mary'

Por USEDELTA, la diferencia entre la imagen posterior de salary (200) en la pista y la imagen anterior de salary (100) en la pista se agrega al valor actual de salary en el destino (600). El resultado es 700.

600 + (200 - 100) = 700
UPDATE aplicado por Replicat para resolver el conflicto para las columnas por defecto, mediante USEMAX.

Variables de enlace SQL:

1)'222222' 2)'Holly' 3)'new' 4)'9/1/10 5:00' 5)'Mary' 6)'9/1/10 5:00'

Por USEMAX, debido a que el valor posterior de last_mod_time en el registro de pista es mayor que el valor actual en la base de datos, la fila se actualiza con los valores posteriores del registro de pista.

Tenga en cuenta que la columna salary no está definida aquí, porque se resuelve con UPDATE desde la resolución USEDELTA.

Ejemplo 3 de CDR: UPDATEROWEXISTS con USEDELTA, USEMAX e IGNORE

Este ejemplo resuelve el conflicto en el que existe una fila de destino en UPDATE pero las columnas no de clave son diferentes y utiliza tres tipos de resolución diferentes para manejar esta condición basada en la columna afectada.

Tabla utilizada en este ejemplo

En los ejemplos se presuponen bases de datos Oracle idénticas.

CREATE TABLE tgt(
    name varchar2(30) primary key,
    phone varchar2(10),
    address varchar2(100),
    salary number,
    balance number,
    comment varchar2(100),
    last_mod_time timestamp);

En la base de datos origen, todas las columnas se registran de forma adicional:

ADD TRANDATA scott.src, COLS (name, phone, address, salary, balance, comment, last_mod_time);

Sentencia MAP

MAP fin.src, TARGET fin.tgt,
    COMPARECOLS
    (ON UPDATE ALLEXCLUDING (comment)),
    RESOLVECONFLICT (
    UPDATEROWEXISTS,
    (delta_res_method, USEDELTA, COLS (salary, balance)),
    (max_res_method, USEMAX (last_mod_time), COLS (address, last_mod_time)),
    (DEFAULT, IGNORE));

Descripción de la sentencia MAP

Manejo de Errores

Para obtener un ejemplo del manejo de errores en una tabla de excepciones, consulte Configuración de los Archivos de Parámetros de Oracle GoldenGate para el Manejo de Errores.

Tabla 16 UPDATEROWEXISTS con USEDELTA, USEMAX e IGNORE

Imagen SQL Comentarios
Antes de la imagen en pista
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=100 comment=NULL last_mod_time='9/1/10 3:00

last_mod_time='9/1/10 3:00 es la imagen anterior de la columna de resolución para la resolución USEMAX.

salary=100 y balance=100 son las imágenes anteriores para la resolución USEDELTA.

Después de la imagen en pista
phone='222222' address='Holly' salary=200 comment='new' last_mod_time='9/1/10 5:00'

last_mod_time='9/1/10 5:00 es la imagen posterior de la columna de resolución para USEMAX. Dado que hay una imagen posterior, se utilizará para determinar la resolución.

salary=200 es la única imagen posterior disponible para la resolución USEDELTA. Para balance, la imagen anterior se utilizará en el cálculo.

Imagen de base de datos de destino
name='Mary' phone='1234567890' address='Ralston' salary=600 balance=600 comment='com' last_mod_time='9/1/10 4:00'

last_mod_time='9/1/10 4:00 es la imagen actual de la columna de resolución en el destino con la que se compara el valor de la columna de resolución en la pista para USEMAX.

salary=600 y balance=600 son las imágenes actuales de las columnas de destino para USEDELTA.

UPDATE inicial aplicado por Replicat que detecta el conflicto

Variables de enlace SQL:

1)'222222' 2)'Holly' 3)200 4)'new' 5)'9/1/10 5:00' 6)'Mary' 7)'1234567890' 8)'Oracle Pkwy' 9)100 10)100 11)'9/1/10 3:00'
Este SQL devuelve un error sin datos porque los valores de las columnas address, salary, balance y last_mod_time son diferentes.
UPDATE aplicado por Replicat para resolver el conflicto para salary, mediante USEDELTA.

Variables de enlace SQL:

1)200 2)100 3)'Mary'
Para salary, hay una diferencia de 100, pero no se ha producido ningún cambio en el valor de balance, por lo que no es necesario en el SQL de actualización. Por USEDELTA, la diferencia (delta) entre la imagen después de (200) y la imagen anterior (100) de salary en la pista se agrega al valor actual de salary en el destino (600). El resultado es 700.
UPDATE aplicado por Replicat para resolver el conflicto para USEMAX.

Variables de enlace SQL:

1)'Holly' 2)'9/1/10 5:00' 3)'Mary' 4)'9/1/10 5:00'

Puesto que el valor posterior de last_mod_time en el registro de pista es mayor que el valor actual en la base de datos, esa columna más la columna address se actualizan con los valores posteriores del registro de pista.

Tenga en cuenta que la columna salary no está definida aquí, porque se resuelve con UPDATE desde la resolución USEDELTA.

UPDATE aplicado por Replicat para IGNORE.

Variables de enlace SQL:

1)'222222' 2)'new' 3)'Mary'
Se ha especificado IGNORE para el grupo de columnas DEFAULT (phone y comment), por lo que no se aplica ningún SQL de resolución.

Configuración de los archivos de parámetros de Oracle GoldenGate para el manejo de errores

La CDR manual se debe utilizar junto con el manejo de errores para capturar los errores que se resolvieron y los errores que CDR no pudo resolver.

  1. La resolución de conflictos se realiza antes que estos otros parámetros de manejo de errores: HANDLECOLLSIONS, INSERTMISSINGUPDATES y REPERROR. Utilice el parámetro REPERROR para asignar reglas para gestionar errores que no se pueden resolver mediante CDR o para errores que no desea gestionar mediante CDR. Puede ser apropiado que REPERROR maneje algunos errores y que CDR maneje otros; sin embargo, si REPERROR y CDR están configurados para manejar el mismo conflicto, CDR tiene prioridad. Los parámetros INSERTMISSINGUPDATES y HANDLECOLLISIONS también se pueden utilizar para manejar algunos errores que no maneja CDR. Consulte la Referencia de parámetros y funciones para Oracle GoldenGate para obtener más información sobre estos parámetros.

  2. (Opcional) Creación de una tabla de excepciones. Cuando se utiliza una tabla de excepciones con una sentencia MAP de excepciones, Replicat envía todas las operaciones que generan un conflicto (resuelto o no) a la sentencia MAP de excepciones que se va a asignar a la tabla de excepciones. Omita una clave primaria en esta tabla si Replicat va a procesar conflictos UPDATE y DELETE; de lo contrario, puede haber errores de restricción de integridad.

    Como mínimo, una tabla de excepciones debe contener las mismas columnas que la tabla de destino. Estas filas contendrán cada imagen de fila que Replicat haya aplicado al destino (o que haya intentado aplicar).

    Además, puede definir columnas adicionales para capturar otra información que ayude a colocar los datos en el contexto transaccional. Oracle GoldenGate proporciona herramientas para capturar esta información mediante la sentencia MAP de excepciones. Estas columnas pueden ser, entre otras, las siguientes:

    • Imagen anterior del registro de pista. Este es un juego duplicado de las columnas de destino con nombres como col1_before, col2_before, etc.

    • Valores actuales de las columnas de destino. Este también es un juego duplicado de las columnas de destino con nombres como col1_current, col2_current, etc.

    • Nombre de la tabla de destino

    • Registro de hora del conflicto

    • El tipo de operación

    • Número de error de la base de datos

    • (Opcional) Mensaje de error de la base de datos

    • Si el conflicto se resolvió o no

  3. Cree una sentencia MAP de excepciones para asignar los datos de excepciones a la tabla de excepciones. Una sentencia MAP de excepciones contiene:

    • (Necesario) La opción INSERTALLRECORDS. Este parámetro convierte todas las operaciones asignadas a INSERT para que todos los valores de columna se asignen a la tabla de excepciones.

    • (Necesario) La opción EXCEPTIONSONLY. Este parámetro hace que Replicat asigne operaciones que generan un error, pero no las que se han realizado correctamente.

    • (Opcional) Una cláusula COLMAP. Si los nombres y las definiciones de las columnas de la tabla de excepciones son idénticos a los de la tabla de origen y la tabla de excepciones solo contiene esas columnas, no se necesita COLMAP. Sin embargo, si hay nombres o definiciones diferentes, o si hay columnas adicionales en la tabla de excepciones que desea rellenar con datos adicionales, utilice una cláusula COLMAP para asignar todas las columnas.

Herramientas para asignar datos adicionales a la tabla de excepciones

A continuación se muestran algunas herramientas que puede utilizar en la cláusula COLMAP para rellenar columnas adicionales:

Consulte Asignación de excepciones de ejemplo con columnas adicionales en la tabla de excepciones para obtener información sobre cómo combinar estas funciones en una cláusula COLMAP en la sentencia de excepciones MAP para rellenar una tabla de excepciones detallada.

Consulte Referencia de parámetros y funciones para Oracle GoldenGate para obtener información sobre el uso y la sintaxis de los parámetros y las funciones de conversión de columnas que se muestran en estos ejemplos.

Asignación de excepciones de ejemplo solo con columnas de origen y destino

A continuación se muestra un archivo de parámetros de ejemplo que muestra el manejo de errores y la asignación de excepciones simples para las tablas de origen y destino que se utilizan en los ejemplos de CDR que comienzan. Este ejemplo asigna columnas de origen y destino, pero no columnas adicionales. Por los siguientes motivos, no se necesita una cláusula COLMAP en la sentencia MAP de excepciones de este ejemplo:

    -- REPERROR error handling: DEFAULT represents all error types. DISCARD

    -- writes operations that could not be processed to a discard file.
REPERROR (DEFAULT, DISCARD)

    -- Specifies a discard file.
DISCARDFILE /users/ogg/discards/discards.dsc, PURGE

    -- The regular MAP statement with the CDR parameters
MAP fin.src, TARGET fin.tgt, &
COMPARECOLS (ON UPDATE ALL, ON DELETE ALL), &
RESOLVECONFLICT (UPDATEROWEXISTS, (DEFAULT, USEMAX (last_mod_time)), &
RESOLVECONFLICT (INSERTROWEXISTS, (DEFAULT, USEMAX (last_mod_time)), &
RESOLVECONFLICT (DELETEROWEXISTS, (DEFAULT, OVERWRITE)), &
RESOLVECONFLICT (UPDATEROWMISSING, (DEFAULT, OVERWRITE)), &
RESOLVECONFLICT (DELETEROWMISSING, (DEFAULT, DISCARD)), &
);

    -- Starts the exceptions MAP statement by mapping the source table to the

    -- exceptions table.
MAP fin.src, TARGET fin.exception, &

    -- directs Replicat only to map operations that caused the error specified

    -- in REPERROR.
EXCEPTIONSONLY, &

    -- directs Replicat to convert all the exceptions to inserts into the

    -- exceptions table. This is why there cannot be a primary key constraint

    -- on the exceptions table.
INSERTALLRECORDS
;

Asignación de excepciones de ejemplo con columnas adicionales en la tabla de excepciones

A continuación se muestra un archivo de parámetros de ejemplo que muestra el manejo de errores y la asignación de excepciones complejas para las tablas de origen y destino que se utilizan en los ejemplos de CDR que comienzan. En este ejemplo, la tabla de excepciones tiene las mismas filas que la tabla de origen, pero también tiene columnas adicionales para capturar datos de contexto.

Nota: en este ejemplo se excluyen intencionadamente otros parámetros que son necesarios en un archivo de parámetros de Replicat, como el nombre de proceso y las credenciales de conexión, así como cualquier parámetro opcional que pueda ser necesario para un tipo de base de datos determinado. Cuando utilice saltos de línea para dividir una sentencia de parámetro en varias líneas, utilice un ampersand (&) al final de cada línea.

    -- REPERROR error handling: DEFAULT represents all error types. DISCARD
    -- writes operations that could not be processed to a discard file.
REPERROR (DEFAULT, DISCARD)
    -- Specifies the discard file.
DISCARDFILE /users/ogg/discards/discards.dsc, PURGE
    -- The regular MAP statement with the CDR parameters
MAP fin.src, TARGET fin.tgt, &
COMPARECOLS (ON UPDATE ALL, ON DELETE ALL), &
RESOLVECONFLICT (UPDATEROWEXISTS, (DEFAULT, USEMAX (last_mod_time))), &
RESOLVECONFLICT (INSERTROWEXISTS, (DEFAULT, USEMAX (last_mod_time)), &
RESOLVECONFLICT (DELETEROWEXISTS, (DEFAULT, OVERWRITE)), &
RESOLVECONFLICT (UPDATEROWMISSING, (DEFAULT, OVERWRITE)), &
RESOLVECONFLICT (DELETEROWMISSING, (DEFAULT, DISCARD))
);
    -- Starts the exceptions MAP statement by mapping the source table to the -- exceptions table.
MAP fin.src, TARGET fin.exception, &
    -- directs Replicat only to map operations that caused the error specified
    -- in REPERROR.
EXCEPTIONSONLY, &
    -- directs Replicat to convert all the exceptions to inserts into the
    -- exceptions table. This is why there cannot be a primary key constraint
    -- on the exceptions table.
INSERTALLRECORDS &
    -- SQLEXEC query to select the values from the target record before the
    -- Replicat statement is applied. These are mapped to the *_target
    -- columns later.
SQLEXEC (id qry, query 'select name, phone, address, salary, balance, & comment, last_mod_time from fin.tgt where name = :p1', PARAMS(p1 = name )), &
    -- Start of the column mapping, specifies use default column definitions.
COLMAP ( &
    -- USEDEFAULTS maps the source columns to the target exceptions columns
    -- that receive the after image that Replicat applied or tried to apply.
    -- In this case, USEDEFAULTS can be used because the names and definitions
    -- of the source and target exceptions columns are identical; otherwise
    -- the columns must be mapped explicitly in the COLMAP clause.
USEDEFAULTS, &
    -- captures the timestamp when the resolution was performed.
res_date = @DATENOW (), &
    -- captures and maps the DML operation type.
optype = @GETENV ('LASTERR', 'OPTYPE'), &
    -- captures and maps the database error number that was returned.
dberrnum = @GETENV ('LASTERR', 'DBERRNUM'), &
    -- captures and maps the database error that was returned.
dberrmsge = @GETENV ('LASTERR', 'DBERRMSG'), &
    -- captures and maps the name of the target table
tabname = @GETENV ('GGHEADER', 'TABLENAME'), &
    -- If the names and definitions of the source columns and the target
    -- exceptions columns were not identical, the columns would need to
    -- be mapped in the COLMAP clause instead of using USEDEFAULTS, as
    -- follows:
       -- name_after = name, &
       -- phone_after = phone, &
       -- address_after = address, &
       -- salary_after = salary, &
       -- balance_after = balance, &
       -- comment_after = comment, &
       -- last_mod_time_after = last_mod_time &
    -- maps the before image of each column from the trail to a column in the
    -- exceptions table.
name_before = @BEFORE (name), &
phone_before = @BEFORE (phone), &
address_before = @BEFORE (address), &
salary_before = @BEFORE (salary), &
balance_before = @BEFORE (balance), &
comment_before = @BEFORE (comment), &
last_mod_time_before = @BEFORE (last_mod_time), &
    -- maps the results of the SQLEXEC query to rows in the exceptions table
    -- to show the current image of the row in the target.
name_current = qry.name, &
phone_current = qry.phone, &
address_current = qry.address, &
salary_current = qry.salary, &
balance_current = qry.balance, &
comment_current = qry.comment, &
last_mod_time_current = qry.last_mod_time)
;

Una vez que esté seguro de que sus rutinas funcionan como se esperaba en todas las situaciones, puede reducir la cantidad de datos que se registran en la tabla de excepciones para reducir la sobrecarga de las rutinas de resolución.