Know/DATABASE

JDBC FAILOVER 구현예제

Marine™ 2006. 7. 12. 14:04
반응형
[출처: http://blog.naver.com/jaegoan/30002390193 ]

java.sql.SQLException: IO 예외 상황: The Network Adapter could not establish the connection

No. 19100

JDBC Thin driver 사용시 connect time fail-over 지정 방법 (JDBC 8.1.7이상)
==========================================================================

PURPOSE
-------

JDBC Thin driver를 통해 오라클에 접속하는 경우, 기본적으로 hostname
(혹은 ip address)와, 데이타베이스의 SID를 이용하여 접속하게 된다.

이러한 방식으로는, OPS/RAC 환경에서 jdbc thin 방식을 통해, connect time시
fail-over가 불가능하게 된다.

이 문서에서는 JDBC Thin방식을 사용하면서, connect-time을 구현하기 위한
방법을 설명한다.

[주의] 단 이것은 이미 연결된 session이 fail시 자동으로 다른 instance로
자동 연결되어 session의 끊김 현상을 피하게 해주는 TAF (Transparent
Application Failover)에 대한 것은 아니다. JDBC Thin에서는 TAF를
지원하지 못한다.


Explanation & Example
---------------------

다음 순서대로 설정한다. 아래의 지정 방법을 살펴보면 1번 ~ 3번까지는
일반적인 connect time fail-over구현을 위해 필요한 방법이고, 결국 4번이
내용이 jdbc thin을 위해 추가된 것이다.

이것은 Oracle 8.1.7/jdbc 8.1.7을 이용하여 test되었으며, OPS환경이고
각 instance의 hostname은 krtest1, krtest2로 가정하고, 각 listener의
port는 1521을 사용한다고 가정한다. db name은 TESTDB로 가정한다.


1. initial prameter 지정

다음과 같이 두개의 instance 각각에 local_listener와 service_names를
지정하여, listener에 대해 dynamic service registration이 가능하도록 한다.
local_listener는 listener.ora에 정의된 listener정보를 다음과 같이 직접
적거나, 혹은 이 정보를 tnsnames.ora에 지정후 해당 listener alias를
적어도 된다.

service_names는 콤마(,)로 구분하여 복수개를 지정하여도 되면 단 두
instance가 다음과 같이 공통된 값을 최소한 하나는 가지도록 한다.
일반적으로 default값이 db_name과 같은 값을 가지도록 하면 된다.

이 두 parameter는 $ORACLE_HOME/dbs/initSID.ora에 지정하거나, 9i이상에서
spfile을 사용하는 경우는 atler system 명령을 통해 지정하면 된다.


local_listener="(ADDRESS=(PROTOCOL=TCP)(HOST=krtest1)(PORT=1521))"
service_names=TESTDB

local_listener="(ADDRESS=(PROTOCOL=TCP)(HOST=krtest2)(PORT=1521))"
service_names=TESTDB


2. SQL*Net configuration

(1) client side의 tnsnames.ora

다음과 같이 tnsnames.ora에 connect-time failover를 위한 service alias를
지정한다. 여기서는 krtest1에 처음 접속을 시도하게 되고 krtest1이 down인
경우 krtest2로 접속하게 된다.

TEST =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS =
(PROTOCOL = TCP)
(HOST = krtest1)
(PORT = 1521))
(ADDRESS =
(PROTOCOL = TCP)
(HOST = krtest2)
(PORT = 1522)))
(CONNECT_DATA =
(SERVICE_NAME = TESTDB)))

(2) client side의 sqlnet.ora
앞의 tnsnames.ora에 TEST정의시 TEST.WORLD라고 하지 않았으므로 sqlnet.ora에도

names.default_domain = world

와 같은 지정이 있으면 지우거나 #으로 주석처리한다.

(3) server side의 listener.ora

listener.ora에는 sid_list_listener명 에 대한 부분은 포함시키지 않도록 한다.
sid_list_listener가 있으면 krtest1의 listener가 down된 경우에는 fail over가
되나 krtest1의 listener가 살아 있는 상태에서 krtest1의 instnace만 down된
상태에서는 connect-time fail over가 실패하게 된다.

즉, lsnrctl statue에 instance가 down되어도 sid에 대한 정보가 나타나게 되면서,
일단 krtest1에서 client의 request를 받아들이게 되고, 그 후에 해당 instance와
연결시키면서 instance가 down된것을 알게되어 오류가 발생하는 것이다.

그러나 sid_list_listener 부분을 제거하게 되면 krtest1의 instance가 down되면
lsnrctl status상에 해당 instnace의 service정보가 나타나지 않아 client의
connect request에 대해서 listner가 바로 instance가 down된것을 알고 krtest2로
넘기는 것이 가능하게 된다.


3. SQL*Plus 상에서 해당 service name (alias)를 이용하여 접속 확인

먼저 정상적으로 krtest1 쪽의 instance가 정상인경우 접속이 잘 되는지를
test해보고, 접속이 잘되면 이번에는 krtest1쪽의 instnace를 down시켜둔
상태에서 다시 같은 TEST alias를 이용하여 접속하여 자동으로 krtest2쪽으로
접속이 잘 되는지를 확인해 본다.

sqlplus scott/tiger@TEST



4. JDBC getConnection() 절 지정

(1)번의 기존 방식대신 (2)번과 같이 sqlplus상에서 사용된 tns descriptor를 그대로
이용하여 getConnection에 지정하면 된다.

(1) 기존 지정방법:
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@krtest1:
1521:TESTDB", "scott", "tiger");

(2) 변경된 지정 방법:
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@(DESCRIPTIO
N = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP) (HOST = krtest1) (PORT = 1521))
(ADDRESS = (PROTOCOL = TCP) (HOST = krtest2) (PORT = 1521))) (CONNECT_DATA =
(SERVICE_NAME = MIKE.us.oracle.com))) ", "scott", "tiger");


Reference Documents
-------------------
반응형

'Know > DATABASE' 카테고리의 다른 글

DB2 HADR 문서  (0) 2006.09.09
DB2 JDBC TYPE  (0) 2006.07.13
rollup  (0) 2006.02.15
IBM WebSphere 5.0 데이타베이스 연결 설정법  (0) 2005.06.23
ERROR 2006 : MySQL server has gone away  (0) 2005.06.21