문서유형ㅣ기술정보
분야ㅣ관리/환경설정
적용제품버전ㅣTibero5, Tibero6, Tibero7
문서번호ㅣTADTI158
개요
TSC 환경에서 서버에 종속되는 객체를 생성하여 사용하는 경우, 해당 종속 객체가 동기화되지 않아 발생하는 현상과 이에 대한 우회 방안을 기술합니다.
서버에 종속되는 객체의 대표적인 예로는 External Procedure(C, JAVA) 및 External Table이 있습니다.
TSC 환경에서는 공식적으로 External 객체의 사용을 권장하지 않습니다.
다만, TSC 환경에서도 서드파티 솔루션(암·복호화 등)의 사용이나 사용자가 직접 생성한 External 객체로 인해 해당 객체가 불가피하게 사용되는 경우가 있습니다.
이와 같은 환경에서 Primary 서버에서 생성된 External 객체 파일은 Standby 서버로 동기화되지 않습니다. 이로 인해 Standby 서버로 Fail-over가 발생할 경우, 해당 객체 파일을 찾을 수 없어 오류가 발생할 수 있습니다.
이러한 상황이 발생하는 경우, 기술된 내용을 참고하여 우회 방안을 적용함으로써 문제를 해결할 수 있습니다.
방법
TSC 제약조건
TSC는 Primary 노드에서 Standby 노드로 REDO 정보를 전송하고, Standby 노드에서 복구 모드로 데이터 동기화를 수행하는 구조로 동작합니다.

REDO 정보에는 서버에 종속된 객체 파일이 포함되지 않기 때문에, Standby 노드에서는 해당 파일을 동기화할 수 없습니다.
객체의 구조는 동기화 되지만 객체가 바라보는 파일은 동기화되지 않습니다.
TSC 환경에서의 자세한 제약 조건에 대해서는 온라인 매뉴얼의 TSC 제약조건 항목을 참고하시기 바랍니다.
개발자 또는 관리자가 TSC 환경에 대해 모른 상태에서 서버에 종속된 객체를 생성하여 사용하고 있다면, Primary 장애로 인해 Standby로 FAIL-OVER 수행 시 다음과 같은 오류를 확인할 수 있습니다.
-- External C Procedure의 라이브러리 파일이 Standby에 없는 경우
TBR-140004: Failed to open library ('/tibero/tibero_engine/database/external_procedure/libextproc.so') - /tibero/tibero_engine/database/external_procedure/libextproc.so: cannot open shared object file: No such file or directory.
-- External JAVA Procedure의 라이브러리 파일이 Standby에 없는 경우
TBR-150008:Invalid class name. - SimpleMath
-- External Table의 Load Data 파일이 Standby에 없는 경우
TBR-80011: Unable to open data file.
External Procedure 우회
External C Procedure
- Primary에서 C library 생성
$ mkdir -p /tibero/tibero_engine/database/external_procedure/
$ cd /tibero/tibero_engine/database/external_procedure/
$ cat extproc.c
long find_max(long x, long y)
{
if (x >= y) return x;
else return y;
}
$ cc -g -fpic -shared -o libextproc.so extproc.c
$ ls
extproc.c libextproc.so
- Primary에서 LIBRARY 객체 생성
SQL> CREATE LIBRARY extproc IS '/tibero/tibero_engine/database/external_procedure/libextproc.so'; Library 'EXTPROC' created. OWNER LIBRARY_NAME FILE_SPEC STATUS -------------------- -------------------- ---------------------------------------------------------------------- --------------- TIBERO EXTPROC /tibero/tibero_engine/database/external_procedure/libextproc.so VALID
- Primary에서 LIBRARY 객체 생성 확인
set linesize 150 col owner for a20 col library_name for a20 col file_spec for a70 col status for a15 SQL> select owner, library_name, file_spec, status from dba_libraries ; OWNER LIBRARY_NAME FILE_SPEC STATUS -------------------- -------------------- ---------------------------------------------------------------------- --------------- TIBERO EXTPROC /tibero/tibero_engine/database/external_procedure/libextproc.so VALID
-
Standby에서 LIBRARY 객체 생성 확인
객체 구조는 Standby에서 반영 됩니다.
set linesize 150 col owner for a20 col library_name for a20 col file_spec for a70 col status for a15 SQL> select owner, library_name, file_spec, status from dba_libraries ; OWNER LIBRARY_NAME FILE_SPEC STATUS -------------------- -------------------- ---------------------------------------------------------------------- --------------- TIBERO EXTPROC /tibero/tibero_engine/database/external_procedure/libextproc.so VALID
- Primary에서 C LIBRARY에 종속된 FUNCTION 객체 생성
SQL> CREATE OR REPLACE FUNCTION ext_find_max(num1 BINARY_INTEGER, num2 BINARY_INTEGER) RETURN BINARY_INTEGER AS LANGUAGE C LIBRARY extproc NAME "find_max" PARAMETERS(num1 int, num2 int); Function 'EXT_FIND_MAX' created.
- Primary에서 C LIBRARY에 종속된 FUNCTION 객체 생성 확인
set linesize 150 col owner for a20 col object_name for a20 col object_type for a15 col status for a15 SQL> select owner, object_name, object_type, status from dba_objects where object_name='EXT_FIND_MAX'; OWNER OBJECT_NAME OBJECT_TYPE STATUS -------------------- -------------------- --------------- --------------- TIBERO EXT_FIND_MAX FUNCTION VALID 1 row selected.
- Standby에서 C LIBRARY에 종속된 FUNCTION 객체 생성 확인
set linesize 150 col owner for a20 col object_name for a20 col object_type for a15 col status for a15 SQL> select owner, object_name, object_type, status from dba_objects where object_name='EXT_FIND_MAX'; OWNER OBJECT_NAME OBJECT_TYPE STATUS -------------------- -------------------- --------------- --------------- TIBERO EXT_FIND_MAX FUNCTION VALID 1 row selected.
-
Primary에서 생성된 FUNCTION 사용
정상적으로 수행되는 것을 확인 할 수 있습니다.
SQL> create table tbl(col1 nubmer, col2 number);
SQL> insert into tbl values(1, 2);
SQL> insert into tbl values(5, 3);
SQL> insert into tbl values(7, 9);
SQL> commit;
SQL> select * from tbl;
COL1 COL2
---------- ----------
1 2
5 3
7 9
3 rows selected.
SQL> select col1, col2, ext_find_max(col1, col2) as max from tbl;
COL1 COL2 MAX
---------- ---------- ----------
1 2 2
5 3 5
7 9 9
3 rows selected.
-
Standby에서 생성된 FUNCTION 사용
C LIBRARY 파일이 동기화 되지 않아 TBR-140004 에러가 발생합니다.
SQL> select * from tbl;
COL1 COL2
---------- ----------
1 2
5 3
7 9
3 rows selected.
SQL> select col1, col2, ext_find_max(col1, col2) as max from tbl;
TBR-140004: Failed to open library ('/tibero/tibero_engine/database/external_procedure/libextproc.so') - /tibero/tibero_engine/database/external_procedure/libextproc.so: cannot open shared object file: No such file or directory.
-
Standby에 서버에 종속된 C LIBRARY 파일 복사
Primary에서 C LIBRARY 파일을 Standby로 복사 합니다.
$ mkdir -p /tibero/tibero_engine/database/external_procedure $ ls /tibero/tibero_engine/database/external_procedure libextproc.so
-
Standby에서 FUNCTION 사용
C LIBRARY 파일이 Standby에도 존재하기 때문에 정상적으로 조회 됩니다.
SQL> select * from tbl;
COL1 COL2
---------- ----------
1 2
5 3
7 9
3 rows selected.
SQL> select col1, col2, ext_find_max(col1, col2) as max from tbl;
COL1 COL2 MAX
---------- ---------- ----------
1 2 2
5 3 5
7 9 9
3 rows selected.
External JAVA Procedure
TSC 환경에서 JAVA SOURCE 객체 생성 제한
싱글 환경으로 운영 중에 생성된 JAVA SOURCE 객체가 TSC로 구성 변경된 경우, 싱글 환경에서 적용된 JAVA SOURCE가 사용될 수 있습니다.
TBR-1040: Not permitted while standby database is connected.
- Primary에서 JAVA SOURCE 확인
set linesize 150
col owner for a20
col object_name for a20
col object_type for a15
col status for a15
SQL> select owner, object_name, object_type, status from dba_objects where object_name='JAVAEXTPROC';
OWNER OBJECT_NAME OBJECT_TYPE STATUS
-------------------- -------------------- --------------- ---------------
TIBERO JAVAEXTPROC JAVA VALID
1 row selected.
SQL> show param JAVA_CLASS_PATH
NAME TYPE VALUE
---------------------------------------------------------------------- -------- --------------------------------------------------------------------
JAVA_CLASS_PATH DIRNAME /tibero/tibero_engine/database/external_java/
SQL> !tree /tibero/tibero_engine/database/external_java/
/tibero/tibero_engine/database/external_java/
└── TIBERO
├── 96.error
└── SimpleMath.class
1 directory, 2 files
-
Standby에서 JAVA SOURCE 확인
JAVA LIBRARY 파일은 동기화 되지 않기 때문에 Standby에는 존재하지 않습니다.
set linesize 150 col owner for a20 col object_name for a20 col object_type for a15 col status for a15 SQL> select owner, object_name, object_type, status from dba_objects where object_name='JAVAEXTPROC'; OWNER OBJECT_NAME OBJECT_TYPE STATUS -------------------- -------------------- --------------- --------------- TIBERO JAVAEXTPROC JAVA VALID 1 row selected. SQL> show param JAVA_CLASS_PATH NAME TYPE VALUE ---------------------------------------------------------------------- -------- -------------------------------------------------------------------- JAVA_CLASS_PATH DIRNAME /tibero/tibero_engine/database/external_java/ SQL> !tree /tibero/tibero_engine/database/external_java/ /tibero/tibero_engine/database/external_java/ [error opening dir] 0 directories, 0 file
- Primary에서 FUNCTION 생성
SQL> CREATE OR REPLACE FUNCTION find_max(x PLS_INTEGER, y PLS_INTEGER)
RETURN PLS_INTEGER IS
LANGUAGE JAVA NAME 'SimpleMath.findMax(int, int) return int';
/
Function 'FIND_MAX' created.
- Primary에서 FUNCTION 생성 확인
set linesize 150 col owner for a20 col object_name for a20 col object_type for a15 col status for a15 SQL> select owner, object_name, object_type, status from dba_objects where object_name='FIND_MAX'; OWNER OBJECT_NAME OBJECT_TYPE STATUS -------------------- -------------------- --------------- --------------- TIBERO FIND_MAX FUNCTION VALID 1 row selected.
-
Standby에서 FUNCTION 생성 확인
Standby에서 객체에 대한 구조는 동기화가 됩니다.
set linesize 150 col owner for a20 col object_name for a20 col object_type for a15 col status for a15 SQL> select owner, object_name, object_type, status from dba_objects where object_name='FIND_MAX'; OWNER OBJECT_NAME OBJECT_TYPE STATUS -------------------- -------------------- --------------- --------------- TIBERO FIND_MAX FUNCTION VALID 1 row selected.
- Primary에서 FUNCTION 사용
SQL> select find_max(4,60) from dual;
FIND_MAX(4,60)
--------------
60
1 row selected.
-
Standby에서 FUNCTION 사용
External JAVA Procedure를 사용하는 경우 epa 프로세스가 기동되어 있어야 하나 Standby 노드에서는 기동되지 않습니다.
SQL> select find_max(4,60) from dual; TBR-15138: Generic I/O error: Failed to connect Java External Procedure Agent. $ ps -ef UID PID PPID C STIME TTY TIME CMD root 64 1 0 Dec17 ? 00:01:48 tbcm -CM_SID standby root 65 64 0 Dec17 ? 00:00:02 tbcm_guard -CM_SID standby tibero 382165 1 10 03:04 pts/2 00:00:00 tbsvr -t recovery -SVR_SID testdb_s tibero 382166 382165 0 03:04 pts/2 00:00:00 /tibero/tibero_engine/bin/tblistener -n 11 -t RECOVERY -SVR_SID testdb_s tibero 382172 382165 0 03:04 pts/2 00:00:00 tbsvr_MGWP -t recovery -SVR_SID testdb_s tibero 382173 382165 0 03:04 pts/2 00:00:00 tbsvr_FGWP000 -t recovery -SVR_SID testdb_s tibero 382182 382165 0 03:04 pts/2 00:00:00 tbsvr_FGWP009 -t recovery -SVR_SID testdb_s tibero 382183 382165 0 03:04 pts/2 00:00:00 tbsvr_PEWP000 -t recovery -SVR_SID testdb_s tibero 382184 382165 0 03:04 pts/2 00:00:00 tbsvr_PEWP001 -t recovery -SVR_SID testdb_s tibero 382187 382165 0 03:04 pts/2 00:00:00 tbsvr_PEWP004 -t recovery -SVR_SID testdb_s tibero 382188 382165 1 03:04 pts/2 00:00:00 tbsvr_AGNT -t recovery -SVR_SID testdb_s tibero 382189 382165 0 03:04 pts/2 00:00:00 tbsvr_DBWR -t recovery -SVR_SID testdb_s tibero 382190 382165 1 03:04 pts/2 00:00:00 tbsvr_RCWP -t recovery -SVR_SID testdb_s tibero 382191 382165 0 03:04 pts/2 00:00:00 tbsvr_SCSD -t recovery -SVR_SID testdb_s tibero 382420 363314 0 03:04 pts/2 00:00:00 ps -ef
-
Standby로 FAIL-OVER 수행
Standby로 FAIL-OVER 되면서 epa 프로세스가 기동 됩니다.
$ ps -ef UID PID PPID C STIME TTY TIME CMD root 64 1 0 Dec17 ? 00:01:48 tbcm -CM_SID standby root 65 64 0 Dec17 ? 00:00:02 tbcm_guard -CM_SID standby tibero 382780 1 21 03:05 pts/2 00:00:00 tbsvr -t failover -SVR_SID testdb_s tibero 382781 382780 0 03:05 pts/2 00:00:00 /tibero/tibero_engine/bin/tblistener -n 11 -t NORMAL -SVR_SID testdb_s tibero 382782 382780 0 03:05 pts/2 00:00:00 tbsvr_MGWP -t failover -SVR_SID testdb_s tibero 382783 382780 0 03:05 pts/2 00:00:00 tbsvr_FGWP000 -t failover -SVR_SID testdb_s tibero 382792 382780 0 03:05 pts/2 00:00:00 tbsvr_FGWP009 -t failover -SVR_SID testdb_s tibero 382793 382780 0 03:05 pts/2 00:00:00 tbsvr_PEWP000 -t failover -SVR_SID testdb_s tibero 382794 382780 0 03:05 pts/2 00:00:00 tbsvr_PEWP001 -t failover -SVR_SID testdb_s tibero 382797 382780 0 03:05 pts/2 00:00:00 tbsvr_PEWP004 -t failover -SVR_SID testdb_s tibero 382798 382780 10 03:05 pts/2 00:00:00 tbsvr_AGNT -t failover -SVR_SID testdb_s tibero 382799 382780 1 03:05 pts/2 00:00:00 tbsvr_DBWR -t failover -SVR_SID testdb_s tibero 382800 382780 5 03:05 pts/2 00:00:00 tbsvr_RCWP -t failover -SVR_SID testdb_s tibero 382801 382780 0 03:05 pts/2 00:00:00 tbsvr_SCSD -t failover -SVR_SID testdb_s tibero 382802 382780 34 03:05 pts/2 00:00:00 java -verbose:gc -Xms128m -Xmx512m -Djepa.home=/tibero/tibero_engine/client/epa/ tibero 383046 363314 0 03:05 pts/2 00:00:00 ps -ef
-
Standby에서 FUNCTION 수행
External JAVA Procedure를 수행하기 위한 epa 프로세스가 기동 되었지만, JAVA LIBRARY 파일이 동기화 되지 않아 TBR-150008 에러가 발생 합니다.
SQL> select find_max(4,60) from dual; TBR-150008:Invalid class name. - SimpleMath
-
Standby에서 JAVA CLASS 파일 복사
Primary에서 JAVA LIBRARY 파일을 복사해옵니다.
$ mkdir -p /tibero/tibero_engine/database/external_java/TIBERO $ ls /tibero/tibero_engine/database/external_java/TIBERO SimpleMath.class
-
Standby에서 FUNCTION 수행
JAVA LIBRARY 파일이 Standby에 존재하기 때문에 정상적으로 수행됩니다.
SQL> select find_max(4,60) from dual;
FIND_MAX(4,60)
--------------
60
1 row selected.
External Table
- External Table의 Load File의 경로 인식을 위해 DIRECTORY 생성
SQL> CREATE OR REPLACE DIRECTORY dir_external as '/tibero/tibero_engine/database/external';
- Primary에서 External Table용 파일 생성
$ cat /tibero/tibero_engine/database/external/data.csv 1,test1,testtest1,1000 2,test2,testtest2,2000 3,test3,testtest3,3000
- Primary 조회
set linesize 200 col name for a50 col path for a100 SQL> select name,path from dba_directories where name='DIR_EXTERNAL'; NAME PATH -------------------------------------------------- ---------------------------------------------------------------------------------------------------- DIR_EXTERNAL /tibero/tibero_engine/database/external SQL> !ls /tibero/tibero_engine/database/external data.csv
-
Standby 조회
Standby로 External Table의 Load File이 동기화 되지 않기 때문에 파일을 확인할 수 없습니다.
set linesize 200 col name for a50 col path for a100 SQL> select name,path from dba_directories where name='DIR_EXTERNAL'; NAME PATH -------------------------------------------------- ---------------------------------------------------------------------------------------------------- DIR_EXTERNAL /tibero/tibero_engine/database/external SQL> !ls /tibero/tibero_engine/database/external ls: cannot access '/tibero/tibero_engine/database/external': No such file or directory
- Primay에서 External Table 생성
create table table_external ( col1 number, col2 varchar(10), col3 varchar(10), col4 number ) organization external ( default directory dir_external access parameters( load data fields terminated by ',' (col1,col2,col3,col4) ) location( 'data.csv' ) );
- Primary에서 조회
set linesize 200 col owner for a50 col table_name for a100 SQL> select owner, table_name from dba_tables where table_name='TABLE_EXTERNAL'; OWNER TABLE_NAME -------------------------------------------------- ---------------------------------------------------------------------------------------------------- TIBERO TABLE_EXTERNAL
-
Standby에서 조회
External Table의 구조는 동기화 됩니다.
set linesize 200 col owner for a50 col table_name for a100 SQL> select owner, table_name from dba_tables where table_name='TABLE_EXTERNAL'; OWNER TABLE_NAME -------------------------------------------------- ---------------------------------------------------------------------------------------------------- TIBERO TABLE_EXTERNAL
-
Primary에서 External Table 조회
정상적으로 조회되는 것을 확인할 수 있습니다.
SQL> select * from TABLE_EXTERNAL;
COL1 COL2 COL3 COL4
---------- ---------- ---------- ----------
1 test1 testtest1 1000
2 test2 testtest2 2000
3 test3 testtest3 3000
3 rows selected.
-
Standby에서 External Table 조회
Standby로 Load File이 동기화 되지 않기 때문에 다음과 같은 오류가 발생합니다.
SQL> select * from TABLE_EXTERNAL; TBR-80011: Unable to open data file.
-
Standby로 External Table의 Load Data 파일 생성
Primary와 동일한 Load File을 생성 또는 복제 합니다.
$ mkdir /tibero/tibero_engine/database/external $ cat /tibero/tibero_engine/database/external/data.csv 1,test1,testtest1,1000 2,test2,testtest2,2000 3,test3,testtest3,3000
-
Standby에서 External Table 조회
Standby에서 Load File이 확인되어 정상적으로 수행됩니다.
SQL> select * from TABLE_EXTERNAL;
COL1 COL2 COL3 COL4
---------- ---------- ---------- ----------
1 test1 testtest1 1000
2 test2 testtest2 2000
3 test3 testtest3 3000
3 rows selected.
마무리
TSC 환경에서 External 객체를 사용하고자 한다면, External 객체의 실제 물리적 파일을 Standby 노드로 동기화를 해주어야 합니다.
고객사 환경에서 암/복호화 솔루션 (External C Procedure)를 사용하는 경우 본 문서와 같은 이슈가 발생할 수 있으며, External 객체에 사용된 파일들이 고려되지 않은 환경에서는 Standby로 FAIL-OVER 수행 시 Standby에서 정상적인 서비스를 이어갈 수 없는 상황이 발생할 수 있어, External 객체에 대한 관리가 필요합니다.