문의가 와서 Oracle 10g에서 제공되기 시작한 model dimension by 에 대해 살펴보게 되었다.

DB2의 오라클 호환성이 어지간한 신택스는 다 지원된다고 생각하고 있었는데, 이런 엑셀스러운 신택스도 있는 것을 알게 된 것 같다.

 

처음보는 기능이기에 어떤 방식으로 처리되는지를 알고자 웹 검색을 해보니 “증분 누적?”(바로 전 값을 계속 누적 연산) 처리 로직정도로 이해가 되었다.

 

(참고) http://www.gurubee.net/lecture/2203

 

어떤 문서에는 common table (with 문을 통한 recursive 처리) 로의 변환이 되지 않게 쓰인 문서들도 있었는데 위의 참조된 웹 문서를 기준으로 db2 방식으로 변환을 해 보았다.

 

[예제1] 증분 누적

 

입력 값 및 결과

MM

AMT

결과 값

1

-2000

0

2

4000

4000

3

-5000

0

4

-2000

0

5

3000

3000

6

1500

4500

7

-250

4250

8

320

4570

9

-4000

570

10

10000

10570

11

-20000

0

 

변환 SQL

with

   t1(mm,amt) as

     (select * from

              (values(1,-2000),(2,4000),(3,-5000),(4,-2000),(5,3000),(6,1500),(7,-250),(8,320),(9,-4000),(10,10000),(11,-20000)) t(mm,amt)),


   tmp(c1,c2,c3) as
    (select mm, greatest(0,amt), amt from t1 where mm=1
        union all
     select c1+1,
            (select greatest(0,c2+amt) from t1 where mm=c1+1),
            (select amt from t1 where mm=c1+1)
     from tmp where c1 < (select max(mm) from t1)
    )


select c1,c3 amt, c2 result from tmp ;

 

[예제2] 행 분할 누적

 

입력값

M

AMT

1

100

5

200

6

100

9

300

 

결과

M

결과

1

100

2

100

3

100

4

100

5

200

6

100

7

100

8

100

9

300

10

300

11

300

12

300

 

변환 SQL

with
  t1(mm,amt) as

     (select * from (values(1,100),(5,200),(6,100),(9,300)) t(mm,amt)) ,


  tmp (c1,c2,c3) as
   (select t1.mm, t1.amt, t1.amt from t1 where t1.mm=1
    union all
    select c1+1,
           case when (select amt from t1 where c1+1 = mm) is null then c2
                else (select amt from t1 where c1+1 = mm) end ,
           (select amt from t1 where c1+1 = mm)
    from  tmp
    where c1 < 12 
    )


select c1, c2 from tmp
order by c1
;

 

SQL의 복잡성에 따라서 어떤 경우에는 위처럼 변환되지 않는 경우가 있을 수도 있겠다.

 

개인적으로 SQL 표현을 간소하게 하여 SQL 문을 단순화하고 직관적으로 볼 수 있는 것을 좋아하기에 SQL에 대해서는 Oracle SQL 철학을 좋아한다. (+, connect by 등)

표준 SQL을 준수하는 DB2에서는 이런 부분을 장문의 SQL로 표현을 해야 되는 번거로움을 느끼지만 common table의 미학을 느껴볼 수 있는 계기가 된 것 같다.

'Note' 카테고리의 다른 글

[관리] 메모리 부족  (0) 2014.11.21
[보안] authentication 과 srvcon_auth  (0) 2014.07.14
[보안] SSL 설정  (0) 2014.06.18
[관리] db2gcf  (0) 2014.05.19
[복구] 경로재지정 복구  (0) 2014.04.15

고객사 요청으로 기술지원을 갔다가 데이터 복구 작업을 해야 되는 경우가 있었다.

특정 테이블의 데이터 복구 작업 시 업무 영향도를 최소화하기 위해서 개발 시스템에 운영DB의 백업 이미지를 경로재지정 복구를 수행하여 필요한 데이터를 추출하는 방법으로 작업을 진행하였다.

 

문제는 개발서버의 자원이 운영시스템만큼 풍족하지 못하고, 이미 개발DB가 존재하기 때문에 복구 중 rollforward 작업이 진행되지 못하게 되었다.

rollforward를 수행하면서 내부적으로 DB가 활성화되는 것 같은데, 개발서버의 물리적 메모리의 가용량이 DB가 필요로 하는 메모리 크기가 되지 못해서 생긴 것 같다.  마치 대저택에서 살던 사람이 사업이 망해 단칸방으로 세간살이를 옮겨야 되는 경우와 비슷한..

 

인스턴스 메모리 및 DB 메모리를 변경해도 이 문제는 해결되지 않았다. STMM이 수행되어도 DB내 설정된 버퍼풀의 크기를 충족하지 못해 DB가 활성화되지 못하는..

 

해결 방안을 얻고자 자료들을 찾아보니, Registry 변수에서 버퍼풀 크기를 강제로 제어하는 변수를 알게 되었다.

DB2_OVERRIDE_BPF=버퍼풀ID,페이지수;버퍼풀ID,페이지수

 

운영DB를 통해서 가장 큰 (페이지수가 많은) 버퍼풀ID와 페이지 수를 확인을 하고 크기를 줄여나갔다.

 

이 변수를 적용하고 나서 rollforward 작업 진행되어 데이터 복구 작업을 완료할 수 있었다.

 

이후 언젠가 블로그 글을 살펴보면서 같이 일했던 동료분이 “실수로 bufferpool 크기를 과도하게 설정한 경우 해결하는 방법”으로 글이 적혀둔걸 보게 되었다. (남의 경험이 공유되어도 직접 비슷한 경험을 하지 않는 이상 급박한 상황에서 해결안을 쉽게 찾아내긴 어려운 법 같다.)

고객사 시스템에 직접 터미널로 붙어서 작업하는 환경이 없어져서 장애관련 정보를 수집하고 메모하는 것이 어려워진다. 그저 기억속으로만 간직해야 되는

 

'Note' 카테고리의 다른 글

[SQL] model dimension by  (0) 2015.01.08
[보안] authentication 과 srvcon_auth  (0) 2014.07.14
[보안] SSL 설정  (0) 2014.06.18
[관리] db2gcf  (0) 2014.05.19
[복구] 경로재지정 복구  (0) 2014.04.15

이전에 db2 jdbc driver 버전에 대해 기술한 적이 있다.

JAVA 6 (JDK 1.6) 버전 관점에서 설명을 하고 버전 확인하는 법들을 설명했는데, Driver 버전이 4인 경우와 아닌 경우에 따른JAVA 연동 시의 문제점을 최근에 알게 되었다.

 

문제점

- JDBC 4.0 (db2jcc4.jar) 으로 DB2와 연동하는 경우 SELECT문의 “컬럼 별명"이 반영되지 않는(무시되는) 현상

 

원인

- jdbc 4.0 에서는 ResultSetMetaData.getColumnName 과 ResultSetMetaData.getColumnLabel 이 명확히 구분되어

  ResultSetMetaData.getColumnLabel 를 사용하지 않는 이상 “컬럼 명"으로 결과 값들이 반환됨

 

정리

JDBC & SQLJ getColumnName getColumnLabel
버전 4 이전 별명 반환 별명 반환
버전 4 이상 컬럼 명 반환 별명 반환

 

DB2 V9.5 정보센터를 보면 Application Developer 변경 사항에 이에 대한 언급이 설명되어 있다.

http://publib.boulder.ibm.com/infocenter/db2luw/v9r5/index.jsp?topic=%2Fcom.ibm.db2.luw.wn.doc%2Fdoc%2Fi0052606.html

 

DB2 V9.7 에서도 이에 대해 예제를 들어 설명해 놓았다. (오타가 있어 감안해서 봐야 될 것 같다)

http://pic.dhe.ibm.com/infocenter/db2luw/v9r7/index.jsp?topic=%2Fcom.ibm.db2.luw.apdv.java.doc%2Fsrc%2Ftpc%2Fimjcc_c0052593.html

 

두 버전의 호환 사용방안

(방법1) useJDBC4ColumnNameAndLabelSemantics Connection  설정

(방법2) DataSource property to DB2BaseDataSource.NO (2) 설정

고객사의 connect by 관련 지원하다 C 소스 코드를 컴파일 해보는 작업을 잠시 해 보게 되었다.

윈도우 환경에서 사용되어 C 컴파일러가 필요하여 지인을 통해 무료 컴파일러인 MinGW 다운받아 설치를 했다.

그러나 bldrtn 을 이용해서 컴파일은 되지 않았다. (cl.exe 오류)

왜 오류가 날까? bldrtn을 열어보니 기본 컴파일러로 Visual Studio C++ 를 사용하도록 BLDCOMP 변수에 박여 있었다.

즉 Visual Studio를 설치해야 bldrtn을 구동할 수 있게 셋팅되어 있던 것…

MinGW 및 기타 gcc 들을 설치해 봐야 “어떤 값"을 넣어 “기본 컴파일러" 설정해야 하는지 알 수 없기에 Trial version으로 VS를 설치하였다.

 

물론 VC++이 설치되어 있다고 bldrtn이 실행되지 않는다.

환경변수 설정이 필요하다. (내 컴퓨터 > 속성 > 고급 시스템 설정 > 고급 탭 > 환경 변수)

 

1) INCLUDE 변수에 경로 추가  (stdio.h 에러)

    C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include

2) CLASSPATH, LIB 변수에 경로 추가

    C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\lib    (msvcrt.lib 에러)

    C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib   (kernel132.lib 에러)

    SDK가 설치 되지 않은 경우 kernel132.lib 에러가 발생하므로 Visual Studio 업데이트 파일 실행 후 kernel132.lib 라이브러리 확인 필요

 

이후 bldrtn 이 정상적으로 수행되었다.

 

C:\Program Files\IBM\SQLLIB\samples\c>bldrtn connect_by
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.51106.1 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

connect_by.c
Microsoft (R) Incremental Linker Version 11.00.51106.1
Copyright (C) Microsoft Corporation.  All rights reserved.

connect_by.def(2) : warning LNK4017: DESCRIPTION statement not supported for the
target platform; ignored
   Creating library connect_by.lib and object connect_by.exp

        1개 파일이 복사되었습니다.

 

오라클의 connect by 구문은 DB2 V9.7 이상부터 지원되고 있다.

(V9.5에서도 오라클 호환성 변수가 적용되어 지원은 된다.)

 

표준 recursive SQL 인 Common table 을 이용해서는 “위계/계층"의 순서를 살릴 수가 없다.

(common 테이블 결과는 위계/계층별로 정렬되어 보여 줌)

성능 이슈가 제기되어 DB2 의 connect by의 대안으로 ibm developer works에 소개된 c로 만든 connect by였다.

(참고: http://www.ibm.com/developerworks/data/library/techarticle/dm-0510rielau/ )

 

connect by 대상 테이블에 다른 테이블이 조인되어 사용되는 경우 siblings by 처리 시 미묘하게 값 정렬이 틀려진다.

성능은 좋았지만 적용할 수가 없었다.

 

현재까지 DB2에서 제공되는 connect by 는  self join 방식에서는 성능 문제가 없지만, 다른 테이블과 join 되는 경우 성능이 많이 느려지는 느낌을 받았고, self join 이여도 siblings by 를 추가하는 경우 느려지는 느낌을 받았다.

 

다른 테이블과의 join이 발생하는 경우,  connect by 처리를 inline view(subquery)로 처리하여 되도록 self join 만 하도록 해야 성능 저하를 막을 수 있을 것으로 보인다.

Informix에서는 CLR (continuous log restore) 를 통하여 원격지 서버에 복제 서버 구성이 가능한 것으로 알고 있다.

DB2에서는 (내가 모르고 있는 것인지 모르지만) CLR에 해당하는 기능은 없어 보인다.

HADR 설정을 통하여 DB 동기화는 가능하지만, Flash Copy 및 디스크 복제 기반의 이중화 환경에서는 실시간으로 Disk 복제를 하지 않는 이상 불가능하다.

 

한번은 고객사쪽에서 아카이브 로그만 복제 서버로 옮겨서 복구를 계속 할 수 있는지를 문의해 왔다.

즉 rollforward 작업을 한번이 아닌, 여러 번 수행 가능한지 확인이 필요한 문제였다.

아카이브 로그를 원격지 복제서버에 수동으로 옮겨주어야 하는 불편함은 있지만, 이 부분은 제외를 하고 다음과 같이 테스트를 해 보았다.

 

1. 테스트 시나리오

순서

TEST(운영 서버)

TEST1 (복제서버)

1

TEST DB 생성 및 archive log 적용

2

T1 테이블 생성

3

온라인 DB full 백업

4

TEST 온라인 백업을 TEST1 이름으로 Restore

5

T1 에 값 입력(1) 후 로그 스위치

6

아카이브 로그 복사 후 rollforward

7

T1 에 값 입력(2) 후 로그 스위치

8

아카이브 로그 복사 후 rollforward

9

Rollforward 완료 및 데이터 조회

10

데이터 조회

 

2. 테스트

 

TEST(운영 서버)

TEST1 (복제서버)

1

db2 create db test on /database

db2 update db cfg for test using logarchmeth1 disk:/database/archivelog

db2 backup db test to /dev/null

2

db2 connect to test

db2 "create table t1 (c1 int, c2 timestamp)"

3

db2 backup db test online to /database/backup

4

db2 "restore db test from /database/backup into test1"

db2 "rollforward database test1 query status"

Rollforward Status

Input database alias = test

Number of members have returned status = 1

Member ID = 0

Rollforward status = DB pending

Next log file to be read = S0000001.LOG

Log files processed = -

Last committed transaction = 2013-03-20-06.18.12.000000 UTC

5

db2 "insert into t1 values (1,current timestamp)"

ls /database/archivelog/fed10/TEST/NODE0000/

LOGSTREAM0000/C0000000

S0000000.LOG S0000001.LOG S0000002.LOG S0000003.LOG

 ls /database/archivelog/fed10/TEST/NODE0000/

LOGSTREAM0000/C0000000

S0000000.LOG S0000001.LOG S0000002.LOG S0000003.LOG S0000004.LOG S0000005.LOG

 

6

cp /database/archivelog/fed10/TEST/NODE0000/

LOGSTREAM0000/C0000000/* .

db2 "rollforward db test1 to end of logs"

Rollforward Status

Input database alias = test1

Number of members have returned status = 1

Member ID = 0

Rollforward status = DB working

Next log file to be read = S0000006.LOG

Log files processed = S0000001.LOG - S0000005.LOG

Last committed transaction = 2013-03-20-06.21.14.000000 UTC

7

db2 "insert into t1 values (2,current timestamp)"

db2 archive log for db test

S0000000.LOG S0000001.LOG S0000002.LOG S0000003.LOG S0000004.LOG S0000005.LOG S0000006.LOG

8

cp TEST/NODE0000/LOGSTREAM0000/

C0000000/S0000006.LOG .

db2 "rollforward db test1 to end of logs"

Rollforward Status

Input database alias = test1

Number of members have returned status = 1

Member ID = 0

Rollforward status = DB working

Next log file to be read = S0000007.LOG

Log files processed = S0000001.LOG - S0000006.LOG

Last committed transaction = 2013-03-20-06.26.44.000000 UTC

9

db2 "rollforward db test1 complete"

Rollforward Status

Input database alias = test1

Number of members have returned status = 1

Member ID = 0

Rollforward status = not pending

Next log file to be read =

Log files processed = S0000001.LOG - S0000006.LOG

Last committed transaction = 2013-03-20-06.26.44.000000 UTC

 

db2 connect to test1

db2 "select * from t1"

C1 C2

----------- --------------------------

1 2013-03-20-15.21.14.698452

2 2013-03-20-15.26.44.622604

2 record(s) selected

10

db2 connect to test

db2 "select * from t1"

C1 C2

----------- --------------------------

1 2013-03-20-15.21.14.698452

2 2013-03-20-15.26.44.622604

2 record(s) selected

 

 

고객사 DB 데이터 암호화 작업 지원 중 진단로그에 다음과 같은 오류가 발생하였다.

 

2013-08-10-12.54.51.756152+540 I75183662C377      LEVEL: Error
PID     : 630814               TID  : 1           PROC : db2pfchr 0
FUNCTION: DB2 UDB, buffer pool services, sqlbReadAndReleaseBuffers, probe:40
RETCODE : ZRC=0x870F0009=-2029060087=SQLO_EOF "the data does not exist"
          DIA8506C Unexpected end of file was reached.

2013-08-10-12.54.51.769508+540 I75184799C441      LEVEL: Error
PID     : 630814               TID  : 1           PROC : db2pfchr 0
FUNCTION: DB2 UDB, buffer pool services, sqlbReadAndReleaseBuffers, probe:50
DATA #1 : String, 162 bytes
Obj={pool:7;obj:1033;type:0} State=x27 Parent={7;1033}, EM=340480, PP0=340608 Page=0 Cont=0 Offset=113664 BlkSize=12
sqlbReadAndReleaseBuffers error: num-pages=6

2013-08-10-12.54.51.779808+540 I75187165C356      LEVEL: Error
PID     : 630814               TID  : 1           PROC : db2pfchr 0
FUNCTION: DB2 UDB, buffer pool services, sqlbPFPrefetcherEntryPoint, probe:0
DATA #1 : String, 78 bytes
Prefetcher Error rc = -2029060087 IGNORED ... err loc 0
. Request follows...

 

원시 디바이스(raw device) 콘테이너를 암호화가 설정된 원시 디바이스로 옮긴 후 테이블 조회 시, prefetcher 에러가 진단로그에 기록이 되었다.

 

해당 문제는 원시 디바이스 환경에서 암호화 작업 시 문제가 생겼으며 암호화 솔루션의 수정(patch)를 통하여 해결되었다.

“데이터 무결성”을 확인하는 방법으로 DB2에서 제공하는 툴들이다. db2dart는 DB가 비활성화(offline)일 때 사용 가능하고, db2 inspace는 DB가 활성화된 상태에서 사용된다는 점이 사용 상 차이점일 듯 하다.

 

두 개의 툴이 사용되는 경우는 DB가 활성화되지 않는 상황이거나, 진단로그(db2diag.log)에 bad page 오류가 발생할 때 사용이 될 뿐 보통의 경우에는 사용하지 않는다. 필자의 경우도 많이 사용해 본 도구들은 아니다.

 

데이터 무결성 확인이외에도 두 개의 도구는 기능상 약간의 차이점이 있다.

(1) db2dart

    - 데이터 추출 기능

    - 테이블 공간의 고수위 마크(HWM)를 떨어뜨리는 기능

    - 유효하지 않는 색인(index) 고치기 기능

 

(2) db2 inspect

    - 압축된 테이블의 “압축으로 인한 스토리지 절감률” 확인

 

 

개인적으로는 DB가 접속되지 않는 상황에서 “테이블공간 목록과 콘테이너 정보”를 확인하고 싶었던 경우가 있다.

(경로재지정 복구를 하고자 함 이였는지, 특정 테이블공간에 대한 정보를 통하여 DB rebuild 복원을 하려고 했었던 것인지는 기억나지 않지만..)

 

이런 경우 db2dart 의 옵션 /ATSC 나 /DTSF 를 사용하면 “스토리지 그룹 정보”, “테이블 공간 정보”, “콘테이너 정보”들을 확인할 수 있다.

 

사용 예 (두 도구의 실행 결과는 db2diag.log가 있는 위치에 결과 파일이 생성된다)

$> db2dart sample /DTSF

Action option: DTSF

Connecting to Buffer Pool Services...

      Storage group file (automatic storage) report phase start.

      Header version:            0
      Header flavour:            1
      Number of storage groups:  1
      Checksum:                  0x0b050154

      Storage group ID:          0
      Storage group name:        DBSTORAGE
      Flavour:                   3
      Version:                   0
      State flags:               0x0000000000000000
      Last LSN:                  0x0000000000000000
      Initial LSN:               0x0000000000000000
      Next path ID:              1
      Checksum:                  0x193a7a22

      Number of storage paths:   1
      Storage path # 0:          /db2/instance/db2inst (id = 0, state = 0x0)

      Storage group file (automatic storage) report phase end.


      Tablespace file report phase start.
      Tablespace information for current database:
      --------------------------------------------


      Number of defined tablespaces:  8
      High water mark of used pools:  7
      Number of disabled tablespaces: 0

      Individual tablespace details:
      -------------------------------

      Information for Tablespace ID: 0

      (생략)

 

$> db2dart sample /LHWM
2 48   (tablespace ID 및 페이지 크기 지정)

The requested DB2DART processing has completed successfully!
Complete DB2DART report found in:/db2/instance/db2inst/sqllib/db2dump/DART0000/SAMPLE.RPT

High water mark:  1952 pages, 61 extents (extents #0 - 60)


Lower high water mark processing - phase start.
     Current high water mark:                    60
     Desired high water mark:                    1
     Number of used extents in tablespace:       57
     Number of free extents below original HWM:  4
     Number of free extents below desired HWM:   0
     Number of free extents below current HWM:   4


Final high water mark:  Extent #56 (57 extents, 1824 pages).

** This cannot be lowered further as there are not enough free extents
   to move the object holding the high water mark.

 

$> db2 "inspect check database results keep db.inspect"
$> cd ~/sqllib/db2dump
$> db2inspf db.inspect db.db2infp -e -s –w

 

DB에 bad page 오류가 발생을 하는 경우 진단로그에 tablespace id 및 object id 들이 기록이 된다.

db가 비활성상태라면 db2dart를 통하여 tablespace id 및 object id를 지정하여 결과 파일을 통하여 page 오류를 확인할 수 있을 것이고,

db가 온라인 상태라면 db2 inspect 를 통하여 “데이터 무결성’을 점검할 수 있을 것 같다.

 

본 도구들을 많이 사용해 봤다면, 특정 주제를 가지고 설명을 했을텐데 둘러보기 식으로 해당 도구에 대한 소개를 마친다.

DB2에서는 수행된 SQL을 분석할 수 있는 db2 벤치마크 도구를 제공한다.

db2batch 라는 도구를 통하여 SQL이 수행된 시간, SQL이 수행되면서 사용된 bufferpool 정보들도 확인이 가능하다.

 

다양한 옵션이 많지만 장황하지 않는 선에서 다음과 같이 명령어를 정리해 본다.

db2batch -d 데이터베이스 -f SQL_파일명 -a ID/PWD -m 변수값 -z 출력_파일명 -iso cs -car cc -o r 1 p 2 e yes

 

가장 간단한 옵션은 –f 옵션까지만 주어서 SQL문을 실행시키면 된다.

원격에서 실행하는 경우 –a 옵션을 주어 접속 계정 정보를 명시적으로 지정하고, –m 변수를 통하여 동적 SQL을 수행할 수도 있다.

 

jennifer 등을 통하여 실행된 동적SQL의 변수 값이 추출 가능한데, SQL문과 변수 값 리스트가 별도로 나오기 때문에 “정적SQL”로 만드는 작업이 번거로울 수 있다.  이런 경우 –m 옵션을 통하여 동적으로 SQL 성능 분석을 편하게 할 수 있을 것 같다.

 

-z 옵션은 결과 출력 파일 지정하는 옵션이며, –iso 는 격리수준(isolation level)을 의미하며 V9.7 이후 currently committed 이 지원되므로 –car cc 옵션을 주어도 무방할 듯 하다.

 

-o 옵션에는 세부 옵션들이 다양하게 존재한다. r 옵션은 실행된 SQL의 return 값을 몇 개 반환하게 할 지를 결정하는 경우로 50건 이상 넘어가는 결과 값의 경우 샘플로 몇 개의 데이터를 확인하고자 할 때 지정하면 될 듯 하다.

p 옵션은 성능 분석을 위한 데이터 수집을 하도록 하는 옵션으로 2 인 경우는 실행된 SQL 수행시간 이외 application snapshot 정보도 수집해 준다. 숫자가 커질수록 수집되는 snapshot 정보는 많아 진다. 해당 SQL이 어떤 자원을 어떻게 사용했는지 확인하고자 한다면 (app. snapshot 정보로도 충분하다고 생각이 들지만 더욱 더 상세하게 수집하고자 하는 경우) 숫자를 조정하면 될 듯 하다.

 

e 옵션은 explain 정보를 수집하는 옵션인데, 테스트를 해 본 바 수집되지는 않았다.

 

1. Static SQL 테스트

   sample 데이터베이스의 employee 테이블을 대상으로한 select 문으로 수행하였다.

 

SQL 문

cat > sql.db2 <<EOF
select * from emp where empno > 10 ;
EOF

 

실행

db2 "CALL SYSPROC.SYSINSTALLOBJECTS('EXPLAIN','C',NULL,CURRENT SCHEMA)"
db2batch -d sample -f sql.db2 -a db2inst/db2inst -z sql1.out -iso cs -car cc -o r 1 p 2 e yes

 

결과

* Timestamp: Tue Aug 27 2013 00:43:11 KORST
---------------------------------------------

* SQL Statement Number 1:

select * from emp where empno > 10 ;

(생략) 데이터 1건 결과

* 41 row(s) fetched, 1 row(s) output.

* Elapsed Time is:       0.011069 seconds

            Monitoring Information

Instance name                                  = db2inst

(생략)

            Application Snapshot


Application handle                         = 49923
Application status                         = UOW Waiting

(생략)

* Summary Table:

Type      Number      Repetitions Total Time (s) Min Time (s)   Max Time (s)   Arithmetic Mean Geometric Mean Row(s) Fetched Row(s) Output
--------- ----------- ----------- -------------- -------------- -------------- --------------- -------------- -------------- -------------
Statement           1           1       0.011069       0.011069       0.011069        0.011069       0.011069             41             1

* Total Entries:              1
* Total Time:                 0.011069 seconds
* Minimum Time:               0.011069 seconds
* Maximum Time:               0.011069 seconds
* Arithmetic Mean Time:       0.011069 seconds
* Geometric Mean Time:        0.011069 seconds
---------------------------------------------

 

 

2. 동적SQL 예제(1)

SQL 문

cat > par.db2 <<EOF
--#PARAM 1000
--#PARAM 'M'
select * from emp where salary > ? and sex = ?;
EOF

 

실행

db2batch -d sample -f par.db2 -z par.out -iso cs -car cc -o r 5 p 2

 

 

3. 동적SQL 예제(2)

SQL 문

cat > par.ins <<EOF
1000 'M'
EOF


cat > par.db2 <<EOF
select * from emp where salary > ? and sex = ?;
EOF

 

실행

db2batch -d sample -f par.db2 -m par.ins -z par.out -iso cs -car cc -o r 5 p 2

리눅스 환경에서 DB2 설치를 하여 사용하는 경우 고려해야 되는 parameter가 존재한다.

 

1. randomize_va_space = 0

   DB2는 “자체 메모리 주소 체계”를 만들어 주소를 관리하도록 설계되어져 있다. 그래서 db2pd –osinfo 에서 "virtual memory” 라고 메모리 항목이 표현된 것을 볼 수 있다.

DB2에서 메모리 주소를 가상화해서 사용하다보니, OS 레벨에서 메모리 주소가 가상화 되어지는 것을 메모리 관리 안정성 면에서 위험할 수 있다고 보는 것 같다.

그래서 IBM TechNote에서 리눅스 운영체제에서 랜덤 주소 공간 사용을 하지 못하도록 설정을 권장하고 있다.

개인적으로 운영 서버의 경우 설정될 필요가 있다고 생각이 든다. (개발이나 테스트 용도의 경우는 별도 설정할 필요는 없을 것 같다)

 

(참고) https://www-304.ibm.com/support/docview.wss?uid=swg21365583

 

2. vm.swappingness=0

   DB2 교육 준비를 위하 자료를 찾다가 보게 된 parameter로 DB2 정보센터에는 별도 언급이 없는 것으로 알고 있다.

   물리적 메모리 가용 공간이 존재해도 어떤(?) 이유에서 SWAP 공간을 사용하는 경우가 발생하여 성능 저하가 될 수 상황을 방지하기 위하여  DB 서버 환경에서는 SWAP공간 사용을 막는 설정을 권장하는 것 같다.

   개인적으로 운영 서버 구축 시, OS 및 업무 담당자와 협의를 통하여 적용 여부를 결정하는 것이 좋을 것 같다.

 

(참고) http://seuis398.blog.me/70128624124

 

3. vm.overcommit_memory = 2 & vm.overcommit_ratio = 99

    자원이 극도로 적게 할당된 상태의 고객사 개발서버 환경에서 DB2 서버가 갑자기 죽어버리는 경우를 경험한 적이 있다. 리눅스는 OOM Killer (Out-of-Memory Killer) 라는 daemon이 작동을 하여 메모리 부족 시 메모리를 많이 잡고 있는 Application을 kill 시키도록 설계가 되어 있다.

 

    어떤 면에서는 안전 장치가 되겠지만, 중요한 업무를 수행하는 Application이라면 큰 문제를 야기할 수 있는 프로세스라고 할 수 있지 않을까 싶다.

    검색해서 본 문서를 보면 DB서버의 경우는 OOM Kill이 발생하지 않도록 메모리 overcommit을 허용하도록 설정하는 것을 권장하는 것 같다.

    실제 물리적 메모리보다 많이 가지고 있도록 설정을 해 놓아 OOM Kill에 의해 비정상적으로 죽는 것을 방지하고,  DB서버 자체적으로 메모리 부족 예외 상황을 만나 예외 처리 되도록 하는 것을 권장하는 것 같다.

 

    이 parameter도 운영 서버 구축 시에 OS 담당자 및 업무 담당자와의 협의를 통해 결정하는 것이 좋을 것 같다.

 

(참고) http://www.mimul.com/pebble/default/2013/05/10/1368171783727.html

         http://zalhae.blog.me/30150887343

'Note' 카테고리의 다른 글

[관리] db2dart 와 db2 inspect  (0) 2013.08.27
[성능] SQL 성능 분석  (0) 2013.08.26
[관리] row migration 과 row chain  (0) 2013.06.26
[설치] 비루트 설치  (0) 2013.06.19
[관리] 테이블 상태 확인(SQL0668N)  (0) 2013.05.28

락 상태를 확인하거나 Waiting에 빠진 상태를 확인하기 위해 db2top (U옵션) 혹은 db2pd –locks wait 등의 명령어를 통해 확인을 한다.

두 명령어 모두 서버에서만 실행가능한 명령어이기 때문에 사용의 제약이 발생한다. SQL로 실행하여 lock 상태는 다음과 같이 snapshot 함수를 통해 확인 가능하다.

 

SELECT a.locks_held,

             a.MEMBER,

              a.agent_id app_handl,

              substr(b.appl_name,1,20) app_name,

              a.APPL_CON_TIME,

              a.lock_wait_time,

              substr(b.client_nname,1,20) client_name,

              b.client_platform

FROM SYSIBMADM.SNAPAPPL AS a,

          SYSIBMADM.APPLICATIONS b

WHERE locks_held > 0 AND a.agent_id = b.agent_id

order by locks_held desc

결과 값

LOCKS_HELD  MEMBER  APP_HANDL  APP_NAME  APPL_CON_TIME  LOCK_WAIT_TIME CLIENT_NAME  CLIENT_PLATFORM

------------- ---------- ------------ ----------- ----------------- -------------------- -------------------- ---------------

      2               0             80                db2bp          2012-08-24-12.14.15.363344  0  pureScale                  LINUXX8664

 

App_Handle이 80인 Application이 2개의 lock를 가지고 있음을 확인할 수 있다.

잠금 대기(Lock waiting)에 놓인 테이블을 통하여 어떤 Application에 의해 Lock Chain이 발생했는지 확인 가능하다.

select substr(tabschema,1,8) || '.' || substr(tabname,1,16) tabname,

          lock_name,

          substr(lock_object_type,1,12) lock_object_type,

          req_application_handle,

          req_member,substr(req_application_name,1,14) req_app_name,hld_member,

           hld_application_handle,

           substr(hld_application_name,1,14) hld_app_name,

           substr(req_stmt_text,1,32) req_stmt,

           substr(hld_current_stmt_text,1,26) hel_cur_stmt

from SYSIBMADM.MON_LOCKWAITS

결과 값

TABNAME LOCK_NAME LOCK_OBJECT_TYPE REQ_APPLICATION_HANDLE REQ_MEMBER REQ_APP_NAME HLD_MEMBER HLD_APPLICATION_HANDLE HLD_APP_NAME REQ_STMT HEL_CUR_STMT

--------- -------------------------------- ---------------- ---------------------- ---------- -------------- ---------- ---------------------- -------------- -------------------------------- --------------------------

INST10 .T1 03000800040000000000000052 ROW 70 0 db2bp 0 60 db2bp delete from t1

T1 테이블에 대해서 Lock을 잡고 있는 Application(HLD_APPLICATION_HANDLE) 은 60번이고,

Lock 을 얻고자 요청한 Application(REQ_APPLICATION_HANDLE)은 70번이다.

이 경우 lock chain 현상을 풀고자 60번 Application을 강제로 죽이면 chain현상은 풀리게 된다.

db2 “force application(‘60’)”

+ Recent posts