Detecção e Resolução Manuais de Conflitos
Saiba mais sobre como configurar manualmente o CDR (Conflict Detection and Resolution) usando parâmetros específicos. A detecção e a resolução de conflitos são necessárias nas configurações ativo-ativo, em que o Oracle GoldenGate deve manter a sincronização de dados entre vários bancos de dados que contêm os mesmos conjuntos de dados.
Visão Geral do Recurso CDR do Oracle GoldenGate
O CDR (Conflict Detection and Resolution) do Oracle GoldenGate tem duas partes: Detecção de Conflitos e Resolução de Conflitos. Antes de começar com a resolução de conflitos, é importante investigar e concluir a detecção de conflitos.
O CDR (Conflict Detection and Resolution) do Oracle GoldenGate fornece rotinas básicas de resolução de conflitos que:
-
Resolva um conflito de exclusividade para um
INSERT. -
Resolva um conflito "nenhum dado encontrado" para um
UPDATEquando a linha existir, mas a imagem anterior de uma ou mais colunas for diferente do valor atual no banco de dados. -
Resolva um conflito "nenhum dado encontrado" para uma
UPDATEquando a linha não existir. -
Resolva um conflito "nenhum dado encontrado" para um
DELETEquando a linha existir, mas a imagem anterior de uma ou mais colunas for diferente do valor atual no banco de dados. -
Resolva um conflito "nenhum dado encontrado" para um
DELETEquando a linha não existir.
Para usar a detecção e resolução de conflitos (CDR), o banco de dados de destino deve residir em um sistema Windows, Linux ou UNIX. Não há suporte para bancos de dados na plataforma NonStop.
O CDR suporta tipos de dados escalares, como:
-
NUMERIC -
BOOLEAN -
DATE -
TIMESTAMP -
CHAR/NCHAR -
VARCHAR/ NVARCHAR
Isso significa que esses tipos de coluna podem ser usados com o parâmetro COMPARECOLS e como a coluna de resolução nas opções USEMIN e USEMAX do parâmetro RESOLVECONFLICT. Somente colunas NUMERIC podem ser usadas para a opção USEDELTA de RESOLVECONFLICT. Para USEMAX, USEMIN, somente TIMESTAMP e NUMBER são suportados.
A resolução de conflitos não é executada quando o Replicat opera no modo BATCHSQL. Se ocorrer um conflito no modo BATCHSQL, o Replicat reverterá para o modo GROUPTRANSOPS e, em seguida, para o modo de transação única. A detecção de conflitos ocorre nos três modos.
Configurando os Arquivos de Parâmetros do Oracle GoldenGate para Resolução de Conflitos
Os seguintes parâmetros são necessários para suportar a detecção e a resolução de conflitos.
-
Use a opção
COMPARECOLSdo parâmetroMAPno arquivo de parâmetros Replicat para especificar colunas que devem ser usadas com valores anteriores na cláusulaWHEREdo Replicat. Os valores anteriores são comparados com os valores atuais no banco de dados de destino para detectar conflitos de atualização e exclusão. (Por padrão, o Replicat só usa a chave primária na cláusulaWHERE; isso pode não ser suficiente para a detecção de conflitos). -
Use a opção
RESOLVECONFLICTdo parâmetroMAPpara especificar rotinas de resolução de conflito para diferentes operações e tipos de conflito. Você pode usarRESOLVECONFLICTvárias vezes em uma instruçãoMAPpara especificar diferentes resoluções para diferentes tipos de conflito. No entanto, não é possível usarRESOLVECONFLICTvárias vezes para o mesmo tipo de conflito. Use procedimentos idênticos de resolução de conflitos em todos os bancos de dados, para que o mesmo conflito produza o mesmo resultado final. Um método de resolução de conflitos pode não funcionar para cada conflito que possa ocorrer. Pode ser necessário criar várias rotinas que podem ser chamadas em uma ordem lógica de prioridade para que o risco de falha seja minimizado.
Observação: Uma consideração adicional deve ser dada quando uma tabela tiver uma chave primária e índices exclusivos adicionais ou chaves exclusivas. As rotinas automatizadas fornecidas com os parâmetros COMPARECOLS e RESOLVECONFLICT exigem uma maneira consistente de identificar exclusivamente cada linha. A não identificação consistente de uma linha resultará em erro durante a resolução do conflito. Nessas situações, as chaves exclusivas adicionais devem ser desativadas ou você pode usar o recurso SQLEXEC para tratar o erro gerado e resolver o conflito.
Para obter informações detalhadas sobre esses parâmetros, consulte Referência de Parâmetros e Funções do Oracle GoldenGate. Consulte os exemplos que começam no Exemplo 1 do CDR: Todos os Tipos de Conflito com USEMAX, OVERWRITE, DISCARD para obter mais informações sobre esses parâmetros.
Disponibilizando os Valores de Coluna Obrigatórios para Extração
Para usar CDR, os valores de coluna a seguir devem ser registrados para que o Extract possa gravá-los na trilha.
-
A imagem anterior completa de cada registro. Alguns bancos de dados não fornecem uma imagem anterior no registro de log e devem ser configurados para isso com o registro em log complementar. Para a maioria dos bancos de dados suportados, você pode usar o comando
ADD TRANDATApara essa finalidade. -
Use o parâmetro
LOGALLSUPCOLSpara garantir que as imagens completas antes e depois das colunas de programação sejam gravadas na trilha. As colunas de programação são colunas de chave primária, índice exclusivo e chave estrangeira.LOGALLSUPCOLSfaz com que o Extract inclua no registro de trilha a imagem anterior das operaçõesUPDATEe a imagem anterior de todas as colunas com log complementar para as operaçõesUPDATEeDELETE.
Para obter informações detalhadas sobre esses parâmetros e comandos, consulte o Parameters and Functions Reference for Oracle GoldenGate. Consulte os exemplos que começam com Exemplo 1 do CDR: Todos os Tipos de Conflito com USEMAX, OVERWRITE, DISCARD para obter mais informações sobre como esses parâmetros funcionam com o CDR.
Visualizando Estatísticas de CDR
O recurso CDR fornece os seguintes métodos para visualizar os resultados da resolução de conflitos.
Aqui estão diferentes técnicas que você pode usar para exibir estatísticas de CDR.
Arquivo de Relatório
O Replicat grava estatísticas de CDR no arquivo de relatório:
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
Linha de Comandos
Você pode exibir estatísticas CDR na linha de comando usando o comando STATS REPLICAT com a opção REPORTCDR:
STATS REPLICAT *group*, REPORTCDR
Funções de Conversão de Colunas
As estatísticas de CDR a seguir podem ser recuperadas e mapeadas para uma tabela de exceções ou usadas em outros parâmetros do Oracle GoldenGate que aceitam entrada de funções de conversão de coluna, conforme apropriado.
-
Número de conflitos que o Replicat detectou
-
Número de resoluções que o Replicat resolveu
-
Número de resoluções que o Replicat não pôde resolver
Para recuperar essas estatísticas, use a função de conversão de coluna @GETENV com o tipo de informação STATS ou DELTASTATS. Os resultados se baseiam na sessão Replicat atual. Se o Replicat for interrompido e reiniciado, ele redefinirá as estatísticas.
Você pode retornar estas estatísticas para uma tabela ou conjunto de tabelas com curinga específico:
@GETENV ('STATS','TABLE','SCHEMA.TABLNAME','CDR_CONFLICTS')
@GETENV ('STATS','TABLE','SCHEMA.TABLNAME','CDR_RESOLUTIONS_SUCCEEDED')
@GETENV ('STATS','TABLE','SCHEMA.TABLNAME','CDR_RESOLUTIONS_FAILED')
Você pode retornar essas estatísticas para todas as tabelas em todas as instruções MAP no arquivo de parâmetros Replicat:
@GETENV ('STATS','CDR_CONFLICTS')
@GETENV ('STATS','CDR_RESOLUTIONS_SUCCEEDED')
@GETENV ('STATS','CDR_RESOLUTIONS_FAILED')
O tipo de informação 'STATS' nos exemplos anteriores pode ser substituído por 'DELTASTATS' para retornar as contagens solicitadas desde a última execução do 'DELTASTATS'. Para obter mais informações sobre a @GETENV, consulte @GETENV
Exemplo 1 de CDR: Todos os Tipos de Conflito com USEMAX, OVERWRITE, DISCARD
Este exemplo resolve todos os tipos de conflito usando as resoluções USEMAX, OVERWRITE e DISCARD.
Tabela Utilizada neste Exemplo
Os exemplos pressupõem bancos de dados Oracle idênticos.
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);
No banco de dados de origem, todas as colunas são registradas de forma complementar:
ADD TRANDATA hr.emp_src, COLS (name, phone, address, salary, balance, comment, last_mod_time);
Instrução MAP com Especificações de Resolução de Conflitos
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)),
);
Descrição da instrução MAP
A instrução MAP é descrita a seguir:
-
Por
COMPARECOLS, use a imagem anterior de todas as colunas no registro de trilha na cláusulaWHEREdo Replicat para atualizações e exclusões. -
Por
DEFAULT, use todas as colunas como o grupo de colunas para todos os tipos de conflito; assim, a resolução se aplica a todas as colunas. -
Para um conflito
INSERTROWEXISTS, use a resoluçãoUSEMAX: Se a linha existir durante uma inserção, use a colunalast_mod_timecomo a coluna de resolução para decidir qual é o valor maior: o valor na trilha ou o valor no banco de dados. Se o valor na trilha for maior, aplique o registro, mas altere a inserção para uma atualização. Se o valor do banco de dados for maior, ignore o registro. -
Para um conflito
UPDATEROWEXISTS, use a resoluçãoUSEMAX: Se a linha existir durante uma atualização, use a colunalast_mod_timecomo a coluna de resolução: Se o valor na trilha for maior, aplique a atualização. -
Se você usar
USEMINouUSEMAXe os valores forem exatamente os mesmos,RESOLVECONFLICTnão será acionado e a linha de entrada será ignorada. Se você usarUSEMINEQouUSEMAXEQe os valores forem exatamente os mesmos, a resolução será acionada. -
Para um conflito
DELETEROWEXISTS, use a resoluçãoOVERWRITE: Se a linha existir durante uma operação de exclusão, aplique a exclusão. -
Para um conflito
UPDATEROWMISSING, use a resoluçãoOVERWRITE: Se a linha não existir durante uma atualização, altere a atualização para uma inserção e aplique-a. -
Para um conflito
DELETROWMISSING, use a resoluçãoDISCARD: Se a linha não existir durante uma operação de exclusão, descarte o registro de trilha.Observação: Como alternativa ao
USEMAX, você pode usar a resoluçãoUSEMAXEQpara aplicar uma condição>=. Para obter mais informações, consulte Referência de Parâmetros e Funções do Oracle GoldenGate.
INSERTROWEXISTS com a Resolução USEMAX
Para este exemplo, a resolução USEMAX é ilustrada com as imagens aplicáveis antes e depois do registro na trilha e no banco de dados. Ela mostra como resolver uma inserção em que a linha existe na origem e no destino, mas alguns ou todos os valores de linha são diferentes.
Tabela 10 Conflito de INSERTROWEXISTS com a Resolução USEMAX
| Imagem | SQL | Comentários |
|---|---|---|
| Antes da imagem na trilha | None (row was inserted on the source). |
N/D |
| Após a imagem na trilha | name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=100 comment=NULL last_mod_time='9/1/10 3:00' |
|
| Imagem do banco de dados 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 é a imagem atual da coluna de resolução no destino em relação à qual o valor da coluna de resolução na trilha é comparado. |
INSERT inicial aplicado pelo Replicat que detecta o conflito |
Variáveis de bind SQL: 1)'Mary' 2)'1234567890' 3)'Oracle Pkwy' 4)100 5)100 6)NULL 7)'9/1/10 3:00' |
Este SQL retorna um conflito de exclusividade em 'Maria'. |
UPDATE aplicado pelo Replicat para resolver o conflito |
Variáveis de bind 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' |
Como USEMAX é especificado para INSERTROWEXISTS, o Replicat converte a inserção em uma atualização, e compara o valor de last_mod_time no registro de trilha com o valor no banco de dados. O valor no registro é maior, portanto, as imagens posteriores das colunas no arquivo de trilha são aplicadas ao destino. |
UPDATEROWEXISTS com a Resolução USEMAX
Para este exemplo, a resolução USEMAX é ilustrada com as imagens aplicáveis antes e depois do registro na trilha e no banco de dados. Ela mostra como resolver uma atualização em que a linha existe na origem e no destino, mas alguns ou todos os valores de linha são diferentes.
Tabela 11 Conflito de UPDATEROWEXISTS com a Resolução USEMAX
| Imagem | SQL | Comentários |
|---|---|---|
| Antes da imagem na trilha | 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 é a imagem anterior da coluna de resolução. |
| Após a imagem na trilha | phone='222222' address='Holly' last_mod_time='9/1/10 5:00' |
last_mod_time='9/1/10 5:00 é a imagem posterior da coluna de resolução. Como há uma imagem posterior, ela será usada para determinar a resolução. |
| Imagem do banco de dados 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 é a imagem atual da coluna de resolução no destino em relação à qual o valor da coluna de resolução na trilha é comparado. |
UPDATE inicial aplicado pelo Replicat que detecta o conflito |
Variáveis de bind 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' |
Essa SQL retorna um erro no-data-found porque os valores para Todas as colunas são usadas na cláusula |
UPDATE aplicado pelo Replicat para resolver o conflito |
Variáveis de bind 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' |
Como o valor posterior de last_mod_time no registro de trilha é menor que o valor atual no banco de dados, o valor do banco de dados é retido. O Replicat aplica a operação com uma cláusula WHERE que contém a chave primária mais um valor last_mod_time definido com menos de 9/1/10 5:00. Nenhuma linha corresponde a esses critérios; portanto, a instrução falha com um erro "data not found", mas o Replicat ignora o erro porque espera-se que uma resolução USEMAX falhe se a condição não for satisfeita. |
UPDATEROWMISSING com resolução SUBSTITUÍDA
Para este exemplo, a resolução OVERWRITE é ilustrada com as imagens aplicáveis antes e depois do registro na trilha e no banco de dados. Ela mostra como resolver o caso em que a linha de destino está ausente. A resolução lógica, e a usada, é substituir a linha no destino para que ambos os bancos de dados estejam sincronizados novamente.
Tabela 12 Conflito UPDATEROWMISSING com resolução OVERWRITE
| Imagem | SQL | Comentários |
|---|---|---|
| Antes da imagem na trilha | name='Jane' phone='333' address='Oracle Pkwy' salary=200 balance=200 comment=NULL last_mod_time='9/1/10 7:00' |
N/D |
| Após a imagem na trilha | phone='4444' address='Holly' last_mod_time='9/1/10 8:00' |
|
| Imagem do banco de dados de destino | None (row for Jane is missing) |
|
UPDATE inicial aplicado pelo Replicat que detecta o conflito |
Variáveis de bind 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 retorna um erro no-data-found. Todas as colunas são usadas na cláusula WHERE porque a instrução COMPARECOLS está definida como ALL. |
INSERT aplicado pelo Replicat para resolver o conflito |
Variáveis de bind SQL: 1)'Jane' 2)'4444' 3)'Holly' 4)200 5)200 6)NULL 7)'9/1/10 8:00' |
A atualização é convertida em uma inserção porque OVERWRITE é a resolução. A imagem posterior de uma coluna é usada, se disponível; caso contrário, a imagem anterior é usada. |
DELETEROWEXISTS com resolução OVERWRITE
Para este exemplo, a resolução OVERWRITE é ilustrada com as imagens aplicáveis antes e depois do registro na trilha e no banco de dados. Ela mostra como resolver o caso em que a linha de origem foi excluída, mas a linha de destino existe. Nesse caso, a resolução OVERWRITE aplica a exclusão ao destino.
Tabela 13 Conflito DELETEROWEXISTS com resolução OVERWRITE
| Imagem | SQL | Comentários |
|---|---|---|
| Antes da imagem na trilha | name='Mary' phone='222222' address='Holly' salary=100 balance=100 comment=NULL last_mod_time='9/1/10 5:00' |
N/D |
| Após a imagem na trilha | None |
N/D |
| Imagem do banco de dados de destino | name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=600 comment=com last_mod_time='9/1/10 7:00' |
A linha existe no destino, mas as colunas phone, address, balance, comment e last_mod_time são diferentes da imagem anterior na trilha. |
DELETE inicial aplicado pelo Replicat que detecta o conflito |
Variáveis de bind SQL: 1)'Mary' 2)'222222' 3)'Holly' 4)100 5)100d 6)NULL 7)'9/1/10 5:00' |
Todas as colunas são usadas na cláusula Um erro no-data-found ocorre devido à diferença entre os valores anterior e atual. |
DELETE aplicado pelo Replicat para resolver o conflito |
Variáveis de bind SQL: 1)'Mary' |
Como OVERWRITE é a resolução, o DELETE é aplicado usando apenas a chave primária (para evitar um erro de integridade). |
DELETEROWMISSING com resolução DISCARD
Para este exemplo, a resolução DISCARD é ilustrada com as imagens aplicáveis antes e depois do registro na trilha e no banco de dados. Ela mostra como resolver o caso em que a linha de destino está ausente. No caso de uma exclusão na origem, é aceitável que a linha de destino não exista (ela precisaria ser excluída mesmo assim), portanto, a resolução é descartar a operação DELETE que está na trilha.
Tabela 14 Conflito DELETEROWMSING com a Resolução DISCARD
| Imagem | SQL | Comentários |
|---|---|---|
| Antes da imagem na trilha | name='Jane' phone='4444' address='Holly' salary=200 balance=200 comment=NULL last_mod_time='9/1/10 8:00' |
N/D |
| Após a imagem na trilha | None |
N/D |
| Imagem do banco de dados de destino | None (row missing) |
N/D |
DELETE inicial aplicado pelo Replicat que detecta o conflito |
Variáveis de bind SQL: 1)'Jane' 2)'4444' 3)'Holly' 4)200 5)200 6)NULL 7)'9/1/10 8:00' |
Este SQL retorna um erro no-data-found. Todas as colunas são usadas na cláusula WHERE porque a instrução COMPARECOLS está definida como ALL. |
| SQL aplicada pelo Replicat para resolver o conflito | None |
Como DISCARD é especificado como a resolução para DELETEROWMISSING, a exclusão da trilha vai para o arquivo de descarte. |
Exemplo 2 de CDR: UPDATEROWEXISTS com USEDELTA e USEMAX
Este exemplo resolve a condição em que existe uma linha de destino em UPDATE, mas as colunas que não são de chave são diferentes, e usa dois tipos de resolução diferentes para tratar essa condição com base na coluna afetada.
Tabela Utilizada neste Exemplo
Os exemplos pressupõem bancos de dados Oracle idênticos.
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);
No banco de dados de origem, todas as colunas são registradas de forma complementar:
ADD TRANDATA scott.src, COLS (name, phone, address, salary, balance, comment, last_mod_time);
Instrução 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)));
Descrição da instrução MAP
Para um conflito UPDATEROWEXISTS, em que existe uma linha de destino em UPDATE, mas as colunas que não são de chave são diferentes, use duas resoluções diferentes, dependendo da coluna:
-
De acordo com a resolução
delta_res_method, use a lógica de resoluçãoUSEDELTApara a colunasalarypara que a alteração no valor seja adicionada ao valor atual da coluna. -
Por
DEFAULT, use a lógica de resoluçãoUSEMAXpara todas as outras colunas da tabela (o grupo de colunas padrão), usando a colunalast_mod_timecomo a coluna de resolução. Essa coluna é atualizada com a hora atual sempre que a linha é modificada; o valor dessa coluna na trilha é comparado ao valor no destino. Se o valor delast_mod_timeno registro de trilha for maior que o valor atual delast_mod_timeno banco de dados de destino, as alterações emname,phone,address,balance,commentelast_mod_timeserão aplicadas ao destino.
Por COMPARECOLS, use a chave primária (coluna name ) mais as colunas address, phone, salary e last_mod_time como as colunas de comparação para detecção de conflito para operações UPDATE e DELETE. (As colunas balance e comment não são comparadas.)
Observação: Como alternativa ao USEMAX, você pode usar a resolução USEMAXEQ para aplicar uma condição >=. Para obter mais informações, consulte Referência de Parâmetros e Funções do Oracle GoldenGate.
Tratamento de Erros
Para obter um exemplo de tratamento de erros em uma tabela de exceções, consulte Configurando os Arquivos de Parâmetros do Oracle GoldenGate para Tratamento de Erros.
Tabela 15 UPDATEROWEXISTS com USEDELTA e USEMAX
| Imagem | SQL | Comentários |
|---|---|---|
| Antes da imagem na trilha | |
|
| Após a imagem na trilha | |
last_mod_time='9/1/10 5:00 é a imagem posterior da coluna de resolução para USEMAX. Como há uma imagem posterior, ela será usada para determinar a resolução. |
| Imagem do banco de dados de destino | |
|
UPDATE inicial aplicado pelo Replicat que detecta o conflito |
Variáveis de bind SQL: |
Esta SQL retorna um erro no-data-found porque os valores para salary e last_mod_time são diferentes. (Os valores para comment e balance também são diferentes, mas essas colunas não são comparadas.) |
UPDATE aplicado pelo Replicat para resolver o conflito de salary, usando USEDELTA. |
Variáveis de bind SQL: |
Por |
UPDATE aplicado pelo Replicat para resolver o conflito das colunas padrão, usando USEMAX. |
Variáveis de bind SQL: |
Por Observe que a coluna |
Exemplo 3 de CDR: UPDATEROWEXISTS com USEDELTA, USEMAX e IGNORE
Este exemplo resolve o conflito em que existe uma linha de destino em UPDATE, mas as colunas que não são de chave são diferentes, e usa três tipos de resolução diferentes para tratar essa condição com base na coluna afetada.
Tabela Utilizada Neste Exemplo
Os exemplos pressupõem bancos de dados Oracle idênticos.
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);
No banco de dados de origem, todas as colunas são registradas de forma complementar:
ADD TRANDATA scott.src, COLS (name, phone, address, salary, balance, comment, last_mod_time);
Instrução 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));
Descrição da instrução MAP
-
Para um conflito
UPDATEROWEXISTS, em que existe uma linha de destino emUPDATE, mas as colunas que não são de chave são diferentes, use duas resoluções diferentes, dependendo da coluna:-
De acordo com a resolução
delta_res_method, use a lógica de resoluçãoUSEDELTApara as colunassalaryebalancepara que a alteração em cada valor seja adicionada ao valor atual de cada coluna. -
De acordo com a resolução
max_res_method, use a lógica de resoluçãoUSEMAXpara as colunasaddresselast_mod_time. A colunalast_mod_timeé a coluna de resolução. Essa coluna é atualizada com a hora atual sempre que a linha é modificada; o valor dessa coluna na trilha é comparado ao valor no destino. Se o valor delast_mod_timeno registro de trilha for maior que o valor atual delast_mod_timeno banco de dados de destino, as alterações emaddresselast_mod_timeserão aplicadas ao destino; caso contrário, elas serão ignoradas em favor dos valores de destino. -
Por
DEFAULT, use a lógica de resoluçãoIGNOREpara as colunas restantes (phoneecomment) na tabela (o grupo de colunas padrão). As alterações nessas colunas serão sempre ignoradas pelo processo Replicat.
-
-
Por
COMPARECOLS, use todas as colunas, exceto a colunacomment, como as colunas de comparação para detecção de conflito para operaçõesUPDATE. O comentário não será usado na cláusulaWHEREpara atualizações, mas todas as outras colunas que tiverem uma imagem anterior no registro de trilha serão usadas. Observação: Como alternativa aoUSEMAX, você pode usar a resoluçãoUSEMAXEQpara aplicar uma condição>=. Para obter mais informações, consulte Referência de Parâmetros e Funções do Oracle GoldenGate.
Tratamento de Erros
Para obter um exemplo de tratamento de erros em uma tabela de exceções, consulte Configurando os Arquivos de Parâmetros do Oracle GoldenGate para Tratamento de Erros.
Tabela 16 UPDATEROWEXISTS com USEDELTA, USEMAX e IGNORE
| Imagem | SQL | Comentários |
|---|---|---|
| Antes da imagem na trilha | |
|
| Após a imagem na trilha | |
|
| Imagem do banco de dados de destino | |
|
UPDATE inicial aplicado pelo Replicat que detecta o conflito |
Variáveis de bind SQL: |
Essa SQL retorna um erro no-data-found porque os valores das colunas address, salary, balance e last_mod_time são diferentes. |
UPDATE aplicado pelo Replicat para resolver o conflito de salary, usando USEDELTA. |
Variáveis de bind SQL: |
Para salary, há uma diferença de 100, mas não houve alteração no valor para balance; portanto, não é necessário atualizar o SQL. Por USEDELTA, a diferença (delta) entre a imagem posterior (200) e a imagem anterior (100) de salary na trilha é adicionada ao valor atual de salary no destino (600). O resultado é 700. |
UPDATE aplicado pelo Replicat para resolver o conflito de USEMAX. |
Variáveis de bind SQL: |
Como o valor posterior de Observe que a coluna |
UPDATE aplicado pelo Replicat para IGNORE. |
Variáveis de bind SQL: |
IGNORE é especificado para o grupo de colunas DEFAULT (phone e comment), portanto, nenhuma SQL de resolução é aplicada. |
Configurando os Arquivos de Parâmetros do Oracle GoldenGate para Tratamento de Erros
O CDR manual deve ser usado em conjunto com o tratamento de erros para capturar erros que foram resolvidos e erros que o CDR não pôde resolver.
-
A resolução de conflitos é executada antes desses outros parâmetros de tratamento de erros:
HANDLECOLLSIONS,INSERTMISSINGUPDATESeREPERROR. Use o parâmetroREPERRORpara designar regras para tratar erros que não podem ser resolvidos pelo CDR ou para erros que você não deseja tratar por meio do CDR. Pode ser apropriado queREPERRORtrate alguns erros e CDR trate outros; no entanto, seREPERRORe CDR estiverem configurados para tratar o mesmo conflito, o CDR terá precedência. Os parâmetrosINSERTMISSINGUPDATESeHANDLECOLLISIONStambém podem ser usados para tratar alguns erros não tratados pelo CDR. Consulte a Referência de Parâmetros e Funções do Oracle GoldenGate para obter detalhes sobre esses parâmetros. -
(Opcional) Crie uma tabela de exceções. Quando uma tabela de exceções é usada com uma instrução
MAPde exceções, o Replicat envia cada operação que gera um conflito (resolvido ou não) para a instruçãoMAPde exceções a ser mapeada para a tabela de exceções. Omita uma chave primária nesta tabela se o Replicat for processar conflitos entreUPDATEeDELETE; caso contrário, poderá haver erros de restrição de integridade.No mínimo, uma tabela de exceções deve conter as mesmas colunas que a tabela de destino. Essas linhas conterão cada imagem de linha que o Replicat aplicou ao destino (ou tentou aplicar).
Além disso, você pode definir colunas adicionais para capturar outras informações que ajudam a colocar os dados no contexto transacional. O Oracle GoldenGate fornece ferramentas para capturar essas informações por meio da instrução
MAPde exceções. Essas colunas podem ser, mas não se limitam a:-
A imagem anterior do registro de trilha. Este é um conjunto duplicado de colunas de destino com nomes como col1_before, col2_before, e assim por diante.
-
Os valores atuais das colunas de destino. Este também é um conjunto duplicado das colunas de destino com nomes como col1_current, col2_current e assim por diante.
-
O nome da tabela de destino
-
O timestamp do conflito
-
O tipo de operação
-
O número de erro do banco de dados
-
(Opcional) A mensagem de erro do banco de dados
-
Se o conflito foi resolvido ou não
-
-
Crie uma instrução
MAPde exceções para mapear os dados de exceções para a tabela de exceções. Uma instruçãoMAPde exceções contém:-
(Obrigatório) A opção
INSERTALLRECORDS. Esse parâmetro converte todas as operações mapeadas emINSERTs para que todos os valores de coluna sejam mapeados para a tabela de exceções. -
(Obrigatório) A opção
EXCEPTIONSONLY. Esse parâmetro faz com que o Replicat mapeie as operações que geram um erro, mas não as que foram bem-sucedidas. -
(Opcional) Uma cláusula
COLMAP. Se os nomes e definições das colunas na tabela de exceções forem idênticos aos da tabela de origem e a tabela de exceções contiver apenas essas colunas, não será necessárioCOLMAP. No entanto, se houver nomes ou definições diferentes ou se houver colunas extras na tabela de exceções que você deseja preencher com dados adicionais, use uma cláusulaCOLMAPpara mapear todas as colunas.
-
Ferramentas para Mapeamento de Dados Adicionais para a Tabela de Exceções
Veja a seguir algumas ferramentas que você pode usar na cláusula COLMAP para preencher colunas extras:
-
Se os nomes e as definições das colunas de origem forem idênticos aos das colunas de destino na tabela de exceções, você poderá usar a palavra-chave
USEDEFAULTSem vez de mapear nomes explicitamente. Caso contrário, você deverá mapear essas colunas na cláusulaCOLMAP, por exemplo:COLMAP (exceptions_col1 = col1, [...]) -
Para mapear a imagem anterior da linha de origem para colunas na tabela de exceções, use a função de conversão
@BEFORE, que captura a imagem anterior de uma coluna do registro de trilha. Este exemplo mostra o uso do@BEFORE.COLMAP (USEDEFAULTS, exceptions_col1 = @BEFORE (source_col1), & exceptions_col2 = @BEFORE (source_col2), [...]) -
Para mapear a imagem atual da linha de destino para colunas na tabela de exceções, use uma consulta
SQLEXECpara capturar a imagem e, em seguida, mapeie os resultados da consulta para as colunas na tabela de exceções usando a sintaxe 'queryID.column' na cláusulaCOLMAP, como no seguinte exemplo:COLMAP (USEDEFAULTS, name_current = *queryID*.*name*, phone_current = *queryID*.*phone*, [...]) -
Para mapear timestamps, erros de banco de dados e outras informações ambientais, use as funções de conversão de coluna apropriadas do Oracle GoldenGate. Por exemplo, o seguinte mapeia o timestamp atual no momento da execução.
res_date = @DATENOW ()
Consulte Mapeamento de Exceções de Amostra com Colunas Adicionais na Tabela de Exceções para saber como combinar esses recursos em uma cláusula COLMAP na instrução MAP de exceções para preencher uma tabela de exceções detalhada.
Consulte Referência de Parâmetros e Funções do Oracle GoldenGate para obter o uso e a sintaxe dos parâmetros e das funções de conversão de coluna mostrados nestes exemplos.
Mapeamento de Exceções de Amostra com Colunas de Origem e de Destino Somente
Veja a seguir um arquivo de parâmetro de amostra que mostra o tratamento de erros e o mapeamento de exceções simples para as tabelas de origem e destino usadas nos exemplos de CDR que começam. Este exemplo mapeia colunas de origem e de destino, mas não colunas extras. Por estes motivos, não é necessária uma cláusula COLMAP na instrução MAP de exceções neste exemplo:
-
As colunas de exceções de origem e destino são idênticas em nome e definição.
-
Não há outras colunas na tabela de exceções. Observação: Este exemplo exclui intencionalmente outros parâmetros necessários em um arquivo de parâmetros Replicat, como o nome do processo e as credenciais de log-in, bem como quaisquer parâmetros opcionais que possam ser necessários para um determinado tipo de banco de dados. Ao usar quebras de linha para dividir uma instrução de parâmetro em várias linhas, use um E comercial (&) no fim de cada linha.
-- 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
;
Mapeamento de Exceções de Amostra com Colunas Adicionais na Tabela de Exceções
Veja a seguir um arquivo de parâmetro de amostra que mostra o tratamento de erros e o mapeamento de exceções complexas para as tabelas de origem e destino usadas nos exemplos de CDR que começam. Neste exemplo, a tabela de exceções tem as mesmas linhas da tabela de origem, mas também tem colunas adicionais para capturar dados de contexto.
Observação: Este exemplo exclui intencionalmente outros parâmetros necessários em um arquivo de parâmetros Replicat, como o nome do processo e as credenciais de log-in, bem como quaisquer parâmetros opcionais que possam ser necessários para um determinado tipo de banco de dados. Ao usar quebras de linha para dividir uma instrução de parâmetro em várias linhas, use um E comercial (&) no fim de cada linha.
-- 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)
;
Assim que tiver certeza de que suas rotinas funcionam conforme esperado em todas as situações, você poderá reduzir a quantidade de dados registrados na tabela de exceções para reduzir a sobrecarga das rotinas de resolução.