CYFILE

CYFILE

CYFILE은 Change Data Capture (CDC) 방식을 사용하여 변경되는 데이터를 Comma-Separated Values (CSV) 형식의 파일로 저장해주는 툴이다.

개요

실시간으로 redo log file을 분석하여 데이터베이스에서 수행되는 transaction을 CSV 형식의 파일로 저장한다. Async 방식으로 near real time으로 기록되는 transaction 파일을 3rd party tool을 사용하여 데이터베이스로 이중화하거나 다른 형식으로 변환할 수 있다.

운영상 특징

운영 시 제약사항

사용자 실수를 방지하기 위해 DISABLE_DDL_CDC_GIVEUP 서버 프로퍼티를 사용하여 이중화 give up을 유발하는 DDL을 수행하지 못하도록 제어할 수 있다. 또한, 서버 프로퍼티를 DISABLE_UPDATE_PK_CDC_GIVEUP사용하여 primary key의 갱신을 비활성화 할 수 있다.

기타

다음 시점에 파일이 저장된다.

준비사항

GOLDILOCKS 준비사항과 사용자 등록 및 권한 설정을 수행해야 한다.

GOLDILOCKS 준비사항

CYFILE를 시작하기 전에 GOLDILOCKS에는 다음과 같은 사항이 설정되어 있어야 한다.

SUPPLEMENTAL LOGGING

SUPPLEMENTAL LOGGING은 redo log file에 부가 정보를 함께 저장한다. 이미 운영 중인 데이터베이스의 해당 설정을 변경하려면 데이터베이스를 다시 시작해야 하는데 특정 테이블에만 SUPPLEMENTAL LOGGING을 설정할 경우에는 데이터베이스를 다시 시작할 필요가 없다.

데이터베이스에 SUPPLEMENTAL LOGGING 설정

이중화에 참여하는 특정 Table에 SUPPLEMENTAL LOGGING 설정

<add table supplemental log statement> ::=
    ALTER TABLE table_name 
        ADD SUPPLEMENTAL LOG DATA ( PRIMARY KEY ) COLUMNS
    ;

ARCHIVE LOG

GOLDILOCKS는 redo log file을 순환하며 재사용한다. 만약 CYFILE이 처리 중인 redo log file을 GOLDILOCKS가 재사용하면 CYFILE은 더 이상 진행되지 못하고 종료된다. 이런 이중화가 지속적으로 운영되도록 보장하려면 반드시 GOLDILOCKS를 ARCHIVE LOG 모드로 운영해야 한다.

운영 중인 데이터베이스를 ARCHIVE LOG 모드로 변경

gSQL> \startup mount

Startup success

gSQL> alter database archivelog;

Database altered.

데이터베이스 생성 시 ARCHIVE LOG 모드 설정

ARCHIVE LOG 파일이 저장되는 경로는 'ARCHIVELOG_DIR'로 확인하고 변경할 수 있다.

DATA_STORE_MODE

CYFILE은 GOLDILOCKS의 redo log file을 읽어서 이중화를 수행한다. 따라서 GOLDILOCKS는 Transactional Data Store (TDS) 모드로 동작해야 한다.

DATA_STORE_MODE 변경

DATA_STORE_MODE 값이 1일 경우 Concurrent Data Store (CDS)를 의미하고, 2일 경우에는 Transactional Data Store (TDS)를 의미한다.

사용자 등록 및 권한 설정

CYFILE은 운영 중에 필요한 정보를 검색하고 조작한다. 따라서 CYFILE을 운영하는 사용자가 있어야 하고 해당 사용자에게 특정 권한을 설정해 주어야 한다.

데이터베이스 User 생성

CYFILE을 운영하려면 특정 사용자를 추가해야 한다.

<user definition> ::=
    CREATE USER user_identifier IDENTIFIED BY password
    [ DEFAULT TABLESPACE tablespace_name ]
    [ TEMPORARY TABLESPACE tablespace_name ]
    [ INDEX TABLESPACE {tablespace_name|NULL} ]
    [ <schema clause> ]
    ;

<schema clause> ::=
      WITH SCHEMA [schema_name]
    | WITHOUT SCHEMA

다음은 이름이 cyfile_user이고 password가 cyfile_password인 사용자를 추가하는 예이다.

gSQL> CREATE USER cyfile_user IDENTIFIED BY cyfile_password;

데이터베이스 권한

사용자 접속 권한 설정

다음은 cyfile_user에게 접속 권한을 부여하는 예이다.

gSQL> GRANT CREATE SESSION ON DATABASE TO cyfile_user;

환경설정

환경설정 파일

CYFILE을 실행할 때 환경 설정 파일을 사용하여 운영에 필요한 정보와 옵션을 설정할 수 있다.

설정 내용

이름

설명

DSN

Data Source Name을 설정한다.

GROUP_NAME

그룹 이름을 설정한다.

HOST_IP

GOLDILOCKS가 운영 중인 host IP address를 설정한다.

HOST_PORT

GOLDILOCKS가 운영 중인 host port를 설정한다.

USER_ID

사용자 이름을 설정한다.

USER_PW

사용자 비밀번호를 설정한다.

USER_ENCRYPT_PW

암호화 된 사용자 비밀번호를 설정한다.

CAPTURE_TABLE

이중화할 테이블을 설정한다.

PROTOCOL

GOLDILOCKS에 연결하는 connection type을 설정한다. (D/A or TCP)

READ_LOG_BLOCK_COUNT

CAPTURE가 동작할 때 한 번에 읽어들일 데이터의 양을 설정한다.

TRANS_SORT_AREA_SIZE

CAPTURE에 할당될 BUFFER의 크기를 설정한다.

TRANS_FILE_PATH

CAPTURE 할 때 임시로 생성되는 file이 저장될 위치를 설정한다.

LOG_CAPTURE_INTERVAL_1

Capture 수행 주기를 설정한다. 해당 값으로 10 회 수행한 후에 변경 사항이 없을 경우에는 LOG_CAPTURE_INTERVAL_2의 값으로 전환되어 capture를 수행한다. (기본값은 0.2 초이다.)

LOG_CAPTURE_INTERVAL_2

Capture 수행 주기를 설정한다. LOG_CAPTURE_INTERVAL_1의 값으로 수행한 후에 변경 사항이 없을 경우 capture 수행 주기를 설정한다. (기본값은 1 초이다.)

DATA_FILE_PATH

CSV 파일이 저장될 경로를 설정한다. (절대 경로여야 한다.)

DATA_FILE_PREFIX

CSV 파일 이름의 접두어를 설정한다.

DATA_FILE_SIZE

CSV 파일의 최대 사이즈를 설정한다. (대략적인 사이즈이며 반드시 설정된 값으로 저장되는 것은 아니다.)

UPDATE_BEFORE_VALUE

Update SQL을 처리할 때 update 되기 전의 값을 CSV로 저장할지 여부를 결정한다. (기본값은 0 이다.)

환경설정 옵션

DSN

• 모든 그룹에 적용되는 설정

DSN=GOLDILOCKS

• 특정 그룹에 적용되는 설정

GROUP_NAME = testGROUP
{
    DSN=GOLDILOCKS
    ....
    ....
}

GROUP_NAME

GROUP_NAME = testGROUP
{
    ....
    ....
}

HOST_IP

• 모든 그룹에 적용되는 설정

HOST_IP = 127.0.0.1

• 특정 그룹에 적용되는 설정

GROUP_NAME = testGROUP
{
    HOST_IP = 127.0.0.1
    ....
    ....
}

HOST_PORT

• 모든 그룹에 적용되는 설정

HOST_PORT = 22531

• 특정 그룹에 적용되는 설정

GROUP_NAME = testGROUP
{
    HOST_PORT = 22531
    ....
    ....
}

USER_ID

GOLDILOCKS 접속에 필요한 사용자 ID를 설정한다.

• 모든 그룹에 적용되는 설정

USER_ID = testID

• 특정 그룹에 적용되는 설정

GROUP_NAME = testGROUP
{
    USER_ID = testID
    ....
    ....
}

USER_PW

GOLDILOCKS 접속에 필요한 사용자 비밀번호를 설정한다.

• 모든 그룹에 적용되는 설정

USER_PW = testPW

• 특정 그룹에 적용되는 설정

GROUP_NAME = testGROUP
{
    USER_PW = testPW
    ....
    ....
}

USER_ENCRYPT_PW

• 모든 그룹에 적용되는 설정

USER_ENCRYPT_PW = 't33KImiqvhqNyfN+uZmFrw=='

• 특정 그룹에 적용되는 설정

GROUP_NAME = testGROUP
{
    USER_ENCRYPT_PW = 't33KImiqvhqNyfN+uZmFrw=='
    ....
    ....
}

CAPTURE_TABLE

GROUP_NAME = testGROUP
{
    CAPTURE_TABLE = 
    (
        testSchema1.testTable1,
        testSchema1.testTable2,
        testSchema2.testTable1
    )
}

PROTOCOL

• 모든 그룹에 적용되는 설정

PROTOCOL = DA

• 특정 그룹에 적용되는 설정

GROUP_NAME = testGROUP
{
    PROTOCOL = DA
    ....
    ....
}

READ_LOG_BLOCK_COUNT

• 모든 그룹에 적용되는 설정

READ_LOG_BLOCK_COUNT = 1024

• 특정 그룹에 적용되는 설정

GROUP_NAME = testGROUP
{
    READ_LOG_BLOCK_COUNT = 1024
    ....
    ....
}

TRANS_SORT_AREA_SIZE

• 모든 그룹에 적용되는 설정

TRANS_SORT_AREA_SIZE = 300

• 특정 그룹에 적용되는 설정

GROUP_NAME = testGROUP
{
    TRANS_SORT_AREA_SIZE = 300
    ....
    ....
}

TRANS_FILE_PATH

• 모든 그룹에 적용되는 설정

TRANS_FILE_PATH = '/data/TmpTrans'

• 특정 그룹에 적용되는 설정

GROUP_NAME = testGROUP
{
    TRANS_FILE_PATH = '/data/TmpTrans'
    ....
    ....
}

LOG_CAPTURE_INTERVAL_1

• 모든 그룹에 적용되는 설정

LOG_CAPTURE_INTERVAL_1 = 200

• 특정 그룹에 적용되는 설정

GROUP_NAME = testGROUP
{
    LOG_CAPTURE_INTERVAL_1 = 200
    ....
    ....
}

LOG_CAPTURE_INTERVAL_2

• 모든 그룹에 적용되는 설정

LOG_CAPTURE_INTERVAL_2 = 1000

• 특정 그룹에 적용되는 설정

GROUP_NAME = testGROUP
{
    LOG_CAPTURE_INTERVAL_2 = 1000
    ....
    ....
}

DATA_FILE_PATH

• 모든 그룹에 적용되는 설정

DATA_FILE_PATH = '/home/goldilocks/dat'

• 특정 그룹에 적용되는 설정

GROUP_NAME = testGROUP
{
    DATA_FILE_PATH = '/home/goldilocks/dat'
    ....
    ....
}

DATA_FILE_PREFIX

• 모든 그룹에 적용되는 설정

DATA_FILE_PREFIX = 'SET_PREFIX'

• 특정 그룹에 적용되는 설정

GROUP_NAME = testGROUP
{
    DATA_FILE_PREFIX = 'SET_PREFIX'
    ....
    ....
}

DATA_FILE_SIZE

• 모든 그룹에 적용되는 설정

DATA_FILE_SIZE = 200

• 특정 그룹에 적용되는 설정

GROUP_NAME = testGROUP
{
    DATA_FILE_SIZE = 200
    ....
    ....
}

UPDATE_BEFORE_VALUE

• 모든 그룹에 적용되는 설정

UPDATE_BEFORE_VALUE = 1

• 특정 그룹에 적용되는 설정

GROUP_NAME = testGROUP
{
    UPDATE_BEFORE_VALUE = 1
    ....
    ....
}

운영하기

CYFILE은 GOLDILOCKS의 D/A 또는 C/S 환경에서 운영할 수 있다.
운영 환경에 따라 다음과 같이 CONFIG 파일 또는 ODBC.INI의 PROTOCOL 설정을 사용해야 한다.
CONFIG 설정은 ODBC.INI 설정보다 우선한다.
CONFIG, ODBC.INI 구분

설정

구분

PROTOCOL=DA

D/A 환경에서 사용된다. (Default)

PROTOCOL=TCP

C/S 환경에서 사용된다.

운영 중에 수행되는 내용은 trace log를 통해 볼 수 있다.

구분

파일

Cyfile

$GOLDILOCKS_DATA/trc/cyfile_(groupName).trc

실행 옵션

CYFILE을 실행할 때는 다음의 옵션과 함께 사용해야 한다.

실행 옵션

옵션

설명

비고

--start | -s

CYFILE을 실행한다.

-

--stop | -t

CYFILE을 종료한다.

-

--status | -u

CYFILE의 상태를 출력한다.

-

--conf | -c

CYFILE을 실행할 때 필요한 환경파일의

경로를 설정한다.

--conf CONFIG_FILE 형식으로 입력한다.

--start와 함께 사용해야 한다.

명시적으로 설정하지 않을 경우,

$GOLDILOCKS_DATA/conf/cyfile.conf를 사용한다.

--silent | -i

메시지를 출력하지 않도록 한다.

-

--reset | -r

Capture 정보를 초기화한다.

--reset TABLE_NAME 또는 --reset all 형식으로 입력한다.

여러 개의 table을 reset할 경우에는 single quote (') 안에 기술한다.

--group | -g

특정 그룹을 설정한다.

--group GROUP_NAME 형식으로 입력한다.

--help | -h

도움말을 출력한다.

-

--encrypt | -e

주어진 key로 사용자 비밀번호를 암호화한다.

-

--key | -k

--encrypt 옵션을 사용할 때 암호화 key를 설정한다.

config에 USER_ENCRYPT_PW가 사용된 경우에는 복호화 key를 설정한다.

-

--info | -o

현재 운영되고 있는 테이블 상태를 보여준다.

--group과 함께 사용해야 한다.

prompt> cyfile --start
prompt> cyfile --stop
prompt> cyfile --start --group TEST_GROUP
prompt> cyfile --stop --group TEST_GROUP
prompt> cyfile --encrypt test --key 1234
Cyfile Encrypted Passwd : '73LsLxss6lk='
prompt> cyfile --start --key 1234
prompt> cyfile --start --reset all
prompt> cyfile --start --reset 'T1, T2'
prompt> cyfile --info --group GROUP1

================================================
 GROUP NAME = GROUP1
================================================
 SCHEMA NAME         : PUBLIC
 TABLE NAME          : TEST_TABLE_02 (ACTIVE (CAPTURE-START-LSN:217368))
 PHYSICAL ID         : 36313948487680
 STATUS              : ONLINE
================================================
 SCHEMA NAME         : PUBLIC
 TABLE NAME          : TEST_TABLE_01 (ACTIVE (CAPTURE-START-LSN:217602))
 PHYSICAL ID         : 36322538422272
 STATUS              : ONLINE
================================================
   TOTAL   COUNT : 2
   GIVE-UP COUNT : 0
   NODE          : TRUST
================================================

Files

CYFILE은 insert/ update/ delete 및 capture 테이블 정보를 CSV 형식으로 저장한다. Async 방식을 사용하지만 near real-time으로 동작한다.
CYFILE을 운영할 때 저장되는 파일의 종류는 두 가지인데 CSV 형식으로 transaction을 저장하는 데이터 파일과 데이터 파일의 저장 정보를 가지고 있는 컨트롤 파일이다. 컨트롤 파일은 데이터 손실이나 삭제에 대비하여 미러 파일을 하나 더 만들어 운영한다.
CYFILE 파일 종류

파일 구분

이름 정보

Data file

CSV 형식으로 저장되며, 확장자는 dat 이다.

Control file

확장자는 ctl 이다.

미러 파일의 확장자는 ctl_0 이다.

Data File

CSV 형식의 transaction 단위로 수행되는 I/D/U 정보 및 capture에 참여하는 테이블의 column 정보, give up 테이블 정보 등을 지속적으로 기록한다. 또한 해당 파일은 사용자가 삭제하지 않는 한 자동으로 삭제되지 않는다.

파일 이름

저장되는 파일은 DATA_FILE_PREFIX, DATA_FILE_PATH 등에 의해 위치와 이름이 결정된다. 확장자 이름은 .dat 이며, 다음 규칙에 따라 생성된다.

데이터 파일의 사이즈가 DATA_FILE_SIZE보다 커져서 새로운 파일이 생성될 경우, FILE_SEQUENCE +1 한 값으로 결정된다.

운영이 시작된 이후에는 DATA_FILE_PATH, DATA_FILE_PREFIX를 바꾸면 안된다.

INSERT의 저장 형식

INSERT 표현식

INSERT 표현식

Query: INSERT INTO PUBLIC.TEST(C1, C2, C3) VALUES( 1, 2, 'ABC' );
CSV 저장: T, I, "PUBLIC", "TEST", "C1", "1", "C2", "2", "C3", "ABC"
Query: INSERT INTO PUBLIC.TEST(C1, C3) VALUES( 1, 'ABC' );
CSV 저장: T, I, "PUBLIC", "TEST", "C1", "1", "C2", NULL, "C3", "ABC"

DELETE의 저장 형식

DELETE 표현식

DELETE 표현식

Sample: Primary key가 한 개인 경우
Query: DELETE FROM PUBLIC.TEST WHERE C1=1;
CSV 저장: T, D, "PUBLIC", "TEST", 1, "C1", "1"
Sample: Primary key가 두 개인 경우
Query: DELETE FROM PUBLIC.TEST WHERE C1=1 AND C2=2;
CSV 저장: T, D, "PUBLIC", "TEST", 2, "C1", "1", "C2", "2"

UPDATE의 저장 형식

UPDATE 표현식

UPDATE 표현식

Sample: Primary key가 C1 한 개인 레코드의 C2 값을 1에서 2로 변경
Query: UPDATE PUBLIC.TEST SET C2=2 WHERE C1=1;

* UPDATE_BEFORE_VALUE가 설정되지 않았을 경우
CSV 저장: T, U, "PUBLIC", "TEST", 1, "C1", "1", "C2", "2"

* UPDATE_BEFORE_VALUE가 설정되어 있을 경우
CSV 저장: T, U, "PUBLIC", "TEST", 1, "C1", "1", "C2", "1", "2"
Sample: Primary key가 C1, C2 두 개인 레코드의 C3 값을 'ABC'에서 'BCD'로 C4 값을 3에서 4로 변경
Query: UPDATE PUBLIC.TEST SET C3='BCD', C4=4 WHERE C1=1 AND C2=2;

* UPDATE_BEFORE_VALUE가 설정되지 않았을 경우
CSV 저장: T, U, "PUBLIC", "TEST", 2, "C1", "1", "C2", "2", "C3", "BCD", "C4", "4"

* UPDATE_BEFORE_VALUE가 설정되어 있을 경우
CSV 저장: T, U, "PUBLIC", "TEST", 2, "C1", "1", "C2", "2", "C3", "ABC", "BCD", "C4", "3", "4"

Transaction 정보

Transaction begin 표현식

Transaction begin 표현식

Transaction commit 표현식

Transaction commit 표현식

Table 정보

Table 표현식

Table 표현식

COLUMN 표현식

COLUMN 표현식

I,T,"PUBLIC","TEST",3,1
I,C,"C1","NUMBER(10,0)",1,0,0
I,C,"C2","VARCHAR(20)",0,0,1
I,C,"C3","VARCHAR(10)",0,0,1
I,T,"PUBLIC","TEST2",2,1
I,C,"C1","NUMBER(10,0)",1,0,0
I,C,"C2","VARCHAR(20)",0,0,1

Meta 정보

Version 표현식

Version 표현식

날짜정보 표현식

날짜정보 표현식

컨트롤 파일 정보 표현식

컨트롤 파일 정보 표현식

I,V, 00000000
I,D,"2022-12-24 00:01:00.000000"
I,M,"/home/cyfile/ctrl_file/cyfile.GROUP1.ctl"

Command 정보

EOF 표현식

EOF 표현식

Control File

typedef struct ctrlFileStr
{
    char           mVersion[8];
    unsigned int   mFileInfoCrc;   //mFileSeq + mFileOffset CRC
    unsigned int   mDummy;         //Not Used.
   
    signed long    mFileSeq;
    signed long    mFileOffset;    //Valid Offset
};