DB2 관련 테스트 작업을 하다 DB2 설치 이미지 내부를 살펴보면서 V9.7에서도 쉘을 이용하여 tsa 버전을 확인하는 법을 알게 되었다.

설치 이미지의 압축을 풀면 server/db2/운영체제/install 이라는 디렉토리가 존재한다.

하위에 db2chktsa 라는 쉘이 존재한다. 이 shell을 통해 시스템 내에 설치된 버전 및 db2 설치 이미지에 있는 버전을 확인할 수 있다.

설치된 tsa 버전 확인

명령어
#>./db2chktsa -m

결과
TSAMP_VERSION=3.2.1.1 

설치 이미지에 있는 tsa 버전 확인

명령어
#>./db2chktsa -c

결과
TSAMP_VERSION=3.2.1.1 

설치를 하지 않았는데도 설치 버전이 나온다.

M옵션은 “라이센스를 갖고 있는 시스템 내에 설치된 SA MP” 그리고 “미디어 내에 try & buy 라이센스를 갖는 SAMP” 를 확인하는 옵션으로 기술되어 있다. (설치된 것 이외에도 미디어에 있는 버전도 보여 준다는 의미인 듯.)

C옵션은 “미디어에 있는 SA MP 및 설치 사전 조건"”을 확인하는 옵션으로 기술되어 있다.

차후 HADR등등의 이중화 구성된 DB2 환경에서는 위와 같은 방법으로 버전 확인할 수 있다.

종종 이기종간의 데이터 마이그레이션을 할 때 우리는 다양한 툴들을 사용하고 있다.
물론 툴들의 기본 내부적인 구조를 보면 DB2의 Command Line을 통하여 움직이고 있으며
데이터 마이그레이션 시 기본적으로 export , load 의 방법을 많이 사용하고 있다.

일반적으로 DB2의 Federation 기법을 사용하여 데이터의 마이그레이션을 손쉽게 할 수는 있으나
때로는 까다로운 혹은 보안이 심하게 걸려있는 고객의 사이트의 경우 직접 떨궈준 SAM파일을 이용해 데이터를 loading 하는 경우도 종종 있다.

DB2에서 제공되는 export 툴의 기능은 심플하며 다양한 기능들을 가지고 있다.
여러가지 modification 옵션을 가지고 있으며 상당히 직관적이고 심플하다.

아래는 일반적으로 데이터의 컬럼 구분자를 명시하는 방법이다.
기본적으로 구분자는 (,) 쉼표로 구분되어 지며 사용자의 특이한 데이터 상황을 고려하여
아래와 같이 변형을 가할 수 있다.

db2 "export to staff.del of del modified by coldel! select * from staff"

이는 구분자를 (!) 로 하겠다는 이야기 이다.

물론 특수 문자(예를 들면 | , '',Tab) 같은 것들은 아스키 코드의 변형으로 가능하다.
아래는 Tab 구분자를 아스키코드로 변환하여 구분자를 주는 것이다.

db2 "export to staff.del of del modified by coldel0x09 select * from staff"

위와 같이 아스키 코드를 이용하여 export 는 물론 Load옵션에도 줄 수 있다.

쓰고자 하는 내용이 DB2 아키텍처에 해당될 수 도 있을 것 같은데, 고객사의 자바로 실행되는 프로시저관련 기술지원하면서 찾아본 내용들을 정리해 본다.

프로시저를 작성하게 되면 FENCED, NOT FENCED 옵션을 선언하게 된다. DB2 내에서 자체적으로 제공되는 내장(built-in) 루틴(함수, 프로시저, 패키지, 모듈)은 not fenced 옵션으로 실행이 되지만, 일반 사용자(개발자)등이 생성하는 루틴은  fenced로 선언을 한다.

함수나 프로시저에서 선언되는 fenced라는 것은 DB2 인스턴스를 생성할 때 지정하게 되는 분리사용자(fence user)와 관계가 깊다.

하나의 프로그램이 실행되는 것은 process (혹은 daemon)가 실행되어 짐을 의미하고, 이것은 다시 계정하고도 매핑이 된다. 즉 OS 상의 자원은 소유자에 의해서 할당되어 실행이 되어진다고 할 수 있겠다.

V9.5부터 DB2는 multi-thread 방식의 아키텍처로 변경되었고, 인스턴스를 기동하면 OS상에서 db2sysc(system controller)라는 프로세스가  db2 인스턴스 계정으로 실행이 된다.

이 db2sysc라는 프로세스 하위에는 (v9.1 이하에서는 프로세스로 존재했던) db2agent라는 thread가 존재한다. (이외 instance 및 db 레벨에서 실행되는 여러 프로세스들이 다 db2sysc 하위의 thread로 포함되었다)

db2agent가 하는 역할은 원격에서 접속이 되면 db2agent가 생성이 되고, 작업 요청을 db2agent가 받아서 db 내부로 던져주는 역할을 한다. db 내에서 응답을 주면 원격에 다시 그 결과를 통보해 주는 통로 역할을 한다. (어찌 보면  client 접속에 대해 전체적인 트랜잭션을 관리해 주는 관리자 프로세스라고 할 수 있겠다.)

db2agent로 인스턴스 계정의 소유로 자원을 받아 실행이 되며, db2sysc와도 관련을 갖고 행동하기 때문에, 작업에 대해 예외가 발생하여 db2agent 한 개가 crash가 되는 경우 db2sysc 까지 영향을 미쳐, 인스턴스가 비정상적으로 종료가 되는 상황이 발생한다.

인스턴스 계정으로 소유된 자원들이기에 하위의 프로세스, 쓰레드는 어느 하나가 문제가 발생해도 전체가 다 죽는 상황이 발생을 하게 된다.

DB2는 사용자 정의 함수(UDF)나 프로시저등의 사용자가 작성해서 사용하는 object들에 대해서는 인스턴스 소유로 실행되지 않도록 db2fmp라는 별도의 프로세스를 통해 처리되도록 설계를 하였고, 이 db2fmp 프로세스는 (db2 인스턴스를 생성할 때 필요한 분리사용자 계정) fence 계정 소유로 실행된다.

따라서, UDF나 Procedure가 들어있는 트랜잭션을 db2agent가 받게 되면 이것을 db2fmp에서 처리되도록 전달한다. db2fmp는 들어온 트랜잭션을 db쪽에 요청하여 작업 처리를 하고 결과를 db2agent에 전달하는 식으로 하여 작업 처리를 하게 된다.

DB2 V9.7 fixpack 2~3에 포함된 IBM JDK에 버그가 발생해서 자바기반의 UDF나 Procedure가 실행되면 db2fmp 프로세스가 CPU 90% 이상을 잡아 먹는 상황이 발생을 하였었다. (해결책은 IBM JDK 최신 버전을 받아 설치해서 DB2가 사용하도록 하면 된다.)

db2fmp에서 어떤 작업들이 실행되었는지는 db2pd –fmp 를 실행함으로 확인해 볼 수 있다.

명령어: db2pd –fmp

결과:

FmpPid     Bit   Flags      ActiveThrd PooledThrd ForcedThrd Active
966858     64    0x00000000 0          0          0          Yes   
 
   Active Threads:
     EduPid : 15455     ThreadId : 0     

FMP Process:
FmpPid     Bit   Flags      ActiveThrd PooledThrd ForcedThrd Active
 950308     64    0x00000003 1          0          0          Yes   
 
   Active Threads:
     EduPid : 14427     ThreadId : 2314     
        Routine ID     Timestamp
        65974          2010-11-11-17.26.19.274874

 

명령어: db2pd -fmpe pid=950308 genquery

결과:

FMP Process:
Address            FmpPid     Bit   Flags      ActiveThrd PooledThrd ForcedThrd Active IPCList
0x0780000000DDBD40 766078     64    0x00000003 5          1          0          Yes    0x0780000000E6EFC0
 
   Active Threads:
   Address            FmpPid     EduPid     ThreadId 
   0x0780000000E6D880 766078     25189      3342     
   0x0780000000DDFE00 766078     17736      3085     
   0x0780000000DDF240 766078     17479      2828     
   0x0780000000DDD500 766078     16708      2571     
   0x0780000000DDC7C0 766078     16451      2314     
 

WITH RTNHIST ( PID, TID, RTNID, RTNTIME) AS
( VALUES   ( 766078    , 3599      , 65960     , TIMESTAMP('2010-11-12-01.03.33.056630')),
           ( 766078    , 3342      , 65960     , TIMESTAMP('2010-11-12-01.02.33.762402')),
           ( 766078    , 3085      , 65974     , TIMESTAMP('2010-11-12-01.01.59.036435')),
           ( 766078    , 2828      , 67495     , TIMESTAMP('2010-11-12-01.01.58.972998')),
           ( 766078    , 2571      , 65974     , TIMESTAMP('2010-11-12-01.01.54.017851')),
           ( 766078    , 2314      , 67495     , TIMESTAMP('2010-11-12-01.01.51.854489')),
           ( 766078    , 3856      , 65960     , TIMESTAMP('2010-11-12-01.03.33.057850'))
)
SELECT R.PID, R.TID, R.RTNTIME, ROUTINESCHEMA, ROUTINENAME, SPECIFICNAME, ROUTINEID
FROM syscat.routines, RTNHIST as R
where ROUTINEID = R.RTNID
ORDER BY R.PID, R.TID, R.RTNTIME

특정 PID에 대해 어떤 SQL이 실행되었는지를 위와 같은 명령어를 통해서 확인할 수 있다.

만일 특정 루틴이 이런 문제를 발생했다면, 위와 같은 방식으로 찾아 낼 수 있지 않을까 하는 생각을 한다.

정보센터에도 자세한 내용은 나오지 않지만 flags에 대해서는 자세히 기술해 놓았다.

참고 문서: http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/index.jsp

 

이외 자바 프로시저 관련해서 발생하는 오류에 대해 잘 정리가 된 문서가 있어 소개해 본다.

(자바 프로시저를 생성하고, 실행해볼 수 있도록 설명이 되었기에 자바 프로시저에 대한 기능 테스트 하기 편할 것 같다.)

참고 문서: http://www.ibm.com/developerworks/data/library/techarticle/dm-0510law/

+ Recent posts