728x90

설치제거 순서


1. 선택사항: 데이터베이스를 모두 삭제(Drop)하십시오. 제어 센터 또는 DROP DATABASE 명령을 사용하여 데이터베이스를 삭제할 수 있습니다. 데이터베이스 파일은 먼저 데이터베이스를 삭제하지 않고 인스턴스를 삭제하면 파일 시스템에 그대로 남아 았습니다.


2. DB2 Administration Server를 중지하십시오.

2.1 DB2 Administration Server 소유자로서 로그인하십시오.

2.2 db2admin stop 명령을 입력하여 DB2 Administration Server를 중지하십시오.


3. DB2 Administration Server를 제거하거나 dasupdt 명령을 실행하여 DB2 Administration Server를 다른 설치 경로로 갱신하십시오.

3.1 루트 사용자 권한이 있는 사용자로 로그인하십시오.

3.2 DAS를 중지하십시오. 예를 들어, 다음과 같습니다.

db2admin stop

3.3 DAS를 제거하십시오. 다음 명령을 입력하십시오.

DB2DIR/instance/dasdrop

여기서 DB2DIR은 DB2 데이터베이스 제품 설치 시 지정한 위치입니다. UNIX®의 디폴트 설치 경로는 /opt/IBM/db2/V9.7입니다. Linux®의 디폴트 설치 경로는 /opt/ibm/db2/V9.7입니다.


참고) DB2 버전별 DB2DIR

버전 8 : AIX에서는 /usr/opt/db2_08_01이고, 기타 모든 UNIX 기반 운영 체제에서는 /opt/IBM/db2/V8.1입니다.

버전 9.1 : UNIX®의 디폴트 설치 경로는 /opt/IBM/db2/V9.1입니다. Linux®의 디폴트 설치 경로는 /opt/ibm/db2/V9.1입니다.

버전 9.5 : UNIX®의 디폴트 설치 경로는 /opt/IBM/db2/V9.5입니다. Linux®의 디폴트 설치 경로는 /opt/ibm/db2/V9.5입니다.


4. DB2 인스턴스를 중지하십시오.

4.1 루트 사용자 권한이 있는 사용자로 로그인하십시오.

4.2 다음 명령을 입력하여 현재 DB2 사본에 연관된 모든 DB2 인스턴스 이름 목록을 확인하십시오.

DB2DIR/bin/db2ilist

여기서 DB2DIR은 DB2 데이터베이스 제품 설치 시 지정한 위치입니다. UNIX®의 디폴트 설치 경로는 /opt/IBM/db2/V9.7입니다. Linux®의 디폴트 설치 경로는 /opt/ibm/db2/V9.7입니다.

4.3 .profile에 포함되지 않은 경우 스크립트를 실행하십시오.

. INSTHOME/sqllib/db2profile       (bash, 본 쉘 또는 콘 쉘)

source INSTHOME/sqllib/db2cshrc    (C 쉘)

여기서 INSTHOME은 인스턴스의 홈 디렉토리입니다.

4.4다음 파일을 저장하도록 권장합니다.

$HOME/sqllib/db2systm 데이터베이스 관리 프로그램 구성 파일

$HOME/sqllib/db2nodes.cfg 노드 구성 파일

$HOME/sqllib/function에서 사용자 정의 함수 또는 분리(fenced)된 스토어드 프로시저 응용프로그램

4.5 db2stop force 명령을 입력하여 DB2 데이터베이스 관리 프로그램을 중지하십시오.

4.6 db2 terminate 명령을 입력하여 인스턴스가 중지되었는지 확인하십시오.

4.7 각 인스턴스에 대해 이 단계를 반복하십시오.


5. DB2 인스턴스를 제거하거나 db2iupdt 명령을 실행하여 인스턴스를 다른 설치 경로로 갱신하십시오.

5.1 루트 사용자 권한이 있는 사용자로 로그인하십시오.


5.2 선택사항: 연관된 데이터베이스에서 데이터가 더 이상 필요하지 않다고 확신하는 경우에는 인스턴스를 삭제하기 전에 시스템에서 데이터베이스 파일을 제거하거나 데이터베이스를 삭제(drop)할 수 있습니다.


5.3 다음 명령을 입력하여 인스턴스를 제거하십시오.

DB2DIR/instance/db2idrop InstName

여기서 DB2DIR은 DB2 데이터베이스 제품 설치 시 지정한 위치입니다. UNIX®의 디폴트 설치 경로는 /opt/IBM/db2/V9.7입니다. Linux®의 디폴트 설치 경로는 /opt/ibm/db2/V9.7입니다.

db2idrop 명령은 인스턴스 목록에서 인스턴스 항목을 제거하고 INSTHOME/sqllib 디렉토리를 제거합니다. 여기서, INSTHOME은 인스턴스의 홈 디렉토리이고, InstName은 인스턴스의 로그인 이름입니다. /sqllib 디렉토리에 파일을 저장할 경우, 이 파일은 이 조치로 제거됩니다. 이 파일이 아직도 필요할 경우, 인스턴스를 삭제하기 전에 복사해야 합니다.


5.4선택사항: 루트 사용자 권한이 있는 사용자로 인스턴스 소유자의 사용자 ID 및 그룹을 제거하십시오(해당 인스턴스에 대해서만 사용된 경우). 인스턴스를 다시 작성할 계획이라면 이를 제거하지 마십시오.

주: 인스턴스 소유자 및 인스턴스 소유자 그룹이 다른 목적으로 사용될 수 있으므로 이 단계는 선택적입니다.


6. DB2 데이터베이스 제품을 제거하십시오.


제한사항 (버전 9.1 이상)


rpm 또는 SMIT와 같은 원시 운영 체제 유틸리티를 사용하여 DB2 데이터베이스 제품을 제거할 수 없습니다.

doce_deinstall 명령은 Linux 운영 체제(Linux x32 및 x64)에서만 사용 가능합니다.


6.1 루트 권한을 가진 사용자로 로그인하십시오.

6.2 DB2 제품이 있는 경로에 액세스하십시오. 제거할 DB2 제품의 경로를 찾으려면 시스템에 설치되어 있는 DB2 제품 목록을 참조하십시오.

6.3 DB2DIR/install 디렉토리에서 db2_deinstall -a 명령을 실행하거나 DB2DIR/doc/install 디렉토리에서 doce_deinstall -a 명령을 실행하십시오. 여기서 DB2DIR은 DB2 제품을 설치할 때 지정한 위치입니다.



참고) DB2 버전 8 설치 제거


UNIX 시스템에서 DB2 제품을 제거하려면 다음을 수행하십시오.


1. root 권한이 있는 사용자로 로그인하십시오.

2. DB2 버전 8 제품 CD-ROM을 마운트하십시오.

3. DB2 버전 8 제품 CD-ROM의 루트 디렉토리에서 db2_deinstall -n 명령을 실행하십시오. -n 매개변수를 사용하면 pkgrm 이 비대화식으로 됩니다. -n 매개변수는 System V(Solaris)에만 있습니다.


이 명령은 시스템에서 모든 DB2 제품을 제거합니다.


운영 체제에서 DB2 제품을 제거하기 위한 대체 메소드가 있습니다. 시스템에서 DB2 제품의 서브세트를 제거하고자 하는 경우에 이런 메소드 중 하나를 채택할 수 있습니다. DB2 제품을 제거하기 위한 대안 메소드에는 다음이 포함됩니다.


AIX

SMIT(System Management Interface Tool)를 사용하여 DB2 제품의 일부 또는 전체를 제거할 수 있습니다. SMIT를 사용하여 DB2를 제거하는 경우, DB2 버전 8 제품은 db2_08_01의 자체 접두부에 의해 식별이 가능합니다. installp -u db2_08_01 을 입력함으로써 installp 명령을 사용하여 AIX 시스템에서 모든 DB2 제품을 제거할 수도 있습니다.

HP-UX

swremove 명령을 사용하여 DB2 제품의 일부 또는 전체를 제거할 수 있습니다.

Linux

rpm 명령을 사용하여 DB2 제품의 일부 또는 전체를 제거할 수 있습니다.

Solaris 운영 환경

pkgrm 명령을 사용하여 DB2 제품의 일부 또는 전체를 제거할 수 있습니다.


http://publib.boulder.ibm.com/infocenter/db2luw/v8/index.jsp?topic=/com.ibm.db2.udb.doc/start/t0007439.htm

http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=%2Fcom.ibm.db2.udb.uprun.doc%2Fdoc%2Ft0007439.htm

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

http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/index.jsp?topic=%2Fcom.ibm.db2.luw.qb.server.doc%2Fdoc%2Ft0007439.html

728x90
728x90

DB2 정보 센터

http://publib.boulder.ibm.com/infocenter/db2help/topic/com.ibm.db2.udb.doc/core/c0008880.htm


DB2 UDB Version 8 FixPaks & client downloads for 32 & 64-bit DB2 Products for AIX® Operating Systems

https://www-304.ibm.com/support/docview.wss?uid=swg21256046#r7a


IBM DB2 Universal Database Version 8.2 (Version 8.1 FixPak 7)  Readme
ftp://public.dhe.ibm.com/ps/products/db2/fixes/english-us/db2aix5v8/fixpak/FP7a_U498350/FixPackReadme.txt


Alternate DB2 UDB FixPaks on UNIX-based systems


https://www-304.ibm.com/support/docview.wss?dc=D600&rs=71&uid=swg21112119&context=SSEPGG&cs=UTF-8&lang=enclass&loc=en_US

728x90
728x90

1. Primary DB를 아카이브 로깅 모드로 변경한다.

db2 update db cfg for socks using LOGARCHMETH1 "disk:경로"

예) db2 update db cfg for socks using LOGARCHMETH1 "disk:/work/db2home/db2hadr/db2hadr/NODE0000/SQL00002/SQLOGDIR2/"

(참조. LOGRETAIN 파라미터는 하위 호환성을 위해서만 사용함)


2. 로깅 모드를 변경하면 BACKUP PENDING 상태로 변경되므로 풀백업을 수행한다.

db2 backup db socks (to 경로)


3. ftp등을 통해 백업 이미지를 Standby DB Server로 전송한다


4. 전송한 백업이미지를 사용하여 Standby DB에 복원작업을 수행한다. 복원 작업이 완료되면 DB는 roll-forward 상태로 변경된다.

db2 restore db socks from (백업 이미지 파일을 받은 경로) replace history file


5. HADR 관련 파라미터를 초기화 한다. (필요시 수행)

db2 update db cfg for socks using HADR_LOCAL_HOST NULL

db2 update db cfg for socks  using HADR_LOCAL_SVC NULL

db2 update db cfg for socks  using HADR_REMOTE_HOST NULL

db2 update db cfg for socks  using HADR_REMOTE_SVC NULL

db2 update db cfg for socks  using HADR_REMOTE_INST NULL


6. Primary DB의 HADR 파라미터를 설정한다.

db2 update db cfg for socks  using HADR_LOCAL_HOST lpar1

db2 update db cfg for socks  using HADR_LOCAL_SVC 60010

db2 update db cfg for socks  using HADR_REMOTE_HOST lpar2

db2 update db cfg for socks  using HADR_REMOTE_SVC 50010

db2 update db cfg for socks  using HADR_REMOTE_INST db2hadr


7. Standby DB의 HADR 파라미터를 설정한다.

db2 update db cfg for socks using HADR_LOCAL_HOST lpar2

db2 update db cfg for socks  using HADR_LOCAL_SVC 50010

db2 update db cfg for socks  using HADR_REMOTE_HOST lpar1

db2 update db cfg for socks  using HADR_REMOTE_SVC 60010

db2 update db cfg for socks  using HADR_REMOTE_INST db2hadr



8. Standby DB에서 HADR을 시작한다. 

db2 start hadr on db socks as standby


9. Primary DB에서 HADR을 시작한다.

db2 start hadr on db socks as primary



(메시지 참조)

SQL1766W  The command completed successfully. However, LOGINDEXBUILD was not

enabled before HADR was started.

728x90

'Db2 > Db2 reference' 카테고리의 다른 글

DB2 설치제거 (Linux and UNIX)  (0) 2011.10.03
db2 8.x ref  (0) 2011.10.01
link: db2top  (0) 2011.09.18
DB2 UDB의 Locking 매커니즘과 동시성 제어  (0) 2011.06.12
tablespace 컨테이너 추가할 때의 주의사항  (0) 2011.04.24
728x90

https://www-304.ibm.com/support/docview.wss?uid=swg27009542


https://www.ibm.com/developerworks/mydeveloperworks/blogs/thekguydw/?lang=ko


http://www.thekguy.com/


http://www.ibm.com/developerworks/data/library/techarticle/dm-0812wang/

728x90
728x90

대규모 동시 트랜잭션이 일반적인IT 환경에서, DBMS Locking 메커니즘과 동시성 제어는 데이터베이스의 성능과 직결되어있다고 해도 과언이 아닐 것이다 기사에서는 DB2 UDB Locking 메커니즘과 동시성 제어 방식을 테스트를 통해 살펴봄으로써, DB2 UDB  발생 원인 분석의 효율성과 동시성 향상을 도모하고자 한다.

 

 기사의 내용은 DB2 UDB 8.2.3 이용하여 테스트한 결과를 기반으로 작성하였으며다음과 같은 순서로 DB2 UDB 내부 동작원리를 파악해볼 것이다.

1. DB2 지원하는 Isolation level

2.  DB2 UDB에서는 SELECT 시에도  대기가 발생할까?

3. Lock escalation이란?

4. DB2 UDB Lock Mode 이해

5. 동시성 향상을 위한 DB2 레지스트리 변수  Case 테스트

 

1. DB2 UDB 지원하는 Isolation level

DB2 UDB에서는 ANSI SQL 표준으로 정의된 4가지 Isolation level 모두 지원한다. ANSI SQL 표준의 4가지 Isolation level Read Uncommitted, Read Committed, Repeatable Read, Serializable이며, DB2 UDB에서는 각각의 Isolation level UR (Uncommitted Read), CS (Cursor Stability), RS (Read Stability), RR (Repeatable Read) 지원하고 있다(4개의 Isolation level 대한 설명은 [ 1.1] 기술하였다).DB2 UDB 이러한 4개의 Isolation level 제공하는 목적은특정 트랜잭션 별로 자신에게 필요한 수준의 Isolation level 선택적으로 사용하게 함으로써트랜잭션의 동시성을 높이는 것이다. [ 1.2]에서는 DB2 UDB에서 제공하는 Isolation level Isolation level에서 허용하는 이상현상을 보여준다.

[ 1.1] DB2 UDB에서 제공하는 Isolation level

DB2 UDB Isolation level

 

UR (Uncommitted Read)

Uncommitted Read “Dirty Read” 라고도 불리며, DB2 UDB 에서 제공하는 가장 낮은 Isolation level이다이름에서도   있듯이현재 레코드가 변경 (, COMMIT 또는 ROLLBACK으로 트랜잭션이 종료되지 않은 상태)이라도해당 레코드가 조건에 만족하면 리턴 한다. Uncommitted Read 다른 트랜잭션의 락을 릴리즈  때까지 대기하지 않으므로가장 높은 동시성을 제공하지만,가장 낮은 데이터 일관성을 제공하므로일반적으로 READ onLY 테이블을 조회할  사용한다.

CS (Cursor Stability)

Cursor Stability DB2 UDB 기본설정 값이며현재 커서가 위치한 레코드에 대해서 락을 건다해당 레코드에 대한 락은 다음 레코드를 페치(fetch) 하기 또는 UOW종료될 때까지 유지된다. UOW COMMIT 또는ROLLBACK명령문을 수행하면 종료된다. Cursor Stability 항상 커밋된 레코드만을 읽으며만일 커서가가리키는 레코드에 락이 걸려있다면해당 쿼리는  대기상태에 빠진다또한현재 커서가 위치한 레코드에는 락이걸려있으므로다른 트랜잭션에서 해당 레코드에 대한 변경작업을 수행할  없게 된다커밋된 레코드만을 읽으면서동시성을 극대화시키려면, CS Isolation level 사용하여야 한다.

RS (Read Stability)

Read Stability UOW 단위 안에서, result set 해당되는모든 레코드에 대해 락을 획득한다예를 들어 EMP 테이블에서 DEPTNO=10 조건을 만족하는 레코드가 3건이라면, 3건의 레코드에 대해 락을 획득하게 된다. Result set해당되는 레코드에 대해 락을 획득하므로다른 트랜잭션에서 EMP 테이블에 DEPTNO=10 레코드를 입력하는 것이 가능하다(, phantom reads 발생이 가능하다). Read Stability 역시 항상 커밋된 레코드만을 읽게 되며다른 트랜잭션에서 해당 result set 대한 변경작업을 수행할 없다. 

RR (Repeatable Read)

Repeatable Read DB2 UDB에서 제공하는 가장 높은Isolation level이다. Repeatable Read UOW 단위 안에서,커서에서 참조하는 모든 레코드에 대해 락을 획득한다, Read Stability 예에서는 다른 트랜잭션에서DEPTNO=10 레코드를 입력하는 것이 가능했지만, Repeatable Read에서는 불가능하다(, phantom reads 발생을 막을  있다). 이러한 이유로 Repeatable Read 설정할 경우에 쿼리 옵티마이저는 LOCKLIST MAXLOCKS 같은 파라미터 설정을 고려하여레코드 단위가 아닌 테이블 레벨에 락을 획득하는 방식을 사용하기도 한다. Repeatable Read 역시 항상 커밋된 레코드만을읽게 되며다른 트랜잭션에서 해당 커서에서 참조하는 레코드들에 대한 변경작업을 수행할  없다.

[ 1.2] DB2 UDB에서 제공하는 Isolation level  Isolation level에서 허용하는 이상현상

DB2 UDB Isolation level

Lost Updates

Dirty Reads

Non-Repeatable Reads

Phantom Reads

UR (Uncommitted Read)

N

Y

Y

Y

CS (Cursor Stability)

N

N

Y

Y

RS (Read Stability)

N

N

N

Y

RR (Repeatable Read)

N

N

N

N

Isolation level 따라 발생할  있는 이상현상은 Lost Updates, Dirty Reads, Non-Repeatable Reads, Phantom Reads이다. File System 달리모든 사용 DBMS에서는Dirty Write 허용되지 않으므로, Lost Updates 현상은 발생하지 않는다또한 Dirty Reads  그대로 언커밋된 레코드를 읽는 것을 의미한다따라서조금 생소한 Non-Repeatable Reads Phantom Reads 예를 들어 설명하기로 한다.

) EMP 테이블에는 다음과 같은 레코드가 저장되어있다.

EMPNO

DEPTNO

SAL

1

10

100

2

10

100

3

10

100

 

1. Non-Repeatable Reads

Transaction 1

Transaction 2

SELECT SAL FROM EMP WHERE EMPNO=1

Result: 100

 

 

UPDATE EMP SET SAL=200 WHERE EMPNO=1;

COMMIT;

SELECT SAL FROM EMP WHERE EMPNO=1

Result: 200

 

Non-Repeatable Reads 위의 예처럼하나의 UOW 안에서 동일한 레코드를 2 이상조회하는 경우에다른 트랜잭션에서 해당 레코드를 변경함으로 인해조회 시마다 결과가 다르게 나타나는 현상이다이러한 이상현상을 해결하기 위해서는 쿼리의 result set 해당되는 레코드에 로우 레벨의 락을 설정하는 RS (Read Stability) Isolation level 사용하면 된다.

 

2. Phantom reads

Transaction 1

Transaction 2

SELECT SUM(SAL) FROM EMP WHERE DEPTNO=10

Result: 300

 

 

INSERT INTO EMP VALUES (4,10,200);

COMMIT;

SELECT SUM(SAL) FROM EMP WHERE DEPTNO=10

Result: 500

 

Phantom Reads 기존 수행한 쿼리에 해당되는 레코드들에 대한 변경이 아닌신규로삽입된 레코드에 의해 쿼리 결과가 다르게 나타나는 현상을 의미한다이러한 이상 현상을 해결하기 위해서는커서가 참조하는 모든 레코드에 대해 락을 설정하는 RR (Repeatable Read) Isolation level 사용하면 된다.

 

2.  DB2 UDB에서는 SELECT 시에도  대기가 발생할까?

DB2 UDB CS (Cursor Stability) Isolation level부터는현재 변경이 진행중인 레코드를 페치(fetch) 경우에  대기 현상이 발생한다또한 현재 커서가 위치한 레코드에대해서다른 트랜잭션에서 변경을 시도할 경우에도  대기가 발생하게 된다다시 말하면 WRITE READ 블로킹하고, READ WRITE 블로킹하게 된다오라클에 익숙한 사용자라면이러한 현상에 대해서의아하게 생각할 것이다하지만, ANSI-SQL표준에 의하면이러한 현상은 당연한 것이라   있다왜냐면, CS (Cursor Stability) Isolation level부터는 SELECT 시에도 레코드에 로우 레벨 락을 설정함으로써, Isolation 보장하기 때문이다다만오라클에서는 언두 세그먼트(Undo Segment)이용한 MVCC (Multi-Version Concurrency Control) 기법을 이용하여, WRITEREAD간의 블로킹 현상을 방지한 것이다현재 MVCC 지원하는 상용 DBMSORACLE, MS-SQL 2005, ALTIBASE 정도이다. MVCC 지원한다는 것이 트랜잭션의동시성을 높일  있다는 장점은 있으나언두 블록 I/O, CR Copy 오퍼레이션, CR 블록관리와 같은 부가적인 작업이 필요하다는 것도 간과해서는 안될 부분이다.

 

3. Lock escalation이란?

Lock escalation이란 로우 레벨 락이 테이블 락으로 전이되는 현상을 의미한다. Lock escalation DB2 UDB 같이  정보를 메모리상에서 관리하는 DBMS에서는 공통적으로 발생할  있는 현상이다한정된 메모리 공간에서  정보를 관리함에 따라, 정보를 관리하는 메모리 공간이 부족할 경우필연적으로 Lock escalation 발생하게 되는 것이다일반적으로 Lock escalation 발생할 경우트랜잭션의 동시성은 급격히 감소하여전반적인 성능 문제를 유발하게 된다따라서 DB2 UDB에서 Lock escalation 발생하는 경우와 Lock escalation 발생 여부를 감지하는 방법에 대해서설명하고자 한다. DB2 UDB에서 Lock escalation 관련된 DB Configuration 파라미터는 LOCKLIST MAXLOCKS 이다 

LOCKLIST

 정보를 관리하는 메모리 공간의 크기를 지정하는 파라미터이다LOCKLIST 크기를 증가하는 것은 동적으로 가능하지만LOCKLIST 크기를 감소시키려면 DB 재기동해야 한다.해당 파라미터의 단위는 4KB이다.

MAXLOCKS

하나의 응용프로그램에서 획득할  있는  정보의 최대 크기를LOCKLIST 대한 백분율로 나타내는 파라미터이다기본설정 값은 10% 이다 말은 LOCKLIST 10% 공간까지 하나의 응용프로그램에서 사용이 가능하며 비율을 넘기는 시점에 로우 레벨 락이 테이블 레벨 락으로 Lock escalation 발생하게 된다.

 

DB2 UDB에서 Lock escalation 발생하는 경우는 크게 2가지로 구분할  있다.

1. 하나의 응용프로그램이 MAXLOCKS 비율이상으로 락을 획득한 경우

2. LOCKLIST 정의된 메모리 공간에  이상의  정보를 저장할  없을 경우이다.

 중에서 1번에 대해서 테스트를 통해 Lock escalation 동작원리를 살펴보도록 하자.

 

테스트1:

하나의 응용프로그램이 MAXLOCKS 비율이상으로 락을 획득한 경우.

테스트 환경: AIX 5.3 64 Bit, DB2 UDB 8.2.3

 

-------- 테스트 시작 -------

--현재의 LOCKLIST 설정 값을 확인한다.

$ db2 get db cfg | grep LOCKLIST

Max storage for lock list (4KB)              (LOCKLIST) = 100

 

--테스트의 편의성을 위해 LOCKLIST 최소값으로 설정한  DB  기동한다.

$ db2 update db cfg using LOCKLIST 4

$ db2 terminate

$ db2 force application all

$ db2 deactivate db sample

$ db2 activate db sample

$ db2 connect to sample

$ db2 get db cfg | grep LOCKLIST

Max storage for lock list (4KB)              (LOCKLIST) = 4

*) DB  기동 후에 LOCKLIST 4 변경되었음을   있다LOCKLIST 지정된 메모리 공간은 16KB(4*4KB)이고MAXLOCKS 10% 이므로하나의 응용프로그램은 1.6KB(1638 Bytes) 만큼의  메모리 공간을 사용하는 것이 가능하다.

 

--테스트를 위한 테이블을 생성하고 1건을 입력한다.

$ db2 “create table lock_escals_test (id integer, name char(10))”

$ db2 +c   -- 테스트를 위해 auto commit mode 해제한다.

db2 => insert into lock_escals_test values (1,’1’)

 

-- 다른 터미널에서  정보를 조회한다.

$ db2 –tf lock_info.sql

AGENT_ID LOCK_MODE                  LOCK_OBJECT_TYPE     TABLE_NAME

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

1031     Exclusive Lock             table row lock type  LOCK_ESCALS_TEST

1031     Intention Exclusive Lock   table lock type      LOCK_ESCALS_TEST

*) LOCK_ESCALS_TEST 테이블에, IX(Intention Exclusive) 모드로 1개의 테이블 락을획득하였고, X(Exclusive) 모드로 1개의 로우 락을 획득한 것을   있다.

-- 추가로 1건을 입력한 후에  정보를 조회해보자.

$ db2 –tf lock_info.sql

AGENT_ID LOCK_MODE                  LOCK_OBJECT_TYPE     TABLE_NAME     

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

1031     Exclusive Lock             table row lock type  LOCK_ESCALS_TEST

1031     Exclusive Lock             table row lock type  LOCK_ESCALS_TEST

1031     Intention Exclusive Lock   table lock type      LOCK_ESCALS_TEST

*) 조회 결과, DB2 UDB에서는 로우 단위의 락이 메모리에서 관리됨을 명확히 확인할 있다이러한 방식으로 MAXLOCKS 도달할 때까지  메모리상에 로우  정보가 저장될 것이다.

 

-- LOCK_ESCALS_TEST 45건을 입력한 시점의  정보는 다음과 같다.

AGENT_ID LOCK_MODE                  LOCK_OBJECT_TYPE     TABLE_NAME     

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

1031     Exclusive Lock             table row lock type  LOCK_ESCALS_TEST

1031     Exclusive Lock             table row lock type  LOCK_ESCALS_TEST

....                                                     

1031     Exclusive Lock             table row lock type  LOCK_ESCALS_TEST

1031     Intention Exclusive Lock   table lock type      LOCK_ESCALS_TEST                                                                                      

46 record(s) selected.

*) LOCK_ESCALS_TEST 테이블에, IX(Intention Exclusive) 모드로 1개의 테이블 락을획득하였고, X(Exclusive) 모드로 45개의 로우 락을 획득한 것을   있다.

 

-- 추가로 1건을 입력한 후에  정보를 조회해보자.

AGENT_ID LOCK_MODE                 LOCK_OBJECT_TYPE     TABLE_NAME     

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

1031     Exclusive Lock            table lock type      LOCK_ESCALS_TEST

 

*) LOCK_ESCALS_TEST 테이블에, IX(Intent Exclusive) 모드로 획득한 테이블 락이X(Exclusive) 모드의 락으로 변경되었고기존에 획득한 로우 락이 모두 사라졌음을  있다, Lock escalation 발생한 것이다테이블 락을 X(Exclusive) 모드로 획득하였으므로다른 응용프로그램에서는 LOCK_ESCALS_TEST 테이블에 대한 SELECT DML 수행이 불가능하다 이유는  모드간의 호환성이 없기 때문인데 모드간의 호환성에 대해서는 “4. DB2 UDB Lock Mode 이해” 에서 설명하기로 한다. Lock escalation 발생 여부를 확인하는 방법은  가지가 있지만가장 인지 하기 쉬운 방법은 db2diag.log 확인하는 것이다. Lock escalation 대한 상세 정보를db2diag.log에서 확인하기 위해서는 DBM Configuration 파라미터인 NOTIFYLEVEL 3또는 4이어야 한다(기본설정 값은 3). 아래는 Lock escalation 발생한 경우에db2diag.log 출력되는 내용이다.

2007-04-24-11.04.15.430688+540 E3616C468          LEVEL: Warning

PID     : 1634496              TID  : 1           PROC : db2agent (SAMPLE) 0

INSTANCE: db2inst1             NODE : 000         DB   : SAMPLE

APPHDL  : 0-1031               APPID: *LOCAL.db2inst1.070424014503

FUNCTION: DB2 UDB, data management, sqldEscalateLocks, probe:3

MESSAGE : ADM5502W  The escalation of "46" locks on table

          "DB2INST1.LOCK_ESCALS_TEST" to lock intent "X" was successful.

*) DB2INST1.LOCK_ESCALS_TEST 테이블에 대해 46개의 락이 X 모드의 테이블 락으로 escalation 되었다는 정보를 확인할  있다현재의 LOCKLIST, MAXLOCKS 설정으로하나의 응용프로그램은 하나의 테이블에 대해서 46개의  정보를  메모리공간에 저장할  있다.

-------- 테스트 종료 -------

 

지금까지의 테스트 내용은 하나의 응용 프로그램에서 하나의 테이블에 대해MAXLOCKS 지정된 비율 이상으로 락을 획득한 경우의 Lock escalation 발생 현상을살펴보았다그렇다면하나의 응용 프로그램에서 2 이상의 테이블에 대한 락을 획득하였고특정 1개의 테이블에 대한 과도한 로우  획득으로 인해 MAXLOCKS 비율 이상으로 락을 획득한 경우를 살펴보도록 하자. Lock escalation 어떻게 발생할 것인가모든 테이블에 대해서 Lock escalation 발생할 것인가아니면 가장 많은 로우 락이 설정된 테이블에 대해서만 Lock escalation 발생할 것인가상식적으로 생각해도,후자가 맞을 것이다테스트를 통해서 확인해 보도록 하자.

 

-------- 테스트 시작 -------

-- LOCK_ESCALS_TEST2 테이블 생성  1 입력

$ db2 “create table lock_escals_test2 (id integer, name char(10))”

$ db2 +c   -- 테스트를 위해 auto commit mode 해제한다.

db2 => insert into lock_escals_test2 values (1,’1’)

-- LOCK_ESCALS_TEST 테이블에 38 입력 후에  정보 확인

$ db2 –tf lock_info.sql

AGENT_ID LOCK_MODE                 LOCK_OBJECT_TYPE     TABLE_NAME

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

1162     Exclusive Lock            table row lock type  LOCK_ESCALS_TEST

....                               

1162     Exclusive Lock            table row lock type  LOCK_ESCALS_TEST

1162     Exclusive Lock            table row lock type  LOCK_ESCALS_TEST2

1162     Intention Exclusive Lock  table lock type      LOCK_ESCALS_TEST

1162     Intention Exclusive Lock  table lock type      LOCK_ESCALS_TEST2

41 record(s) selected.

*) LOCK_ESCALS_TEST2 테이블에 IX 모드의 테이블  1, X 모드의 로우  1,LOCK_ESCALS_TEST 테이블에 IX 모드의 테이블  1, X 모드의 로우  38개를 회득하였다현재까지  41개의 락이 하나의 응용프로그램에서 획득한 상태이다.

 경우에 로우 락을 적게 설정한 LOCK_ESCALS_TEST2 테이블에 추가로 3건을 입력한 후에  정보와 db2diag.log 내용을 확인해 보자.

$ db2 –tf lock_info.sql

AGENT_ID LOCK_MODE                 LOCK_OBJECT_TYPE       TABLE_NAME

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

1162     Exclusive Lock            table row lock type    LOCK_ESCALS_TEST2

1162     Exclusive Lock            table row lock type    LOCK_ESCALS_TEST2

1162     Exclusive Lock            table row lock type    LOCK_ESCALS_TEST2

1162     Exclusive Lock            table row lock type    LOCK_ESCALS_TEST2

1162     Exclusive Lock            table lock type        LOCK_ESCALS_TEST

1162     Intention Exclusive Lock  table lock type        LOCK_ESCALS_TEST2

 6 record(s) selected.

 시점에서의 db2diag.log 내용은 아래와 같다.

2007-04-24-11.52.22.987478+540 E5023C468          LEVEL: Warning

PID     : 987356               TID  : 1           PROC : db2agent (SAMPLE) 0

INSTANCE: db2inst1             NODE : 000         DB   : SAMPLE

APPHDL  : 0-1162               APPID: *LOCAL.db2inst1.070424024716

FUNCTION: DB2 UDB, data management, sqldEscalateLocks, probe:3

MESSAGE : ADM5502W  The escalation of "38" locks on table

          "DB2INST1.LOCK_ESCALS_TEST" to lock intent "X" was successful.

*) LOCK_ESCALS_TEST 테이블에 대해, 38개의 락이 X 모드의 테이블 락으로 Lock escalation 되었음을   있으며LOCK_ESCALS_TEST2 테이블에 대해서는 Lock escalation 발생하지 않았다 테스트를 통해, Lock escalation 가장 많은 락이 설정된 테이블에 대해서 우선적으로 수행됨을   있다만일 해당 테이블의 Lock escalation 후에도 MAXLOCKS 지정된 비율보다 높을 경우에는 다음 순위의 테이블에 대해서 Lock escalation 발생할 것이다.

-------- 테스트 완료 -------

 

테스트 결과에서   있듯이하나의 테이블에 대해 락을 획득한 경우와  이상의 테이블에 대해 락을 획득한 경우에락을 저장하는 개수가 약간 상이한 것을  있다테스트 결과에 의하면 대략 1개의   40 bytes 정도의  메모리 공간을 차지한다는 것을   있다일반적으로 Lock escalation 거의 발생하지 않는 것이 정상이지만만일 Lock escalation 현상이 발견된다면, 1차적으로는 LOCKLIST DB Configuration 파라미터의 현재설정 값을 확인한 해당 수치를 증가시키는 것이다. 2차적으로는 db2diag.log  내용을 참조하여해당 어플리케이션에서 필요이상의 락을장기간 획득해야만 하는지에 대한 타당성 점검을  필요성이 있다


DB2 UDB Lock Mode Lock Compatibility

DB2 UDB 사용   대기 현상이 발생할 경우문제 원인 분석을 위해서는 DB2 UDB 에서 사용되는  모드와  호환성에 대한 이해가 선행되어야 한다. DB2 UDB에서는None 모드를 포함하여 12개의  모드를 사용한다ORACLE 데이터베이스의 경우, X(Exclusive), SSX(Sub Share Exclusive), SX(Sub Exclusive), S(Shared), SS(Sub Share), N(Null)  같이 6개의  모드를 사용한다 모드에 대한 정의와 예제는 다음과 같다 모드에 대한 이해를 높이기 위해, AIX 5.3 64비트, DB2 UDB 8.2.3 환경의 테스트를 통해 설명하였다.

 

<테스트 1>

Lock Mode

IN (Intent None)

Applicable Object

Table space, blocks, table

Description

“Dirty Read” , UR Isolation level 사용하여 데이터를 조회하는 경우에 IN 모드의 테이블 락을 획득해야 한다.

 

IN 모드와 호환성이 없는 Z 모드의 락을 T2 트랜잭션에서 획득한 상태에서 T3 트랜잭션에서 “Dirty Read” 수행한다. IN 모드와 Z 모드간에  호환성이 없으므로, T3 트랜잭션은  대기를  것이다또한 Z 모드의 락을 유지하기 위해서, Z 모드와 호환성이 없는 IX 락을 T1 트랜잭션에서 획득한 상태로 테스트를 수행한다.

 

T1 트랜잭션: (Agent ID 1313)

$ db2 +c “insert into lock_test values(3,’3’)

DB20000I  The SQL command completed successfully.

데이터 입력  IX 모드의 테이블 락과 X 모드의 로우 락을 획득한다.

 

T2 트랜잭션: (Agent ID 292)

$ db2 “alter table lock_test add juso char(100)”

* IX 모드와 Z 모드간의 호환성이 없으므로 T2 트랜잭션은 락을 대기한다.

 

T3 트랜잭션: (Agent ID 1345)

$db2 “select * from lock_test with ur

* Z 모드와 IN 모드간의 호환성이 없으므로 T3 트랜잭션은 락을 대기한다.

 

-- 현재의 Lock 대기 상태를 확인해보자.

 $ db2 –tf lock_wait.sql

AGENT_ID LCK_MODE LCK_REQ LOCK_OBJECT_TYPE TABLE_NAME HOLDER_ID

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

292      IX       Z       table lock        LOCK_TEST 1313

1345     IN       IN      table lock        LOCK_TEST 292

* T3 트랜잭션(Agent ID 1345) IN 모드의 테이블 락을 대기하는 것을   있다이를통해,  “Dirty Read” 시에 IN 모드의 테이블 락을 획득한다는 것을 간접적으로 확인할 있다.

 

<테스트 2>

Lock Mode

IS (Intent Share)

Applicable Object

Table space, blocks, tables

Description

CS 이상의 Isolation level 사용하여 데이터를 조회하는 경우에 IS 모드의 테이블 락을 획득해야 한다.

 

IS 모드와 호환성이 없는 X 모드의 락을 T1 트랜잭션에서 획득한 상태에서 T2 트랜잭션에서 읽기 작업을 수행한다. IS 모드와 X 모드간에  호환성이 없으므로, T23 트랜잭션은  대기를  것이다.

 

T1 트랜잭션: (Agent ID 1313)

$ db2 +c “lock table lock_test in exclusive mode

DB20000I  The SQL command completed successfully.

 

T2 트랜잭션: (Agent ID 292)

$ db2 “select * from lock_test with cs”

*) X 모드와 IS 모드간의 호환성이 없으므로 T2 트랜잭션은 락을 대기한다

 

-- 현재의 Lock 대기 상태를 확인해보자.

$ db2 –tf lock_wait.sql

AGENT_ID LCK_MODE LCK_REQ LOCK_OBJECT_TYPE TABLE_NAME HOLDER_ID

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

292      X        IS      table lock       LOCK_TEST  1313

* T2 트랜잭션(Agent ID 292) IS 모드의 테이블 락을 대기하는 것을   있다이를통해, CS 이상의 Isolation level에서 데이터 조회 , IS 모드의 테이블 락을 획득한다는것을 확인할  있다.

 

<테스트 3>

Lock Mode

NS (Next Key Share)

Applicable Object

Rows

Description

CS 또는 RS Isolation level에서 데이터를 조회하는 경우에 현재 커서가 위치한 레코드에 대해 NS 모드의 로우 락을 획득해야 한다.

 

NS 모드와 호환성이 없는 X 모드의 락을 T1 트랜잭션에서 획득한 상태에서, T2 트랜잭션에서 CS Isolation level 데이터 조회를 수행한다.

 

T1 트랜잭션: (Agent ID 1313)

$ db2 +c “insert into lock_test values(3,’3’)

DB20000I  The SQL command completed successfully.

데이터 입력  IX 모드의 테이블 락과 X 모드의 로우 락을 획득한다.

 

T2 트랜잭션: (Agent ID 292)

$ db2 “select * from lock_test with cs”

* X 모드와 NS 모드간의 호환성이 없으므로 T2 트랜잭션은 락을 대기한다.

 

-- 현재의 Lock 대기 상태를 확인해보자.

$ db2 –tf lock_wait.sql

AGENT_ID LCK_MODE LCK_REQ LOCK_OBJECT_TYPE     TABLE_NAME HOLDER_ID

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

292      X        NS      table row lock type  LOCK_TEST  1313

* T2 트랜잭션(Agent ID 292) NS 모드의 로우 락을 대기하는 것을   있다.

 

<테스트 4>

Lock Mode

S (Share)

Applicable Object

Rows, blocks, tables

Description

데이터의 변경을 막기 위해서 설정하는  모드이다예를 들어인덱스 생성 시에는 테이블 데이터의 변경을 막아야 하므로, S 모드의 테이블 락을 획득해야 한다.

 

모드와 호환성이 없는 IX 모드의 락을 T1 트랜잭션에서 획득한 상태에서, T2 트랜잭션에서 인덱스 생성을 시도한다.

 

T1 트랜잭션: (Agent ID 1313)

$ db2 +c “insert into lock_test values(3,’3’)

DB20000I  The SQL command completed successfully.

데이터 입력  IX 모드의 테이블 락과 X 모드의 로우 락을 획득한다.

 

T2 트랜잭션: (Agent ID 292)

$ db2 “create index lock_test_s01 on lock_test(id)”

* IX 모드와 S 모드간의 호환성이 없으므로 T2 트랜잭션은 락을 대기한다.

 

-- 현재의 Lock 대기 상태를 확인해보자.

$ db2 –tf lock_wait.sql

AGENT_ID LCK_MODE LCK_REQ LOCK_OBJECT_TYPE  TABLE_NAME HOLDER_ID

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

292      IX       S       table lock        LOCK_TEST  1313

* T2 트랜잭션(Agent ID 292) S 모드의 테이블 락을 대기하는 것을   있다.

 

<테스트 5>

Lock Mode

IX (Intent Exclusive)

Applicable Object

Table spaces, blocks, tables

Description

테이블내의 레코드에 대한 변경(delete, update)  레코드 입력(insert) 시에 IX 모드의 테이블 락을 획득해야 한다.

 

IX 모드와 호환성이 없는 S 모드의 락을 T1 트랜잭션에서 획득한 상태에서, T2 트랜잭션에서 데이터 삭제를 시도한다.

 

T1 트랜잭션: (Agent ID 1313)

$ db2 +c “lock table lock_test in share mode “ 

DB20000I  The SQL command completed successfully.

 

T2 트랜잭션: (Agent ID 292)

$ db2 “delete from lock_test where id=1”

* S 모드와 IX 모드간의 호환성이 없으므로 T2 트랜잭션은 락을 대기한다.

 

-- 현재의 Lock 대기 상태를 확인해보자.

$ db2 –tf lock_wait.sql

AGENT_ID LCK_MODE LCK_REQ LOCK_OBJECT_TYPE  TABLE_NAME HOLDER_ID

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

292      S        IX      table lock        LOCK_TEST  1313

* T2 트랜잭션(Agent ID 292) IX 모드의 테이블 락을 대기하는 것을   있다.

 

<테스트 6>

Lock Mode

SIX (Share with Intent Exclusive)

Applicable Object

Tables, blocks

Description

IX 모드의 테이블 락을 획득한 상태에서 추가로 S 모드의 테이블 락을 획득하거나 반대의 경우에 SIX 모드의 테이블락을 획득해야 한다.

 

SIX 모드와 호환성이 없는 S 모드 락을 T1 트랜잭션에서 획득한 상태에서, T2 트랜잭션에서 S 모드 락을 획득한 추가로 IX 모드의 락을 획득하려고 시도한다.

 

T1 트랜잭션: (Agent ID 1313)

$ db2 +c “lock table lock_test in share mode “

DB20000I  The SQL command completed successfully.

 

T2 트랜잭션: (Agent ID 292)

$ db2 +c

db2=> lock table lock_test in share mode 

DB20000I  The SQL command completed successfully.

db2=> delete from lock_test where id=1

* S 모드의 테이블 락을 획득한 상태에서삭제(delete)작업을 위해 IX 모드의 테이블 락을 추가로 획득하기 위해 SIX 모드로  컨버젼을 시도한다하지만, T1 트랜잭션이 획득하고 있는 S 모드와 T2 트랜잭션에서 획득해야 하는 SIX 모드간의 호환성이 없으므로 락을 대기한다.

 

 -- 현재의 Lock 대기 상태를 확인해보자.

$ db2 –tf lock_wait.sql

AGENT_ID LCK_MODE LCK_REQ LOCK_OBJECT_TYPE  TABLE_NAME HOLDER_ID

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

292      S        SIX     table lock        LOCK_TEST  1313

* T2 트랜잭션(Agent ID 292) SIX 모드의 테이블 락을 대기하는 것을   있다.

 

<테스트 7>

Lock Mode

U (Update)

Applicable Object

Rows, blocks, tables

Description

SELECT.. FOR UPDATE 시에 U 모드의 로우 락을 획득해야 한다.

 

모드와 호환성이 없는 X 모드 락을 T1 트랜잭션에서 획득한 상태에서, T2 트랜잭션에서 SELECT.. FOR UPDATE 시도한다.

 

T1 트랜잭션: (Agent ID 1313)

$ db2 +c “delete from lock_test where id=1 “ 

DB20000I  The SQL command completed successfully.

데이터 삭제  IX 모드의 테이블 락과 X 모드의 로우 락을 획득한다.

 

T2 트랜잭션: (Agent ID 292)

$ db2 “select * from lock_test where id=1 for update”

* T1 트랜잭션에 의해 해당 레코드에, X 모드의 로우 락이 획득된 상태이므로, T2 트랜잭션은 락을 대기한다..

 

-- 현재의 Lock 대기 상태를 확인해보자.

$ db2 –tf lock_wait.sql

AGENT_ID LCK_MODE LCK_REQ LOCK_OBJECT_TYPE    TABLE_NAME HOLDER_ID

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

292      X        U       table row lock type LOCK_TEST  1313

* T2 트랜잭션(Agent ID 292) U 모드의 로우 락을 대기하는 것을   있다.

 

Lock Mode

X (Exclusive)

Applicable Object

Rows, blocks, tables, buffer pools

Description

테이블 레벨로우 레벨에 대한 변경작업을 하려고   X 모드의 락을 획득해야 한다. X 모드는 테스트 없이도 쉽게 이해가능하므로테스트를 생략한다.

 

Lock Mode

Z (Super Exclusive)

Applicable Object

Table spaces, tables

Description

테이블 DROP, ALTER  같은 오퍼레이션 시에 Z 모드의 테이블 락을 획득해야 한다. IN 모드 설명 시에 Z 모드 테스트를수행하였으므로별도의 테스트를 수행하지 않는다.

 

<테스트 8>

Lock Mode

NW (Next Key Weak Exclusive)

Applicable Object

Rows

Description

테이블에 Non unique 인덱스가 생성되어있고입력하려고 하는 레코드가현재 다른 트랜잭션에서 RR 스캔에 의해 락이설정된 레코드와 동일한 값일 경우에 NW 모드의 락을 대기하게 된다. NW 모드는 쉽게 이해되지 않는 모드 중의 하나이다따라서  부분은 테스트 결과를 통해언제 NW 모드가사용되는지 유추하는 방식을 사용하였다.

 

T1 트랜잭션에서 RR 스캔을 수행하고 있는 상태에서, T2 트랜잭션에서 T1 트랜잭션의RR 스캔의 레코드에 해당되는 값을 입력한다.

앞선 테스트에서는 LOCK_TEST 테이블에 인덱스가 존재하지 않았으나, NW 모드 테스트를 위해 LOCK_TEST 테이블에 Non Unique 인덱스를 생성한다.

$ db2 “create index lock_test_s01 on lock_test(id)”

 

T1 트랜잭션: (Agent ID 1313)

$ db2 +c “select * from lock_test where id=1 with rr“ 

DB20000I  The SQL command completed successfully.

 

T2 트랜잭션: (Agent ID 292)

$ db2 “insert into lock_test values(1,'10')”

 

-- 현재의 Lock 대기 상태를 확인해보자.

$ db2 –tf lock_wait.sql

AGENT_ID LCK_MODE LCK_REQ LOCK_OBJECT_TYPE     TABLE_NAME HOLDER_ID
-------- -------- ------- -------------------  ---------- ---------
292      S        NW      table row lock type  LOCK_TEST  1313

* T1 트랜잭션(Agent ID 292) 인덱스 RR 스캔을 수행한 결과, S 모드의 로우 락을 획득한 상태이고, S 모드와 T2 트랜잭션의 NW 모드는 호환성이 없으므로, T2 트랜잭션은 락을 대기하는 현상을 보인다.

 

<테스트 9>

Lock Mode

W (Weak Exclusive)

Applicable Object

Rows

Description

Unique 인덱스가 생성된 테이블에 대해중복  입력이 발생가능성을 막기 위해 용도로 사용된다.

 

테스트를 위해 LOCK_TEST 테이블에 Non Unique 인덱스를 생성한 것을 DROP하고Unique 인덱스를 생성한다.

$ db2 “drop index lock_test_s01”

$ db2 “create unique index lock_test_uk on lock_test(id)”

 

T1 트랜잭션: (Agent ID 1313)

$ db2 +c “insert into lock_test values(3,’3’)“ 

DB20000I  The SQL command completed successfully.

 

T2 트랜잭션: (Agent ID 292)

$ db2 “insert into lock_test values(3,’3’)“ 

 

-- 현재의 Lock 대기 상태를 확인해보자.

$ db2 –tf lock_wait.sql

AGENT_ID LCK_MODE LCK_REQ LOCK_OBJECT_TYPE     TABLE_NAME HOLDER_ID

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

292      S        W       table row lock type  LOCK_TEST  1313

* Unique 인덱스가 생성되어 있으므로중복  입력을 방지하기 위해 T2 트랜잭션은모드의 로우 락을 대기한다. T1 트랜잭션이 커밋을 수행할 경우 T2 트랜잭션은SQL0803N 에러코드를 발생시키며트랜잭션을 롤백하며, T1 트랜잭션이 롤백을 수행할 경우에 T2 트랜잭션은  대기 상태에서 벗어나서트랜잭션을 진행하게 된다.

 

[ 4.1]  호환성 테스트 결과 매트릭스

 

None

IN

IS

NS

S

IX

SIX

U

X

Z

NW

W

None

O

O

O

O

O

O

O

O

O

O

O

O

IN

O

O

O

O

O

O

O

O

O

X

O

O

IS

O

O

O

O

O

O

O

O

X

X

X

X

NS

O

O

O

O

O

X

X

O

X

X

O

X

S

O

O

O

O

O

X

X

O

X

X

X

X

IX

O

O

O

X

X

O

X

X

X

X

X

X

SIX

O

O

O

X

X

X

X

X

X

X

X

X

U

O

O

O

O

O

X

X

X

X

X

X

X

X

O

O

X

X

X

X

X

X

X

X

X

X

Z

O

X

X

X

X

X

X

X

X

X

X

X

NW

O

O

X

O

X

X

X

X

X

X

X

O

W

O

O

X

X

X

X

X

X

X

X

O

X

 




DB2 UDB V8부터 동시성 향상을 위해 DB2_EVALUNCOMMITTED, DB2_SKIPDELETED, DB2_SKIPINSERTED 라는 3개의 레지스트리 변수를 제공한다.이번 섹션에서는 각각의 레지스트리 변수의 의미와 적용 시의 효과를 살펴보기로 한다.

 

DB2_EVALUNCOMMITTED (DB2 UDB V8.1.4부터 지원)

DB2_EVALUNCOMMITTED CS(Cursor Stability) 또는 RS(Read Stability) Isolation레벨로 테이블  인덱스 스캔시에데이터가 검색 조건에 맞는지 먼저 체크한 후에조건에 맞는 경우에만 해당 레코드에 락을 거는 방식(defer row locking) 사용한다따라서 조건에 맞지 않는 언커밋 상태의 레코드에 대한 스킵이 가능하다뿐만 아니라 테이블 스캔의 경우에는 언커밋 상태의 Deleted 로우에 대한 스킵도 가능하다하지만 인덱스 스캔의 경우에는 언커밋 상태의 Deleted 로우는 스킵이 불가능하다이것을 가능하게 하기 위해서는 뒤에서 설명할 DB2_SKIPDELETE ON으로 설정하여야 한다해당레지스트리 변수의 효과를 테스트를 통해서 확인해보자.

 

테스트 1: DB2_EVALUNCOMMITTED=OFF (기본설정 ) 경우

T1 트랜잭션 (Agent ID 8)

$ db2 +c “insert into lock_test values(9,'9')”

DB20000I  The SQL command completed successfully

 

T2 트랜잭션 (Agent ID 9)

$ db2 “select * from lock_test where id between 1 and 5 with cs”

*) T1 트랜잭션에서 입력한 레코드가 T2 트랜잭션의 쿼리 조건에 해당되지는 않는다.하지만현재 커서가 위치한 다음(Next) 레코드에 NS 모드의 로우 락을 획득한 후에 해당 레코드가 조건에 맞는지 체크하는 방식을 사용하므로, T2 트랜잭션은 락을 대기한다.

-- 현재의  대기상태 확인

$ db2 –tf lock_wait.sql

AGENT_ID LCK_MODE LCK_REQ LOCK_OBJECT_TYPE      TABLE_NAME HOLDER_ID

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

9        X        NS      table row lock type   LOCK_TEST  8

 

테스트 2: DB2_EVALUNCOMMITTED=ON으로 변경한 경우

--DB2_EVALUNCOMMITTED ON으로 설정

$ db2set DB2_EVALUNCOMMITTED=ON

--DB  기동한다.

 

T1 트랜잭션 (Agent ID 8)

$ db2 +c “insert into lock_test values(9,'9')”

DB20000I  The SQL command completed successfully

 

T2 트랜잭션 (Agent ID 9)

$ db2 “select * from lock_test where id between 1 and 5 with cs”

ID          NAME

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

          1 1

          2 2

          3 3

          5 5

4 record(s) selected

*) DB2_EVALUNCOMMITTED=ON 효과에 의해, T2 트랜잭션이  대기 없이 수행되었다현재 커서가 위치한 다음(Next) 레코드를 페치(fetch) 후에 해당 레코드가 조건에 만족하는지 체크한 것이다만일 조건에 만족하지 않을 경우 해당 레코드에 대한 로우  획득이 필요 없으므로 대기현상이 발생하지 않게 된다이러한 defer row locking 방식에는 여러 가지 제약 사항이 존재하지만동시성을 높일  있다는 것은 분명한 사실이다.

 

DB2_SKIPDELETED (DB2 UDB V8.1.4부터 지원)

DB2_SKIPDELETED CS (Cursor Stability) 또는 RS (Read Stability) Isolation 레벨로테이블  인덱스 스캔 시에언커밋  Deleted 로우를 스킵하는 것을 가능하게 한다.

 

테스트 1: DB2_SKIPDELETED=OFF (기본설정 ) 경우

T1 트랜잭션 (Agent ID 7)

$ db2 +c “delete from lock_test where id=3”

DB20000I  The SQL command completed successfully

 

T2 트랜잭션 (Agent ID 8)

-- 테이블 스캔을 수행하여 테스트를 해보자.

$ db2 “select * from lock_test”

ID          NAME

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

          1 1

          2 2

          4 4

         10 10
4 record(s) selected.

*) T1 트랜잭션에 의해 삭제된 레코드가 T2 트랜잭션의 쿼리 조건에 만족하지만테이블 스캔을 수행하므로, DB2_EVALUNCOMMITTED ON 시킨 효과에 의해  대기를하지 않고 결과가 출력된다, DB2_EVALUNCOMMITTED 테이블 스캔에 대해 언커밋 Deleted 로우를 스킵하는 것을 가능하게 한다.

 

-- 인덱스 스캔을 수행하여 테스트를 해보자.

$ db2 “select * from lock_test where id between 1 and 4”

*) T2 트랜잭션에서 인덱스 스캔을 수행하므로  대기를 하게 된다
, DB2_EVALUNCOMMITTED 인덱스 스캔에 대한 언커밋 Deleted 로우를 스킵하는것은 불가능함을   있다.

 

-- 현재의  대기상태 확인

$ db2 –tf lock_wait.sql

AGENT_ID LCK_MODE LCK_REQ LOCK_OBJECT_TYPE     TABLE_NAME HOLDER_ID

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

8        X        NS      table row lock type  LOCK_TEST  7

 

테스트 2: DB2_SKIPDELETED=ON으로 변경한 경우

--DB2_SKIPDELETED ON으로 설정

$ db2set DB2_SKIPDELETED=ON

--DB  기동한다.

 

T1 트랜잭션 (Agent ID 7)

$ db2 +c “delete from lock_test where id=3”

DB20000I  The SQL command completed successfully

 

T2 트랜잭션 (Agent ID 8)

$ db2 “select * from lock_test where id between 1 and 4”

ID          NAME

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

          1 1

          2 2

          4 4

  3 record(s) selected

*) DB2_SKIPDELETED ON으로 설정함에 따라인덱스 스캔 시에도 언커밋 Deleted 로우를 스킵하는 것이 가능하다.

 

DB2_SKIPINSERTED (DB2 UDB V8.2.2부터 지원)

DB2_SKIPDELETED CS (Cursor Stability) 또는 RS (Read Stability) Isolation 레벨로테이블  인덱스 스캔 시에언커밋  Inserted 로우를 스킵하는 것을 가능하게 한다.

 

테스트 1: DB2_SKIPINSERTED=OFF (기본설정 ) 경우

T1 트랜잭션 (Agent ID 7)

$ db2 +c “insert into lock_test values(5,'5')”

DB20000I  The SQL command completed successfully

 

T2 트랜잭션 (Agent ID 8)

$ db2 “select * from lock_test where id between 1 and 5”

*) T1 트랜잭션에서 입력한 레코드가 언커밋 상태이고, T2 트랜잭션 쿼리의 조건에 만족하므로, T2 트랜잭션은  대기를 하게 된다.

 

-- 현재의  대기상태 확인

$ db2 –tf lock_wait.sql

AGENT_ID LCK_MODE LCK_REQ LOCK_OBJECT_TYPE     TABLE_NAME HOLDER_ID

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

8        X        NS      table row lock type  LOCK_TEST  7

 

테스트 2: DB2_SKIPINSERTED=ON으로 변경한 경우

--DB2_SKIPINSERTED ON으로 설정

$ db2set DB2_SKIPINSERTED=ON

--DB  기동한다.

 

T1 트랜잭션 (Agent ID 7)

$ db2 +c “insert into lock_test values(5,'5')”

DB20000I  The SQL command completed successfully

 

T2 트랜잭션 (Agent ID 8)

$ db2 “select * from lock_test where id between 1 and 5”

ID          NAME

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

          1 1

          2 2

          3 3

          4 4

 4 record(s) selected

*) DB2_SKIPINSERTED ON으로 설정함에 따라언커밋  Inserted 로우를 스킵하는것이 가능하다.

 

글을 마치며

앞선 내용에서 DB2 UDB Isolation level, Lock escalation, Lock Mode  동시성 향상을 위한 DB2 레지스트리 변수를 살펴보았다. DB Configuration 파라미터의 적절한 설정과 설계된 Application 사용하는 사이트의 경우에는 Lock escalation이나 대기현상과 같은  문제가 거의 발생하지 않을 수도 있을 것이다하지만 이러한 동작 원리에 대한 이해가 진정한 성능관리 전문가로 거듭나는 시발점이라고 생각하며  기사를통해 독자들이 궁금했던 부분에 대해 한가지라도 이해하는데 도움이 되었으면 하는 바램을 가지며 글을 마친다.

 

APPENDIX

1. lock_info.sql

SELECT substr(char(agent_id),1,7) agent_id ,

       CASE t4.lock_mode

           WHEN 1

           THEN 'Intention Share Lock'

           WHEN 2

           THEN 'Intention Exclusive Lock'

           WHEN 3

           THEN 'Share Lock'

           WHEN 4

           THEN 'Share with Intention Exclusive Lock'

           WHEN 5

           THEN 'Exclusive Lock'

           WHEN 6

           THEN 'Intent None (For Dirty Read)'

           WHEN 7

           THEN 'Super Exclusive Lock'

           WHEN 8

           THEN 'Update Lock'

           WHEN 9

           THEN 'Next-key Share Lock'

           WHEN 10

           THEN 'Next-key Exclusive Lock'

           WHEN 11

           THEN 'Weak Exclusive Lock'

           WHEN 12

           THEN 'Next-key Weak Exclusive Lock'

       END AS lock_mode,

       CASE t4.lock_object_type

           WHEN 1   THEN 'table lock type'

           WHEN 2   THEN 'table row lock type'

           WHEN 3   THEN 'Internal lock type'

           WHEN 4   THEN 'Tablespace lock type'

           WHEN 5   THEN 'end of table lock'

           WHEN 6   THEN 'key value lock'

           WHEN 7   THEN 'Internal lock on the sysboot table'

           WHEN 8   THEN 'Internal Plan lock'

           WHEN 9   THEN 'Internal Variation lock'

           WHEN 10  THEN 'Internal Sequence lock'

           WHEN 11  THEN 'Bufferpool lock'

           WHEN 12  THEN 'Internal Long/Lob lock'

           WHEN 13  THEN 'Internal Catalog Cache lock'

           WHEN 14  THEN 'Internal online Backup lock'

           WHEN 15  THEN 'Internal Object Table lock'

           WHEN 16  THEN 'Internal Table Alter lock'

           WHEN 17  THEN 'Internal DMS Sequence lock'

           WHEN 18  THEN 'Inplace reorg lock'

           WHEN 19  THEN 'Block lock type'

           ELSE char(t4.lock_object_type)

END AS lock_object_type,

       substr(t4.table_name,1,18) table_name

FROM   TABLE( snapshot_lock( 'sample' , - 1 ) ) t4

WHERE  table_name LIKE 'LOCK_ESCALS%';

 

2. lock_wait.sql

SELECT substr(char(t1.agent_id),1,8) agent_id,

       CASE t4.lock_mode

           WHEN 1  THEN 'IS'

           WHEN 2  THEN 'IX'

           WHEN 3  THEN 'S'

           WHEN 4  THEN 'SIX'

           WHEN 5  THEN 'X'

           WHEN 6  THEN 'IN'

           WHEN 7  THEN 'Z'

           WHEN 8  THEN 'U'

           WHEN 9  THEN 'NS'

           WHEN 11 THEN 'W'

           WHEN 12 THEN 'NW'

       END AS lck_mode,

       CASE t4.lock_mode_requested

           WHEN 1  THEN 'IS'

           WHEN 2  THEN 'IX'

           WHEN 3  THEN 'S'

           WHEN 4  THEN 'SIX'

           WHEN 5  THEN 'X'

           WHEN 6  THEN 'IN'

           WHEN 7  THEN 'Z'

           WHEN 8  THEN 'U'

           WHEN 9  THEN 'NS'

           WHEN 11 THEN 'W'

           WHEN 12 THEN 'NW'

       END AS lck_req,

       CASE t4.lock_object_type

           WHEN 1   THEN 'table lock'

           WHEN 2   THEN 'table row lock type'

           WHEN 3   THEN 'Internal lock type'

           WHEN 4   THEN 'Tablespace lock type'

           WHEN 5   THEN 'end of table lock'

           WHEN 6   THEN 'key value lock'

           WHEN 7   THEN 'Internal lock on the sysboot table'

           WHEN 8   THEN 'Internal Plan lock'

           WHEN 9   THEN 'Internal Variation lock'

           WHEN 10  THEN 'Internal Sequence lock'

           WHEN 11  THEN 'Bufferpool lock'

           WHEN 12  THEN 'Internal Long/Lob lock'

           WHEN 13  THEN 'Internal Catalog Cache lock'

           WHEN 14  THEN 'Internal online Backup lock'

           WHEN 15  THEN 'Internal Object Table lock'

           WHEN 16  THEN 'Internal Table Alter lock'

           WHEN 17  THEN 'Internal DMS Sequence lock'

           WHEN 18  THEN 'Inplace reorg lock'

           WHEN 19  THEN 'Block lock type'

           ELSE char(t4.lock_object_type)

       END AS lock_object_type,

       substr(t4.table_name,1,10) table_name,

substr(char(t4.agent_id_holding_lk),1,8) AS holder_id

FROM TABLE( snapshot_appl_info( 'sample' , -1)) t1 ,

       TABLE( snapshot_appl( 'sample' , -1 )) t2,

       TABLE( snapshot_statement( 'sample', -1)) t3,

       TABLE( snapshot_lockwait( 'sample', -1)) t4

WHERE  t1.agent_id=t2.agent_id

AND    t1.agent_id=t3.agent_id

AND    t1.agent_id=t4.agent_id;

 

참고 문헌

DB2 UDB V8.2 Administration Guide :Performance

Lock avoidance in DB2 UDB V8 Improving concurrency with new registry variables

Diagnosing and Resolving Lock Problems with DB2 Universal Database 



728x90

'Db2 > Db2 reference' 카테고리의 다른 글

HADR 구성 순서  (0) 2011.09.27
link: db2top  (0) 2011.09.18
tablespace 컨테이너 추가할 때의 주의사항  (0) 2011.04.24
DB2 9.7에서 Oracle 기능을 사용하기 위한 순서  (0) 2011.04.21
오늘 날짜 조회하기  (0) 2011.04.21
728x90

테이블 스페이스 데이터들은 같은 스트라이프 셋 안에서 리밸런싱을 일으킵니다.


여기서 말하는 스트라이프 셋은 OS의 스트라이프 셋이 아니며 데이터베이스 테이블 스페이스 레벨에서 데이터를 라운드 로빈 형식으로 흩뿌리는 단위가 되는 세트를 말합니다. 테이블 스페이스가 작성될 때 디폴트로 생성되는 스트라이프 셋 번호는 0으로 새로 스트라이프 셋을 생성할 때마다 1씩 증가합니다.


Note. 스트라이프 셋이 여러 개 생성된 경우 추후, 리스토어가 수행되더라도 스트라이프 셋간 데이터 이동은 일어나지 않습니다. 즉, 리스토어시에는 기존에 존재했던 각 스트라이프 셋에 해당하는 데이터는 해당 스트라이프 셋 내에서만 적재되게 된다는 것입니다.


① 스트라이프 셋을 추가 및 스트라이프 셋 지정 없이 컨테이너를 추가하는 경우

데이터가 중.소 용량이고 데이터 리밸런싱으로 인한 부하가 적다고 판단될 때 스트라이프 셋을 추가하지 않고 컨테이너를 추가하면서 사용하려는 경우에 사용됩니다.


$db2 "alter tablespace <테이블 스페이스 이름> add ( <type> 'container-string' <numer of pages or unitsize> )"

예) db2 “alter tablespace userspace2 add ( file '/db2/db2data1/userspace2.c00005' 5000 , file '/db2/db2data2/userspace2.c00006' 5000 )


기존의 테이블 스페이스에 컨테이너가 여러개 있다면, 각 컨테이너마다 같은 사이즈로 증가시켜주는 것이 좋습니다. 다시말해 테이블 스페이스를 구성하는 각 컨테이너의 사이즈는 동일하게 해주는 것이 좋습니다. 만일 한 컨테이너만 사이즈를 증가시킨다면 리밸런싱이 일어날 뿐만 아니라 추후 컨테이너를 추가할 때마다 리밸런싱이 일어나게 됩니다. 같은 사이즈로 증가시킨다고 해도 일시적으로 리밸런싱이 일어날 수 있으나 경미한 수준입니다.


② 새로운 스트라이프 셋을 추가하여 새로 작성된 스트라이프 셋에 추가하려는 경우

이미 데이터가 대용량이 되어 기존 스트라이프 셋에 추가하면 과도한 리밸런싱이 발생할 수 있는 경우 새로운 스트라이프 셋을 추가하는 것을 권장합니다. 다만, I/O 를 잘 고려하여 새로 컨테이너를 추가할 때 필요한 컨테이너 개수와 분포를 적절히 하여야 합니다. 예를 들어 기존에 여러 개의 컨테이너를 이용하여 사용하다가 새 스트라이프 셋 추가시 이 스트라이프 셋에 아주 적은 수의 컨테이너를 추가한다면 I/O 감소가 있을 수 있고 나중에 추후 컨테이너를 더 추가함으로써 리밸런싱을 일으키게 할 소지가 있으므로 잘 고려하여야 합니다.(기존 컨테이너 개수를 유지하고 충분한 I/O 채널을 확보하는 것이 바람직합니다.)


$db2 "alter tablespace <테이블 스페이스 이름> begin new stripe set ( <type> 'container-string' <numer of pages or unitsize> )"

예) db2 “alter tablespace userspace2 begin new stripe set ( file '/db2/db2data1/userspace2.c00007' 5000 , file '/db2/db2data2/userspace2.c00008' 5000 , file '/db2/db2data2/userspace2.c00009' 5000 , file '/db2/db2data2/userspace2.c00010' 5000 , file '/db2/db2data2/userspace2.c00011' 5000 , file '/db2/db2data2/userspace2.c00012' 5000 )


③ 이미 만들어진 스트라이프 셋 중 특정 스트라이프 셋에 추가하려는 경우

이미 만들어져 있는 스프라이프 셋 중 특정한 스트라이프 셋에 컨테이너를 추가하려는 경우에 사용됩니다.


$db2 "alter tablespace <테이블 스페이스 이름> add to stripe set <stripeset number> ( <type> 'container-string' <numer of pages or unitsize> )"

예) db2 “alter tablespace userspace2 add to stripe set 1 ( file '/db2/db2data1/userspace2.c00013' 5000 , file '/db2/db2data2/userspace2.c00014' 5000 )

728x90
728x90

1. db2set registry variable 설정

레지스트리 값 등록, 확인, 엔진 재시작


db2set db2_compatibility_vector=FFF

db2set -all

db2stop force

db2start



2. clpplus

오라클의 sqlplus와 유사한 유틸리티


$ clpplus db2inst1@localhost:50000/sample

Database Connection Information


Hostname = localhost

Database server = DB2/AIX64  SQL09071

SQL authorization ID = db2inst1

Local database alias = SAMPLE

Port = 50000


CLPPlus: Version 1.1

Copyright (c) 2009, IBM CORPORATION.  All rights reserved.


SQL>

728x90
728x90

$ db2 select current timestamp from sysibm.sysdummy1


1

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

2011-04-21-11.57.52.025165


  1 record(s) selected.



$ db2 values current time


1

--------

15:05:45


  1 record(s) selected.


$ db2 values current date


1

----------

10/22/2011


  1 record(s) selected.


$ db2 values current timestamp

1
--------------------------
2011-10-22-15.06.48.413881

  1 record(s) selected.

728x90
728x90

The DB2_COMPATIBILITY_VECTOR registry variable is used to enable one or more DB2® compatibility features introduced since DB2 Version 9.5.

These features ease the task of migrating applications written for other relational database vendors to DB2 Version 9.5 or later.

Important: Enable these features only if they are required for a specific compatibility purpose. If DB2 compatibility features are enabled, some SQL behavior is changed from what is documented in the SQL reference information. To determine the potential impacts on your SQL applications, see the documentation that is associated with each compatibility setting.
This DB2 registry variable is represented as a hexadecimal value, and each bit in the variable enables one of the DB2 compatibility features.
  • Operating systems: All
  • Default: NULL; Values: NULL or 00 to FFFF. To take full advantage of these DB2 compatibility features, set the value to ORA for Oracle applications and SYB for Sybase applications. These are the recommended settings.

Registry variable settings

Table 1. DB2_COMPATIBILITY_VECTOR values
Bit positionCompatibility featureDescription
1 (0x01)ROWNUMEnables the use of ROWNUM as a synonym for ROW_NUMBER() OVER(), and permits ROWNUM to appear in the WHERE clause of SQL statements.
2 (0x02)DUALResolves unqualified table references to 'DUAL' as SYSIBM.DUAL.
3 (0x04)Outer join operatorEnables support for the outer join operator (+).
4 (0x08)Hierarchical queriesEnables support for hierarchical queries using the CONNECT BY clause.
5 (0x10)NUMBER data type 1Enables the NUMBER data type and associated numeric processing.
6 (0x20)VARCHAR2 data type 1Enables the VARCHAR2 and NVARCHAR2 data types and associated character string processing.
7 (0x40)DATE data type 1Enables use of the DATE data type as TIMESTAMP(0), a combined date and time value.
8 (0x80)TRUNCATE TABLEEnables alternate semantics for the TRUNCATE statement, under which IMMEDIATE is an optional keyword that is assumed to be the default if not specified. An implicit commit operation is performed before the TRUNCATE statement executes if the TRUNCATE statement is not the first statement in the logical unit of work.
9 (0x100)Character literalsEnables the assignment of the CHAR or GRAPHIC data type (instead of the VARCHAR or VARGRAPHIC data type) to character and graphic string constants whose byte length is less than or equal to 254.
10 (0x200)Collection methodsEnables the use of methods to perform operations on arrays, such as first, last, next, and previous. Also enables the use of parentheses in place of square brackets in references to specific elements in an array; for example, array1(i) refers to elementi of array1.
11 (0x400)Data dictionary-compatible views 1Enables the creation of data dictionary-compatible views.
12 (0x800)PL/SQL compilation 2Enables the compilation and execution of PL/SQL statements and language elements.
13 (0x1000)Insensitive cursorEnables cursors defined WITH RETURN to be insensitive if the select-statement does not explicitly specify FOR UPDATE
14 (0x2000)INOUT parameterEnables the specification of DEFAULT for INOUT parameter declarations
17 (0x10000)SQL data access level enforcementEnables run-time routine SQL data access level enforcement
  1. Applicable only during database creation. Enabling or disabling this feature only affects subsequently created databases.
  2. See "Restrictions on PL/SQL support".

Usage

The DB2_COMPATIBILITY_VECTOR registry variable is set and updated using the db2set command. Set theDB2_COMPATIBILITY_VECTOR before creating your database:
  • To enable all of the supported Oracle compatibility features, set the registry variable to the value ORA (equivalent to the hexadecimal value 10FFF).
  • To enable all of the supported Sybase compatibility features, set the registry variable to the value SYB (equivalent to the hexadecimal value 3004).
When the DB2_COMPATIBILITY_VECTOR registry variable is set, all databases created should be created as UNICODE databases.

A new setting for the registry variable does not take effect until after the instance has been stopped and then restarted. Existing DB2 packages must be rebound for the change to take effect; packages that are not rebound explicitly will pick up the change on the next implicit rebind.

Example 1

This example sets the registry variable to enable all of the supported Oracle compatibility features:
db2set DB2_COMPATIBILITY_VECTOR=ORA
db2stop
db2start

Example 2

This example shows how to disable all compatibility features by resetting the DB2_COMPATIBILITY_VECTOR registry variable:
db2set DB2_COMPATIBILITY_VECTOR=
db2stop
db2start
Note that if a database has been created with the NUMBER data type or the VARCHAR2 data type enabled, use of the DATE data type as TIMESTAMP(0) enabled, or the creation of Oracle data dictionary-compatible views enabled, the database will still be enabled for these features after this db2set command executes.

http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.apdv.porting.doc/doc/r0052867.html

728x90
728x90

이번에는 DB2의 고가용성 재해복구에 대해서 알아보도록 하겠습니다. 


DB2의 HADR은 로그 기반으로 동작하고, DB2 ESE 버전에서 단일 노드에 대해서만 동작합니다.

DB2 HADR을 구성하고 테스트하기 위하여 Linux머신 2대를 아래와 같이 HADR로 구성하였습니다.

서버 구성 

Blue01을 Primary로 구성하였고, Blue02를 Standby로 구성하였습니다. 

그리고 두서버에 모두 상대서버를 Alertnate Server로 구성하여 클라이언트가 접속이 끊겼을때 상대 서버를 찾을 

수 있도록 구성하였습니다. 

- Primary 서버 (Blue01)
 
 [db2hard@Blue01 ~]$ db2 list db directory

  System Database Directory
 
  Number of entries in the directory = 1
 
 Database 1 entry:
 
  Database alias                       = SAMPLE
  Database name                        = SAMPLE
  Local database directory             = /home/db2hard
  Database release level               = a.00
  Comment                              =
  Directory entry type                 = Indirect
  Catalog database partition number    = 0
  Alternate server hostname            = Blue02
  Alternate server port number         = 51000

 
 [db2hard@Blue01 ~]$ db2 get db cfg for sample |grep HADR
  HADR database role                                      = PRIMARY
  HADR local host name                  (HADR_LOCAL_HOST) = Blue01
  HADR local service name                (HADR_LOCAL_SVC) = hard_services
  HADR remote host name                (HADR_REMOTE_HOST) = Blue02
  HADR remote service name              (HADR_REMOTE_SVC) = hard_services
  HADR instance name of remote server  (HADR_REMOTE_INST) = db2hard
  HADR timeout value                       (HADR_TIMEOUT) = 120
  HADR log write synchronization mode     (HADR_SYNCMODE) = SYNC
 
 
 - Standby 서버 (Blue02)
 
 [db2hard@Blue02 ~]$ db2 list db directory

  System Database Directory
 
  Number of entries in the directory = 1
 
 Database 1 entry:
 
  Database alias                       = SAMPLE
  Database name                        = SAMPLE
  Local database directory             = /home/db2hard
  Database release level               = a.00
  Comment                              =
  Directory entry type                 = Indirect
  Catalog database partition number    = 0
  Alternate server hostname            = Blue01
  Alternate server port number         = 51000

 
 [db2hard@Blue02 ~]$ db2 get db cfg for sample |grep HADR
  HADR database role                                      = STANDBY
  HADR local host name                  (HADR_LOCAL_HOST) = Blue02
  HADR local service name                (HADR_LOCAL_SVC) = hard_services
  HADR remote host name                (HADR_REMOTE_HOST) = Blue01
  HADR remote service name              (HADR_REMOTE_SVC) = hard_services
  HADR instance name of remote server  (HADR_REMOTE_INST) = db2hard
  HADR timeout value                       (HADR_TIMEOUT) = 120
  HADR log write synchronization mode     (HADR_SYNCMODE) = SYNC

 위의 설정정보에서 확인한것 같이 Blue01과 Blue02가 Peer상태로 정상 동작하고 있는 것을 확인할 수 있습니다. 

클라이언트 연결 및 Query 실행 

클라이언트는 테스트의 편의를 위하여 CLP를 사용하였습니다. 
 
C:\Program Files\IBM\SQLLIB\BIN>db2 connect to hadr_sam user db2hard
db2hard의 현재 암호를 입력하십시오.
 
  데이터베이스 연결 정보
 
  데이터베이스 서버                        = DB2/LINUX 8.2.7
  SQL 권한 부여 ID                         = DB2HARD
  로컬 데이터베이스 별명                   = HADR_SAM
 
 
 C:\Program Files\IBM\SQLLIB\BIN>db2 "select * from employee fetch first 1 rows o
 nly"
 
 EMPNO  FIRSTNME     MIDINIT LASTNAME        WORKDEPT PHONENO HIREDATE   JOB
  EDLEVEL SEX BIRTHDATE  SALARY      BONUS       COMM
 ------ ------------ ------- --------------- -------- ------- ---------- --------
  ------- --- ---------- ----------- ----------- -----------
 000010 CHRISTINE    I       HAAS            A00      3978    1965-01-01 PRES
       18 F   1933-08-24    52750.00     1000.00     4220.00
 
   1 레코드가 선택됨.
   
   정상적으로 Primary서버(Blue01)에 정사적으로 로그인 되고, Query가 정상 수행 되었습니다. 

Primary서버(Blue01) 이상발생 

Primary서버(Blue01)에 이상을 발생시키기 위해 db2sysc 프로세스를 강제 종료합니다. 
 
 [db2hard@Blue01 ~]$ ps -ef |grep db2sysc
 db2hard  19260 19259  0 01:34 ?        00:00:00 db2sysc 0                                      
 db2hard   2574  1166  0 11:24 pts/0    00:00:00 grep db2sysc
 [db2hard@Blue01 ~]$ kill -9 19260
 
 Primary서버(Blue01) 이상 발생 클라이언트 동일 Query 실행시 계속 대기합니다. 
 
 C:\Program Files\IBM\SQLLIB\BIN>db2 "select * from employee fetch first 1 rows o
 nly"
 
 클라이언트 대기 상태 
 
Standby서버(Blue02) 상태 확인 및  인계작업 수행 

Standby서버(Blue02) 인계작업 수행전에 우선 Standby서버의 HADR상태를 확인합니다. 
 
 HADR Status
   Role                   = Standby
   State                  = Remote catchup pending
   Synchronization mode   = Sync
   Connection status      = Disconnected, 03/03/2007 11:25:40.214866
   Heartbeats missed      = 0
   Local host             = Blue02
   Local service          = hard_services
   Remote host            = Blue01
   Remote service         = hard_services
   Remote instance        = db2hard
   timeout(seconds)       = 120
   Primary log position(file, page, LSN) = S0000002.LOG, 37, 00000000017959D5
   Standby log position(file, page, LSN) = S0000002.LOG, 37, 00000000017959D5
   Log gap running average(bytes) = 0
   
  Standby서버(Blue02)의 상태는 현재 Primary서버(Blue01)과 연결이 끊어져서 현재 Remote catchup Pending 상태입니다. 
  
  
  Primary서버와 Standby서버가 연결이 종료되었을 경우는 TAKEOVER작업에 BY FORCE 옵션을 사용하여 인계작업을 수행합니다. 
  
 [db2hard@Blue02 ~]$ 
db2 "TAKEOVER HADR on DATABASE SAMPLE BY FORCE"
 DB20000I  The TAKEOVER HADR on DATABASE command completed successfully.
 
 정상적으로 TAKEOVER작업이 수행된 후에 클라이언트 Query 결과가 아래와 같이 출력됩니다. 
 
 C:\Program Files\IBM\SQLLIB\BIN>db2 "select * from employee fetch first 1 rows o
 nly"
 SQL30108N  연결이 실패했으나 다시 연결되었습니다. 호스트 이름 또는 IP 주소는
 "Blue02"이고 서비스 이름 또는 포트 번호는 "51000"입니다. 특수 레지스터는 다시
 시도되거나 시도되지 않을 수 있습니다(이유 코드 = "1").  SQLSTATE=08506

 
 위와 같이 결과가 출력되면 다시 동일 Query 수행시 Blue02서버로 접속이 연결되어 정상적으로 Query가 실행됩니다. 
 
 C:\Program Files\IBM\SQLLIB\BIN>db2 "select * from employee fetch first 1 rows o
 nly"
 
 EMPNO  FIRSTNME     MIDINIT LASTNAME        WORKDEPT PHONENO HIREDATE   JOB
  EDLEVEL SEX BIRTHDATE  SALARY      BONUS       COMM
 ------ ------------ ------- --------------- -------- ------- ---------- --------
  ------- --- ---------- ----------- ----------- -----------
 000010 CHRISTINE    I       HAAS            A00      3978    1965-01-01 PRES
       18 F   1933-08-24    52750.00     1000.00     4220.00
 
   1 레코드가 선택됨.
   
 그리고 Standby서버 역확을 수행했던 Blue02 서버에서 클라이언트의 연결을 확인할 수 있습니다. 
 
 [db2hard@Blue02 ~]$ db2 list applications

 Auth Id  Application    Appl.      Application Id                 DB       # of
          Name           Handle                                    Name    Agents
 -------- -------------- ---------- ------------------------------ -------- -----
 DB2HARD  db2bp.exe      844        C0A8018F.H60E.00BE83021856     SAMPLE   1   

마지막으로 Blue02서버의 HADR의 상태 변경을 확인하면 됩니다.

HADR Status
   Role                   = Primary
   State                  = Disconnected

   Synchronization mode   = Sync
   Connection status      = Disconnected, 03/03/2007 11:25:40.214866
   Heartbeats missed      = 0
   Local host             = Blue02
   Local service          = hard_services
   Remote host            = Blue01
   Remote service         = hard_services
   Remote instance        = db2hard
   timeout(seconds)       = 120
   Primary log position(file, page, LSN) = S0000002.LOG, 38, 0000000001796057
   Standby log position(file, page, LSN) = S0000000.LOG, 0, 0000000000000000
   Log gap running average(bytes) = 0
   
 Standby역활로 실행되었던 Blue02서버가 현재 Primary서버의 이상으로 인계작업을 수행하여 
 Primary역활로 변경된 것을 확인할 수 있으며 상태는 Disconnected입니다. 
 
 
     - 현재상태로 계속해서 시스템의 운영이 가능합니다.
       아래에 나오는 작업을 복구를 위한 작업입니다.
 
 
 
인계작업 완료후 복구 작업
 
 Blue01 서버에서 DB2 Instance를 다시 시작하고 HADR을 Standby로 시작합니다. 
 
 [db2hard@Blue01 ~]$ db2start
 03/03/2007 11:43:32     0   0   SQL1063N  DB2START processing was successful.
 SQL1063N  DB2START processing was successful.
 [db2hard@Blue01 ~]$ 
db2 "START HADR on DATABASE SAMPLE AS STANDBY"
 SQL1766W  The command completed successfully. However, LOGINDEXBUILD was not 
 enabled before HADR was started.  SQLSTATE=00000


 Primary 서버(Blue02) 상태 확인 
 
 HADR Status
   Role                   = Primary
   State                  = Peer

   Synchronization mode   = Sync
   Connection status      = Connected, 03/03/2007 11:45:02.582553
   Heartbeats missed      = 0
   Local host             = Blue02
   Local service          = hard_services
   Remote host            = Blue01
   Remote service         = hard_services
   Remote instance        = db2hard
   timeout(seconds)       = 120
   Primary log position(file, page, LSN) = S0000002.LOG, 38, 0000000001796057
   Standby log position(file, page, LSN) = S0000002.LOG, 38, 0000000001796057
   Log gap running average(bytes) = 51912
 
 Standby 서버(Blue01) 상태 확인 
 
 HADR Status
   Role                   = Standby
   State                  = Peer

   Synchronization mode   = Sync
   Connection status      = Connected, 03/03/2007 11:43:53.856276
   Heartbeats missed      = 0
   Local host             = Blue01
   Local service          = hard_services
   Remote host            = Blue02
   Remote service         = hard_services
   Remote instance        = db2hard
   timeout(seconds)       = 120
   Primary log position(file, page, LSN) = S0000002.LOG, 38, 0000000001796057
   Standby log position(file, page, LSN) = S0000002.LOG, 38, 0000000001796057
   Log gap running average(bytes) = 33156
   
   
 최초에 역활과 반대로 지금은 Blue02서버가 Primary 역활을 수행하고 있으며, Blue01서버가 Standby역확을 수행하고 있습니다. 그리고 상태도 Peer상태로 정상적으로 운영되고 있습니다. 
 
 
 현재 상태로 운여하다가 다시 Standby 서버(Blue01)에서 TAKEOVER 작업을 수행하여 원래의 구성으로 돌아갈 수 있습니다.

TAKEOVER 작업을 통한 역활 변경

 [db2hard@Blue01 ~]$ db2 "TAKEOVER HADR on DATABASE SAMPLE"
 DB20000I  The TAKEOVER HADR on DATABASE command completed successfully.
 
 
 Primary 서버(Blue01) 상태 확인 
 
 HADR Status
   Role                   = Primary
   State                  = Peer

   Synchronization mode   = Sync
   Connection status      = Connected, 03/03/2007 11:43:53.856276
   Heartbeats missed      = 0
  Local host             = Blue01
   Local service          = hard_services
   Remote host            = Blue02
   Remote service         = hard_services
   Remote instance        = db2hard
   timeout(seconds)       = 120
   Primary log position(file, page, LSN) = S0000002.LOG, 38, 00000000017966C9
   Standby log position(file, page, LSN) = S0000002.LOG, 38, 00000000017966C9
   Log gap running average(bytes) = 872

 Standby 서버(Blue02) 상태 확인 
 
 HADR Status
   Role                   = Standby
   State                  = Peer

   Synchronization mode   = Sync
   Connection status      = Connected, 03/03/2007 11:45:02.582553
   Heartbeats missed      = 0
   Local host             = Blue02
   Local service          = hard_services
   Remote host            = Blue01
   Remote service         = hard_services
   Remote instance        = db2hard
   timeout(seconds)       = 120
   Primary log position(file, page, LSN) = S0000002.LOG, 38, 00000000017966C9
   Standby log position(file, page, LSN) = S0000002.LOG, 38, 00000000017966C9
   Log gap running average(bytes) = 820
   
 처음 Test를 시작할 때의 상태로 복원 되었습니다. 
  
Client 연결확인 

 
[db2hard@Blue01 ~]$ db2 list applications

 Auth Id  Application    Appl.      Application Id                 DB       # of
          Name           Handle                                    Name    Agents
 -------- -------------- ---------- ------------------------------ -------- -----
 DB2HARD  db2bp.exe      19         C0A8018F.HC0E.00BE83023817     SAMPLE   1  

클라이언트 연결도 Blue01서버로 다시 연결된것을 확인할 수 있습니다. 

이상과 같이 DB2 HADR의 Primary서버의 문제발생시 Standby서버로의 인계작업 수행 및 복원 과정 그리고 

클라이언트의 연결 변경과정을 확인하여 보았습니다.

그래도 문제가 있죠.. ㅋㅋㅋ 자동으로 인계작업을 발생했으면 좋으련만 Standby서버는 Rollforward 상태로 

남아 있기 때문에 항상 TAKEOVER 작업을 수행해야만 접속이 가능하다는 문제가 있네요.

[db2hard@Blue02 ~]$ db2 get snapshot for database on sample

              Database Snapshot

Database name                              = SAMPLE
Database path                              = /home/db2hard/db2hard/NODE0000/SQL00001/
Input database alias                       = SAMPLE
Database status                            = Rollforward


그래도 문제 발생시 시스템 전체를 다시 시작하거나 또는 DB2 Instance 다시 시작등과 같이 오랜시간 동안의 작업을 대신하여 빠른 시간에 TAKEOVER작업을 수행할 수 있다는 장점과 Client연결을 Alertnate Server기능을 사용하여 유지하고클라이언트 사용자의 접속을 유지할 수 있다는 장점은 좋은것 같습니다.



http://halfork.tistory.com/entry/DB2-HADR-%EA%B3%A0%EA%B0%80%EC%9A%A9%EC%84%B1-%EC%9E%AC%ED%95%B4%EB%B3%B5%EA%B5%AC

728x90

'Db2 > Db2 reference' 카테고리의 다른 글

오늘 날짜 조회하기  (0) 2011.04.21
DB2_COMPATIBILITY_VECTOR registry variable  (0) 2011.04.21
파티션된 데이터베이스(DPF) 환경에서 데이터 로드  (0) 2011.04.16
db2 link  (0) 2011.04.07
[교육정리] transaction log  (0) 2011.03.17

+ Recent posts