수동 충돌 감지 및 해결

특정 매개변수를 사용하여 CDR(충돌 감지 및 해결)을 수동으로 구성하는 방법을 알아봅니다. 충돌 감지 및 해결은 Oracle GoldenGate가 동일한 데이터 세트를 포함하는 여러 데이터베이스 간의 데이터 동기화를 유지 관리해야 하는 활성-활성 구성에서 필요합니다.

Oracle GoldenGate CDR 기능 개요

Oracle GoldenGate CDR(충돌 감지 및 해결)은 충돌 감지 및 충돌 해결의 두 부분으로 구성됩니다. 충돌 해결을 시작하기 전에 충돌 감지를 조사하고 완료하는 것이 중요합니다.

Oracle GoldenGate CDR(충돌 감지 및 해결)은 다음과 같은 기본적인 충돌 해결 루틴을 제공합니다.

CDR(충돌 감지 및 해결)을 사용하려면 대상 데이터베이스가 Windows, Linux 또는 UNIX 시스템에 상주해야 합니다. NonStop 플랫폼의 데이터베이스에는 지원되지 않습니다.

CDR은 다음과 같은 스칼라 데이터 유형을 지원합니다.

즉, 이러한 열 유형을 COMPARECOLS 매개변수와 함께 사용할 수 있으며 RESOLVECONFLICT 매개변수의 USEMIN 및 USEMAX 옵션에서 분석 열로 사용할 수 있습니다. RESOLVECONFLICT의 USEDELTA 옵션에는 NUMERIC 열만 사용할 수 있습니다. USEMAX, USEMIN의 경우 TIMESTAMP 및 NUMBER만 지원됩니다.

Replicat가 BATCHSQL 모드에서 작동하는 경우 충돌 해결이 수행되지 않습니다. BATCHSQL 모드에서 충돌이 발생할 경우 Replicat는 GROUPTRANSOPS 모드로 되돌린 다음 단일 트랜잭션 모드로 되돌아갑니다. 충돌 감지는 세 가지 모드 모두에서 발생합니다.

충돌 해결을 위한 Oracle GoldenGate 파라미터 파일 구성

충돌 감지 및 해결을 지원하려면 다음 매개변수가 필요합니다.

  1. Replicat 매개변수 파일에서 MAP 매개변수의 COMPARECOLS 옵션을 사용하여 Replicat WHERE 절에서 이전 값과 함께 사용할 열을 지정합니다. 이전 값은 Target Database의 현재 값과 비교되어 갱신 및 삭제 충돌을 감지합니다. (기본적으로 Replicat는 WHERE 절의 기본 키만 사용합니다. 충돌 감지에 충분하지 않을 수 있습니다.)

  2. MAP 매개변수의 RESOLVECONFLICT 옵션을 사용하여 여러 작업 및 충돌 유형에 대한 충돌 해결 루틴을 지정합니다. MAP 문에서 RESOLVECONFLICT를 여러 번 사용하여 서로 다른 충돌 유형에 대해 서로 다른 해상도를 지정할 수 있습니다. 그러나 동일한 유형의 충돌에 대해 RESOLVECONFLICT를 여러 번 사용할 수는 없습니다. 모든 데이터베이스에서 동일한 충돌 해결 프로시저를 사용하면 동일한 충돌로 인해 동일한 결과가 발생합니다. 발생할 수 있는 모든 충돌에 대해 하나의 충돌 해결 방법이 작동하지 않을 수 있습니다. 실패 위험이 최소화되도록 논리적 우선 순위 순서로 호출할 수 있는 여러 루틴을 만들어야 할 수 있습니다.

주: 테이블에 기본 키와 추가 고유 인덱스 또는 고유 키가 있는 경우 추가로 고려해야 합니다. COMPARECOLS 및 RESOLVECONFLICT 매개변수와 함께 제공되는 자동화된 루틴의 경우 각 행을 고유하게 식별하는 일관된 방법이 필요합니다. 일관되게 행을 식별하지 못하면 충돌 해결 중 오류가 발생합니다. 이러한 경우 추가 고유 키를 사용 안함으로 설정하거나 SQLEXEC 기능을 사용하여 발생한 오류를 처리하고 충돌을 해결할 수 있습니다.

이러한 매개변수에 대한 자세한 내용은 Oracle GoldenGate용 매개변수 및 함수 참조를 참조하십시오. 이러한 매개변수에 대한 자세한 내용은 CDR Example 1: All Conflict Types with USEMAX, OVERWRITE, DISCARD에서 시작하는 예를 참조하십시오.

필요한 열 값을 추출할 수 있도록 설정

CDR을 사용하려면 Extract가 추적에 쓸 수 있도록 다음 열 값을 기록해야 합니다.

이러한 매개변수 및 명령에 대한 자세한 내용은 Oracle GoldenGate용 매개변수 및 함수 참조를 참조하십시오. 이러한 매개변수가 CDR에서 작동하는 방법에 대한 자세한 내용은 CDR Example 1: All Conflict Types with USEMAX, OVERWRITE, DISCARD에서 시작하는 예를 참조하십시오.

CDR 통계 보기

CDR 기능은 충돌 해결 결과를 보기 위한 다음과 같은 방법을 제공합니다.

다음은 CDR 통계를 보는 데 사용할 수 있는 여러 가지 기법입니다.

보고서 파일로

Replicat는 CDR 통계를 보고서 파일에 기록합니다.

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

명령행

REPORTCDR 옵션과 함께 STATS REPLICAT 명령을 사용하여 명령행에서 CDR 통계를 볼 수 있습니다.

STATS REPLICAT *group*, REPORTCDR

열 변환 함수

다음 CDR 통계를 검색 및 예외 테이블에 매핑하거나 열 변환 함수의 입력을 적절하게 수락하는 다른 Oracle GoldenGate 매개변수에 사용할 수 있습니다.

이러한 통계를 검색하려면 STATS 또는 DELTASTATS 정보 유형과 함께 @GETENV 열 변환 함수를 사용합니다. 결과는 현재 Replicat 세션을 기반으로 합니다. Replicat가 중지되었다가 다시 시작되면 통계가 재설정됩니다.

특정 테이블 또는 와일드카드 테이블 집합에 대해 다음 통계를 반환할 수 있습니다.

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

Replicat 매개변수 파일의 모든 MAP 문에 있는 모든 테이블에 대해 다음 통계를 반환할 수 있습니다.

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

앞의 예에서 'STATS' 정보 유형은 'DELTASTATS'의 마지막 실행 이후 요청된 개수를 반환하기 위해 'DELTASTATS'로 바꿀 수 있습니다. @GETENV에 대한 자세한 내용은 @GETENV을 참조하십시오.

CDR 예제 1: USEMAX, OVERWRITE, DISCARD를 사용하는 모든 충돌 유형

이 예에서는 USEMAX, OVERWRITE 및 DISCARD 해상도를 사용하여 모든 충돌 유형을 해결합니다.

이 예제에 사용된 테이블

예제에서는 동일한 Oracle 데이터베이스를 가정합니다.

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);

원본 데이터베이스에서 모든 열은 보완적으로 기록됩니다.

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

충돌 해결 사양이 있는 MAP 문

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)),
    );

MAP 문 설명

다음은 MAP 문에 대해 설명합니다.

USEMAX 해상도를 사용하는 INSERTROWEXISTS

이 예에서 USEMAX 해상도는 추적 및 데이터베이스의 레코드에 대해 적용 가능한 이전 및 이후 이미지와 함께 표시됩니다. 소스와 대상에서 행이 존재하지만 일부 또는 모든 행 값이 다른 삽입을 분석하는 방법을 보여줍니다.

표 10 INSERTROWEXISTS가 USEMAX 해결과 충돌함

이미지 SQL 설명
트레일의 이전 이미지
None (row was inserted on the source).
N/A
추적에서 이미지 뒤
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는 분석 열의 뒤쪽 이미지입니다. 이후 이미지가 있으므로 해상도를 결정하는 데 사용됩니다.

대상 데이터베이스 이미지
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는 추적의 해결 열 값이 비교되는 대상의 해결 열의 현재 이미지입니다.
충돌을 감지하는 Replicat가 적용한 초기 INSERT

SQL 바인드 변수는 다음과 같습니다.

1)'Mary' 2)'1234567890' 3)'Oracle Pkwy' 4)100 5)100 6)NULL 7)'9/1/10 3:00'
이 SQL은 'Mary'에 대한 고유성 충돌을 반환합니다.
UPDATE 충돌을 해결하기 위해 Replicat에서 적용

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'
USEMAX는 INSERTROWEXISTS에 대해 지정되므로 Replicat는 삽입을 업데이트로 변환하고 추적 레코드의 last_mod_time 값을 데이터베이스의 값과 비교합니다. 레코드의 값이 더 커서 추적 파일의 열에 대한 이후 이미지가 대상에 적용됩니다.

USEMAX 해결을 사용한 UPDATEROWEXISTS

이 예에서 USEMAX 해상도는 추적 및 데이터베이스의 레코드에 대해 적용 가능한 이전 및 이후 이미지와 함께 표시됩니다. 소스와 대상에서 행이 존재하지만 일부 또는 모든 행 값이 다른 경우 갱신을 분석하는 방법을 보여줍니다.

표 11 UPDATEROWEXISTS가 USEMAX 해결과 충돌함

이미지 SQL 설명
트레일의 이전 이미지
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는 분석 열의 이전 이미지입니다.
추적에서 이미지 뒤
phone='222222' address='Holly' last_mod_time='9/1/10 5:00'
last_mod_time='9/1/10 5:00는 분석 열의 뒤쪽 이미지입니다. 이후 이미지가 있으므로 해상도를 결정하는 데 사용됩니다.
대상 데이터베이스 이미지
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는 추적의 해결 열 값이 비교되는 대상의 해결 열의 현재 이미지입니다.
충돌을 감지하는 Replicat가 적용한 초기 UPDATE

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'

이 SQL은 대상에서 balance, comment 및 last_mod_time에 대한 값이 다르기 때문에 데이터를 찾을 수 없는 오류를 반환합니다.

COMPARECOLS 문이 ALL로 설정되었으므로 모든 열이 WHERE 절에서 사용됩니다.

UPDATE 충돌을 해결하기 위해 Replicat에서 적용

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'
트레일 레코드에서 last_mod_time의 이후 값이 데이터베이스의 현재 값보다 작으므로 데이터베이스 값이 유지됩니다. Replicat는 기본 키와 9/1/10 5:00 미만으로 설정된 last_mod_time 값을 포함하는 WHERE 절을 사용하여 작업을 적용합니다. 이 조건과 일치하는 행이 없으므로 "데이터를 찾을 수 없음" 오류로 인해 명령문이 실패하지만 조건이 충족되지 않으면 USEMAX 해결이 실패할 것으로 예상되므로 Replicat는 오류를 무시합니다.

오버라이트 해상도로 UPDATEROWMISSING

이 예에서 OVERWRITE 해상도는 추적 및 데이터베이스의 레코드에 대해 적용 가능한 이전 및 이후 이미지와 함께 표시됩니다. 대상 행이 누락된 경우를 해결하는 방법을 보여줍니다. 논리적 해결 방법과 사용된 해결 방법은 두 데이터베이스가 다시 동기화되도록 행을 대상으로 겹쳐쓰는 것입니다.

표 12 UPDATEROWMISSING OVERWRITE 해상도와 충돌

이미지 SQL 설명
트레일의 이전 이미지
name='Jane' phone='333' address='Oracle Pkwy' salary=200 balance=200 comment=NULL last_mod_time='9/1/10 7:00'
N/A
추적에서 이미지 뒤
phone='4444' address='Holly' last_mod_time='9/1/10 8:00'
 
대상 데이터베이스 이미지
None (row for Jane is missing)
 
충돌을 감지하는 Replicat가 적용한 초기 UPDATE

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'
이 SQL은 데이터를 찾을 수 없는 오류를 반환합니다. COMPARECOLS 문이 ALL로 설정되었으므로 모든 열이 WHERE 절에서 사용됩니다.
INSERT 충돌을 해결하기 위해 Replicat에서 적용

SQL 바인드 변수는 다음과 같습니다.

1)'Jane' 2)'4444' 3)'Holly' 4)200 5)200 6)NULL 7)'9/1/10 8:00'
OVERWRITE가 해상도이므로 업데이트가 삽입으로 변환됩니다. 사용할 수 있는 경우 열의 이후 이미지가 사용되고, 그렇지 않은 경우 이전 이미지가 사용됩니다.

DELETEROWEXISTS: 오버라이트 해상도

이 예에서 OVERWRITE 해상도는 추적 및 데이터베이스의 레코드에 대해 적용 가능한 이전 및 이후 이미지와 함께 표시됩니다. 소스 행이 삭제되었지만 대상 행이 존재하는 경우를 해결하는 방법을 보여줍니다. 이 경우 OVERWRITE 해상도는 대상에 삭제를 적용합니다.

표 13 DELETEROWEXISTS가 OVERWRITE 해상도와 충돌함

이미지 SQL 설명
트레일의 이전 이미지
name='Mary' phone='222222' address='Holly' salary=100 balance=100 comment=NULL last_mod_time='9/1/10 5:00'
N/A
추적에서 이미지 뒤
None
N/A
대상 데이터베이스 이미지
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=600 comment=com last_mod_time='9/1/10 7:00'
대상에는 행이 있지만 phone, address, balance, comment 및 last_mod_time 열은 추적의 이전 이미지와 다릅니다.
충돌을 감지하는 Replicat가 적용한 초기 DELETE

SQL 바인드 변수는 다음과 같습니다.

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

COMPARECOLS 문이 ALL로 설정되었으므로 모든 열이 WHERE 절에서 사용됩니다.

이전 값과 현재 값의 차이로 인해 데이터 없는 오류가 발생합니다.

DELETE 충돌을 해결하기 위해 Replicat에서 적용

SQL 바인드 변수는 다음과 같습니다.

1)'Mary'
OVERWRITE는 해결 방법이기 때문에 DELETE는 무결성 오류를 방지하기 위해 기본 키만 사용하여 적용됩니다.

DISCARD 해상도로 DELETEROWMISSING

이 예에서 DISCARD 해상도는 추적 및 데이터베이스의 레코드에 대해 적용 가능한 이전 및 이후 이미지와 함께 표시됩니다. 대상 행이 누락된 경우를 해결하는 방법을 보여줍니다. 소스에서 삭제하는 경우 대상 행이 존재하지 않을 수 있으므로(어쨌든 삭제해야 함) 추적에 있는 DELETE 작업을 폐기할 수 있습니다.

표 14 DELETEROWMSING이 DISCARD 해결과 충돌함

이미지 SQL 설명
트레일의 이전 이미지
name='Jane' phone='4444' address='Holly' salary=200 balance=200 comment=NULL last_mod_time='9/1/10 8:00'
N/A
추적에서 이미지 뒤
None
N/A
대상 데이터베이스 이미지
None (row missing)
N/A
충돌을 감지하는 Replicat가 적용한 초기 DELETE

SQL 바인드 변수는 다음과 같습니다.

1)'Jane' 2)'4444' 3)'Holly' 4)200 5)200 6)NULL 7)'9/1/10 8:00'
이 SQL은 데이터를 찾을 수 없는 오류를 반환합니다. COMPARECOLS 문이 ALL로 설정되었으므로 모든 열이 WHERE 절에서 사용됩니다.
충돌을 해결하기 위해 Replicat에서 적용한 SQL
None
DISCARD는 DELETEROWMISSING에 대한 해상도로 지정되므로 추적에서 삭제는 폐기 파일로 이동합니다.

CDR 예제 2: USEDELTA 및 USEMAX를 사용한 UPDATEROWEXISTS

이 예제는 대상 행이 UPDATE에 존재하지만 키가 아닌 열이 다른 조건을 해결하고, 영향을 받는 열을 기반으로 이 조건을 처리하기 위해 두 가지 해결 유형을 사용합니다.

이 예제에 사용된 테이블

예제에서는 동일한 Oracle 데이터베이스를 가정합니다.

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);

원본 데이터베이스에서 모든 열은 보완적으로 기록됩니다.

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

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)));

MAP 문 설명

UPDATE에 대상 행이 있지만 키가 아닌 열이 다른 UPDATEROWEXISTS 충돌의 경우 열에 따라 두 가지 해결 방법을 사용합니다.

COMPARECOLS에 따라 UPDATE 및 DELETE 작업에 대한 충돌 감지에 대한 비교 열로 기본 키(name 열)와 address, phone, salary 및 last_mod_time 열을 사용합니다. balance 및 comment 열은 비교되지 않습니다.

주: USEMAX 대신 USEMAXEQ 해상도를 사용하여 >= 조건을 적용할 수 있습니다. 자세한 내용은 Oracle GoldenGate에 대한 매개변수 및 함수 참조를 참조하십시오.

오류 처리

예외 테이블에 대한 오류 처리 예는 오류 처리를 위해 Oracle GoldenGate 매개변수 파일 구성을 참조하십시오.

표 15 USEDELTA 및 USEMAX를 사용한 UPDATEROWEXISTS

이미지 SQL 설명
트레일의 이전 이미지
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는 USEMAX 해상도에 대한 해상도 열의 이전 이미지입니다.

salary=100는 USEDELTA 해상도의 이전 이미지입니다.

추적에서 이미지 뒤
phone='222222' address='Holly' salary=200 comment='new' last_mod_time='9/1/10 5:00'
last_mod_time='9/1/10 5:00는 USEMAX에 대한 분석 열의 뒤쪽 이미지입니다. 이후 이미지가 있으므로 해상도를 결정하는 데 사용됩니다.
대상 데이터베이스 이미지
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는 추적의 해결 열 값이 비교되는 대상의 해결 열의 현재 이미지입니다.

salary=600는 USEDELTA 해상도에 대한 대상 열의 현재 이미지입니다.

충돌을 감지하는 Replicat가 적용한 초기 UPDATE

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'
이 SQL은 salary 및 last_mod_time에 대한 값이 다르기 때문에 데이터를 찾을 수 없는 오류를 반환합니다. comment 및 balance의 값도 다르지만 이러한 열은 비교되지 않습니다.
USEDELTA를 사용하여 salary에 대한 충돌을 해결하기 위해 Replicat에서 적용한 UPDATE입니다.

SQL 바인드 변수는 다음과 같습니다.

1)200 2)100 3)'Mary'

USEDELTA에 따라 추적에서 salary(200)의 후 이미지와 추적에서 salary(100)의 이전 이미지 간의 차이는 대상(600)의 현재 값 salary에 추가됩니다. 결과는 700입니다.

600 + (200 - 100) = 700
USEMAX를 사용하여 기본 열에 대한 충돌을 해결하기 위해 Replicat에서 적용한 UPDATE입니다.

SQL 바인드 변수는 다음과 같습니다.

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

USEMAX당 추적 레코드에서 last_mod_time의 이후 값이 데이터베이스의 현재 값보다 크므로 행이 추적 레코드의 이후 값으로 업데이트됩니다.

salary 열은 USEDELTA 해상도의 UPDATE로 분석되므로 여기서 설정되지 않습니다.

CDR 예제 3: USEDELTA, USEMAX 및 IGNORE를 사용한 UPDATEROWEXISTS

이 예제는 대상 행이 UPDATE에 존재하지만 키가 아닌 열이 서로 다른 경우 충돌을 해결하고, 영향을 받는 열을 기반으로 이 조건을 처리하기 위해 세 가지 해결 유형을 사용합니다.

이 예제에 사용된 테이블

예제에서는 동일한 Oracle 데이터베이스를 가정합니다.

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);

원본 데이터베이스에서 모든 열은 보완적으로 기록됩니다.

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

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));

MAP 문 설명

오류 처리

예외 테이블에 대한 오류 처리 예는 오류 처리를 위해 Oracle GoldenGate 매개변수 파일 구성을 참조하십시오.

표 16 USEDELTA, USEMAX 및 IGNORE를 사용한 UPDATEROWEXISTS

이미지 SQL 설명
트레일의 이전 이미지
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는 USEMAX 해상도에 대한 해상도 열의 이전 이미지입니다.

salary=100 및 balance=100는 USEDELTA 해상도의 이전 이미지입니다.

추적에서 이미지 뒤
phone='222222' address='Holly' salary=200 comment='new' last_mod_time='9/1/10 5:00'

last_mod_time='9/1/10 5:00는 USEMAX에 대한 분석 열의 뒤쪽 이미지입니다. 이후 이미지가 있으므로 해상도를 결정하는 데 사용됩니다.

salary=200는 USEDELTA 해상도에 사용할 수 있는 유일한 이후 이미지입니다. balance의 경우 이전 이미지가 계산에 사용됩니다.

대상 데이터베이스 이미지
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는 추적의 해결 열 값이 USEMAX에 대해 비교되는 대상의 해결 열의 현재 이미지입니다.

salary=600 및 balance=600는 USEDELTA에 대한 대상 열의 현재 이미지입니다.

충돌을 감지하는 Replicat가 적용한 초기 UPDATE

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'
이 SQL은 address, salary, balance 및 last_mod_time 열에 대한 값이 다르기 때문에 데이터를 찾을 수 없는 오류를 반환합니다.
USEDELTA를 사용하여 salary에 대한 충돌을 해결하기 위해 Replicat에서 적용한 UPDATE입니다.

SQL 바인드 변수는 다음과 같습니다.

1)200 2)100 3)'Mary'
salary의 경우 100의 차이가 있지만 balance에 대한 값이 변경되지 않았으므로 SQL 업데이트에 필요하지 않습니다. USEDELTA에 따라 추적에서 salary의 이후(200) 이미지와 이전 이미지(100) 간의 차이(델타)가 대상(600)의 현재 값 salary에 추가됩니다. 결과는 700입니다.
USEMAX에 대한 충돌을 해결하기 위해 Replicat에서 적용한 UPDATE입니다.

SQL 바인드 변수는 다음과 같습니다.

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

추적 레코드에서 last_mod_time의 이후 값이 데이터베이스의 현재 값보다 크므로 해당 열과 address 열은 추적 레코드의 이후 값으로 업데이트됩니다.

salary 열은 USEDELTA 해상도의 UPDATE로 분석되므로 여기서 설정되지 않습니다.

IGNORE에 대해 Replicat에서 적용한 UPDATE입니다.

SQL 바인드 변수는 다음과 같습니다.

1)'222222' 2)'new' 3)'Mary'
IGNORE는 DEFAULT 열 그룹(phone 및 comment)에 대해 지정되므로 분석 SQL이 적용되지 않습니다.

오류 처리를 위해 Oracle GoldenGate 매개변수 파일 구성

수동 CDR은 해결된 오류 및 CDR에서 해결할 수 없는 오류를 캡처하기 위해 오류 처리와 함께 사용해야 합니다.

  1. 충돌 해결은 HANDLECOLLSIONS, INSERTMISSINGUPDATES 및 REPERROR 등의 다른 오류 처리 매개변수보다 먼저 수행됩니다. REPERROR 매개변수를 사용하여 CDR로 해결할 수 없는 오류 또는 CDR을 통해 처리하지 않으려는 오류 처리 규칙을 지정합니다. REPERROR가 일부 오류를 처리하고 CDR이 다른 오류를 처리하는 것이 적절할 수 있지만, REPERROR 및 CDR이 동일한 충돌을 처리하도록 구성된 경우 CDR이 우선합니다. INSERTMISSINGUPDATES 및 HANDLECOLLISIONS 매개변수를 사용하여 CDR에서 처리되지 않은 일부 오류를 처리할 수도 있습니다. 이러한 매개변수에 대한 자세한 내용은 Oracle GoldenGate에 대한 매개변수 및 함수 참조를 참조하십시오.

  2. (선택 사항) 예외 테이블을 만듭니다. 예외 테이블이 예외 MAP 상태와 함께 사용되는 경우 Replicat는 충돌을 생성하는 모든 작업(해결 여부)을 예외 테이블에 매핑할 예외 MAP 문으로 전송합니다. Replicat가 UPDATE 및 DELETE 충돌을 처리하는 경우 이 테이블에서 기본 키를 생략합니다. 그렇지 않으면 무결성 제약 조건 오류가 발생할 수 있습니다.

    최소한 예외 테이블은 대상 테이블과 동일한 열을 포함해야 합니다. 이러한 행에는 Replicat가 대상에 적용하거나 적용하려고 시도한 각 행 이미지가 포함됩니다.

    또한 추가 열을 정의하여 데이터를 트랜잭션 컨텍스트에 저장하는 데 도움이 되는 기타 정보를 캡처할 수 있습니다. Oracle GoldenGate는 예외 MAP 문을 통해 이 정보를 캡처하는 툴을 제공합니다. 이러한 열은 다음과 같을 수 있지만 이에 국한되지는 않습니다.

    • 추적 레코드의 이전 이미지입니다. 이는 col1_before, col2_before 등과 같은 이름을 가진 대상 열의 중복 집합입니다.

    • 대상 열의 현재 값입니다. 또한 col1_current, col2_current 등과 같은 이름을 가진 대상 열의 중복 집합입니다.

    • 대상 테이블의 이름입니다.

    • 충돌 시간 기록

    • 작업 유형

    • 데이터베이스 오류 번호

    • (선택 사항) 데이터베이스 오류 메시지

    • 충돌이 해결되었는지 여부

  3. 예외 데이터를 예외 테이블에 매핑하는 예외 MAP 문을 생성합니다. 예외 MAP 문은 다음을 포함합니다.

    • (필수) INSERTALLRECORDS 옵션. 이 매개변수는 모든 열 값이 예외 테이블에 매핑되도록 매핑된 모든 작업을 INSERT으로 변환합니다.

    • (필수) EXCEPTIONSONLY 옵션. 이 매개변수로 인해 Replicat는 오류를 생성하는 작업을 매핑하지만 성공한 작업은 매핑하지 않습니다.

    • (선택 사항) COLMAP 절입니다. 예외 테이블에 있는 열의 이름과 정의가 소스 테이블의 열과 동일하고 예외 테이블에 해당 열만 포함된 경우 COLMAP가 필요하지 않습니다. 그러나 이름이나 정의가 다르거나 추가 데이터로 채우려는 예외 테이블에 추가 열이 있는 경우 COLMAP 절을 사용하여 모든 열을 매핑합니다.

예외 테이블에 추가 데이터 매핑 도구

다음은 COLMAP 절에서 추가 열을 채우는 데 사용할 수 있는 몇 가지 도구입니다.

예외 MAP 문의 COLMAP 절에서 이러한 기능을 결합하여 자세한 예외 테이블을 채우는 방법은 예외 테이블의 추가 열을 사용한 샘플 예외 매핑을 참조하십시오.

이러한 예에 표시된 매개변수 및 열 변환 함수의 사용 및 구문은 Oracle GoldenGate에 대한 매개변수 및 함수 참조를 참조하십시오.

소스 및 대상 열만 포함된 샘플 예외 매핑

다음은 시작되는 CDR 예제에서 사용되는 소스 및 대상 테이블에 대한 오류 처리 및 간단한 예외 매핑을 보여주는 샘플 매개변수 파일입니다. 이 예제는 소스 및 대상 열을 매핑하지만 추가 열은 매핑하지 않습니다. 다음과 같은 이유로 이 예제의 예외 MAP 문에는 COLMAP 절이 필요하지 않습니다.

    -- 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
;

예외 테이블의 추가 열을 사용한 샘플 예외 매핑

다음은 시작되는 CDR 예제에서 사용되는 소스 및 대상 테이블에 대한 오류 처리 및 복잡한 예외 매핑을 보여주는 샘플 매개변수 파일입니다. 이 예제에서 예외 테이블은 소스 테이블과 동일한 행을 가지지만 컨텍스트 데이터를 캡처하기 위한 추가 열도 있습니다.

주: 이 예에서는 Replicat 매개변수 파일(예: 프로세스 이름 및 로그인 인증서)에 필요한 다른 매개변수와 지정된 데이터베이스 유형에 필요한 선택적 매개변수를 의도적으로 제외합니다. 줄바꿈을 사용하여 매개변수 명령문을 여러 줄로 분할하는 경우 각 줄의 끝에 앰퍼샌드(&)를 사용합니다.

    -- 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)
;

모든 상황에서 루틴이 예상대로 작동한다고 확신하면 예외 테이블에 기록되는 데이터의 양을 줄여 해결 루틴의 오버헤드를 줄일 수 있습니다.