Site icon DBA의 정석

TAF 란?

 

TAF – Connection Failover options

 

 

전제 사항 : Oracle Server는 RAC로 구성되어야 한다.

OCI를 이용하지 않은 Application은 TAF를 위한 특별한 기능을 제공 하지 않으며, 개발자가 Logic을 구현해야 한다.

TAF를 위한 Server Configuration은 이 문서에서 고려하지 않는다. CONNECTION TIME FAIL OVER는 이 문서에서 고려하지 않는다. 위의 사항들을 시간의 여유가 있을 경우에는 작성한다.

 

 

 

TAF는 RAC를 사용하는 환경에서 가용성을 극대화 하기 위해 제공 되는 기능이며, 모든 Application을 적용하기 보다는 중요한 Application에 대해서만 적용토록 한다.

TAF 적용시 고려 사항들

 

구  분

  내    용

  고려사항

CTF(Connection Time FailOver)

데이터 베이스로 접속하는 순간에 Server, DB, Listener등이 가용하 지 않을 경우에 다른 쪽 Server로 접속하는 것을 말함.

OCI를 사용하지 않는 프로그램은 매뉴얼 하게 Logic를 구사해야 한다.

TAF(Run Time FailOver)

접속 후 데이터 베이스 사용 중에 DB나 Session이 장애가 발생 했 을 경우에 다른 node로 접속하여 진행하던 작업을 계속할 수 있도 록 하는 것을 말함.

OCI를 사용할 경우에는 오라클에서 CallBack method를지 원하나 OCI를 사용하지 않을 경우에는 Logic으로 구사해야 함

FailOver 방법

TAF에서 제공하는 Failover 방법들을 말함. Mode : session, select

Method : Basic , Preconnect

Long s elect수행중 장애 발생시 수행하던 작업을 넘기기 위해서는 ‘s elect’로 해야 하며 ‘session’으로 하면 session 만 넘어가고 SQL은 다시 수행해야 함.

Basic은 장애 발생시 다시 접속하는 방법이고, preconnect는 최초 접속시 다른 node에 미리

Language 별

모든 programming language 를 TAF가 지원하지는 않고 OCI를사용하는 language 만을 지원 한다.

OCI를 사용하지 않는 Language 의 경우에는 자체적으로

Logic으로 처리해 한다. Ex) java thin driver사용시

장애 유형별 사용 여부

장애 유형별 TAF를 사용해야 할지 결정한다.

여러 가지 장애에 따라, TAF를 사용할 Error와 사용하지않 을 Error를 구분하여 적용해야 함.

적용할 Application 선정

위의 내역들을 모두 고려하여 CTF, TAF를 적용한 Application을선 정한다. 이때 너무 많은 Application을 고려 할 경우에는 상황의 복 잡함에 시스템의 안정화에 나쁜 영향을 줄 수 있다.

프로그램의 중요도에 따라 CTF, TAF를 적용할 Application 을 선정하며, 다양한 Error에 대한 조치사항을 적절하게 적용해야 한다.

 

 

TAF에는 여러 가지 mode 및 method가 있는데, 각 Application에 적합한 TAF방법을 결정한다.

 

Method/ Mod

SESSION

SELECT

BASIC

장애 발생시 client는 자동적으로 다른 node로 Login이 된다. 만약 수행하던 Select문이 있을 경우 에는 다시 수행해야 한다.

Query를 수행하는 동안 장애가 발생하면 자동으로 다른 node로 Log in이 되며, 수행하던 Query를 자동으로 다시 수행하게 된다.

PRECONNECT 

Client는 접속 시 2개의 node에 모두 접속한다.

이러한 방식은 장애 발생시 접속의 부하를 줄일 수 있다. 물로 양쪽 node에 접속하고 있으므로 접속에 대한 부담

이 존재한다.

Client는 접속 시 2개의 node에 모두 접속한다.

 
 
 

 

제약사항 :OCI(NET8)을 사용하는 Application에 한 해서 적용가능 하다.

만약 OCI를 사용하지 않는 Application은 Manual하게 조치해야 함. 성능 측면에서 Application Partitioning후에 TAF로 Failover는 RAC의 부담을 줄 수 있으므로 이에 대한 고려도 필요함(ping의 부하)

 

 

 TAF Application 선택 기준

 

적용 여부

Application의 성격

TAF 적용

24X365로 수행되는 Application(daemon 형태의 프로그램으로 자체적으로 재기동 할 수 없는Application)

중요 Transaction을 포함하는 Application

TAF 미적용

단순 조회 Web Application

C/ S 환경의 조회 Application

다시 시작해도 되는 Transaction을 가진 Application

 

 

Application TAF 적용 단계 Flow

 

 


 

 

 

 

 개발 언어에 따른 TAF 사용 여부

Java, C++, etc

 

TAF를 사용 가능한 Client Application Product

 

Product

구분

Oracle Call Inte rface

Release 8

ODBC driver

Release 8.0.5

JDBC driver

Release 8 (thick driver only)

Pro*C

Release 8i

SQL*Plus

Release 8.0.4

Oracle Object for OLE

Release 8i(Planned)

 

 

특수한 사용 형태에 따른 고려사항.

Java의 Connection Pool 형태의 Connection에 대한 TAF 구현방법 모색.

OCI를 사용하지 않는 Application 은 자체적으로 Error를 탐지 하여 프로그램 내에 서 Logic으로 처리하여야 한다.

 

 

 

 


 


 

 

 

장애의 유형에 따라 TAF를 사용하는 경우와 사용하지 않는 경우를 구분하여 나누어 고려한다.


 

Error 번호

Error 내용

사용중 장애(TAF 함)

ORA- 01034

ORA- 3113, ORA- 3114

ORA- 1033

ORA- 25401

ORA- 00020

Oracle Not Available Instance Down Shutdown progress

Cannot Continue Fetch(Fetch 중 Error)

Maximum number of processes xx exceeded

접속 시 장애(CTF 함)

ORA- 12541

ORA- 01034

TNS:nolis tener Oracle Not Available

일반 Error(TAF하지 않음)

Others

일반 SQL수행시 발생하는 Error는 TAF에 적용하지 않는다. Ex) extent error나 unique violation error등.

 

 

장애의 복구를 위한 시도에 대한 제한(예, 10회)을 두어 장기적인 장애시 불필요한 자원 낭비를 예방한다.

   

 FailOver(TAF)의 경우에 아래의 몇 가지 정보들을 잃어버리게 되므로, TAF를 적용하기로선정 된 Application내에서 잃어버린 정보에 대한 처리 Logic을 넣어야 한다.


FailOver될 때, RAC환경 의 Global Loc에 대한 remastering 작업으로 약간의 지체 현상이 나타날 수 있다.

 

 

종 류

내 용

PL/ SQL Pac kage s tatus

Package 의 global 변수 같은 정보는 손실됨

Alter Sess ion Statement

Alter s ess ion을 이용한 작업은 손실 되며, 이는 TAF후에 다시 적용하여수 행 해야 한다.

진행중인 Trans action

Trans action은 반드시 rollbac k한후 작업을 진행할수 있다.

Cursor

Cursor를 열고 연속적인 작업을 하는 것은 e rro r를 발생할수 있다. (ora-

25401)

Temporary table data

Temporary table을 사용하는 정보는 잃어버린다.

Lob loc ator reads

 

 

 

 

 

 

OCI를 사용하는 경우의 CTF


 

 

OCI 없이 CTF 구현


 

OCI를 사용하는 경우의 TAF


 

OCI 없이 TAF 구현

 

 

 

TAF Sample 프로그램

 

Test환경 환경 Server : THVSD01, THVSD02

Java : Thick(OCI에서 제공되는 callback이용), Thin(Logic으로 처리)

User : oraerp01

 

 

Listener.ora 내역 내역

 

 

listener.ora(node 1)

 

ERP01 =

(ADDRESS_LIST =

(ADDRESS= (PROTOCOL= IPC)(KEY= EXTPROCERP01))

(ADDRESS= (PROTOCOL= TCP)(Host= td01_net)(Port= 1812)) )

 

listener.ora(node 2)

 

ERP02 =

(ADDRESS_LIST =

(ADDRESS= (PROTOCOL= IPC)(KEY= EXTPROCERP01))

(ADDRESS= (PROTOCOL= TCP)(Host= td02_net)(Port= 1812)) )

 

 

Tnsnames.ora

 

TAF_ERP01=

(DESCRIPTION_LIST=

(DESCRIPTION=

(FAILOVER=on)

(ADDRESS_LIST =

(ADDRESS=(PROTOCOL=tcp)(HOST=TD01_net) (PORT=1812))

(ADDRESS=(PROTOCOL=tcp)(HOST=TD02_net) (PORT=1812))

)

(CONNECT_DATA=

(SERVICE_NAME=ERP)

(FAILOVER_MODE=

(BACKUP=TAF_ERP01)

(TYPE=SELECT)

(METHOD=BASIC)

) ) )

)

 

 

TAFwithOCI.java Sample

 

//OCI 를 이용한 Sample로 로써 써 CallBack Class 를 이용하여 처리한다.

// You need to import java.sql and oracle.jdbc packages to use

// JDBC OCI failover callback

import java.sql.*;

import java.net.*;

import java.io.*;

import java.util.*;

import oracle.jdbc.OracleConnection;

import oracle.jdbc.OracleOCIFailover;

public class TAFwithOCI {

static final String user = “scott”;

static final String password = “tiger”;

static final String driver_class = “oracle.jdbc.driver.OracleDriver”;

static final String URL = “jdbc:oracle:oci8:@TAF_ERP01”;

public static void main (String[] args) throws Exception {

Connection conn = null;

CallBack fcbk= new CallBack();

String msg = null;

Statement stmt = null;

ResultSet rset = null;

// Load JDBC driver

try {

Class.forName(driver_class);

}

catch(Exception e) {

System.out.println(e);

}

// Connect to the database

conn = DriverManager.getConnection(URL, user, password);

// register TAF callback function

((OracleConnection) conn).registerTAFCallback(fcbk, msg);

// Create a Statement

stmt = conn.createStatement ();

for (int i=0; i<30; i++) {

// Select the ENAME column from the EMP table

rset = stmt.executeQuery (” select to_char(sysdate,’YYYY MM DD HH24:MI:SS’)|| ” +

” ‘[‘||instance_name||’][‘||host_name||’]’ from v$instance “);

 

 

TAFwithOCI.java Sample

 

// Iterate through the result and print the employee names

while (rset.next ())

System.out.println (rset.getString (1));

// Sleep one second to make it possible to shutdown the DB.

Thread.sleep(1000);

} // End for

rset.close();

stmt.close();

conn.close();

} // End Main()

} // End class jdemofo

/* * Define class CallBack */

class CallBack implements OracleOCIFailover {

// TAF callback function

public int callbackFn (Connection conn, Object ctxt, int type, int event) {

/*********************************************************************

* There are 7 possible failover event

* FO_BEGIN = 1 indicates that failover has detected a

* lost conenction and faiover is starting.

* FO_END = 2 indicates successful completion of failover.

* FO_ABORt = 3 indicates that failover was unsuccessful,

* and there is no option of retrying.

* FO_REAUTH = 4 indicates that a user handle has been re-

* authenticated.

* FO_ERROR = 5 indicates that failover was temporarily un-

* successful, but it gives the apps the opp-

* ortunity to handle the error and retry failover.

* The usual method of error handling is to issue

* sleep() and retry by returning the value FO_RETRY

* FO_RETRY = 6

* FO_EVENT_UNKNOWN = 7 It is a bad failover event

*********************************************************************/

String failover_type = null;

switch (type) {

case FO_SESSION:

failover_type = “SESSION”;

break;

case FO_SELECT:

failover_type = “SELECT”;

break;

default:

failover_type = “NONE”;

}

 

switch (event) {

case FO_BEGIN:

System.out.println(ctxt + “: “+ failover_type + ” failing over…”);

break;

case FO_END:

System.out.println(ctxt + “: failover ended”);

break;

case FO_ABORT:

System.out.println(ctxt + “: failover aborted.”);

break;

case FO_REAUTH:

System.out.println(ctxt + “: failover.”);

break;

case FO_ERROR:

System.out.println(ctxt + “: failover error gotten. Sleeping…”);

// Sleep for a while

try {

Thread.sleep(100);

}

catch (InterruptedException e) {

System.out.println(“Thread.sleep has problem: ” + e.toString());

}

return FO_RETRY;

default:

System.out.println(ctxt + “: bad failover event.”);

break;

}

return 0;

}

}

 

 

TAFwithLogic.java Sample

 

// 장애에 대한 처리를 Application 에서 Logic으로 처리한다 으로 처리한다

import java.io.*;

import java.util.*;

import java.sql.*;

import java.text.*;

public class TAFwithLogic

{

public static void main( String[] args ) throws Exception

{

DriverManager.registerDriver( new oracle.jdbc.driver.OracleDriver() );

Connection conn = null;

Statement stmt = null;

//while ( true )

for(int i = 1; i < 100; i++)

{

if ( conn == null )

try

{

conn = DriverManager.getConnection( “jdbc:oracle:oci8:@TAF_ERP01”, “apps”, “apps” );

System.out.println ( “[” + DateFormat.getDateTimeInstance().format( new java.util.Date() ) +

“] Connection Success” );

}

catch ( SQLException e )

{

System.out.println ( “[” +

DateFormat.getDateTimeInstance().format( new java.util.Date() ) + “] Connect FAIL!!” );

System.out.println( e );

Thread.sleep( 1000 );

continue;

}

try

{

stmt = conn.createStatement();

//ResultSet rs = stmt.executeQuery( “select sid froM v$session” );

ResultSet rs = stmt.executeQuery(

” select to_char(sysdate,’YYYY MM DD HH24:MI:SS’)|| ” +

” ‘[‘||instance_name||’][‘||host_name||’]’ from v$instance ” );

rs.next();

System.out.println(rs.getString(1));

stmt.close();

Thread.sleep( 1000 ); // wait 1 second

}

catch ( SQLException e ) // SQL 수행중에 Error가 발생하 가 발생하 면 다시 접속한다 한다.

{

System.out.println ( “[” +

DateFormat.getDateTimeInstance().format( new java.util.Date() ) + “] Select FAIL!!” );

System.out.println( e );

conn = null;

}

}

}

}

 

Exit mobile version