6. Fail-Over#
이 장은 Altibase C 인터페이스를 이용해서 Failover 관련 작업을 수행하는 방법을 설명한다.
개요#
Fail-Over는 DBMS 운영 도중 장애가 발생하였을 때 이를 극복하고 장애가 발생하지 않은 것처럼 서비스를 계속할 수 있도록 하는 것을 의미한다.
예를 들어, 질의 수행 중 서버와의 연결이 끊기게 되면 클라이언트가 가용한 서버에 자동으로 접속을 시도하도록 하는 것이다. 이를 이용하면 응용 프로그램이 연결부터 다시 시도할 필요 없이, 직전에 수행하던 작업을 즉시 재실행 할 수 있을 것이다.
이에 대한 보다 자세한 내용은 Replication Manual을 참고한다.
사용법#
이 절은 응용 프로그램에서의 Failover 관련 작업 작성을 위해 제공되는 자료 구조와 그 사용법에 대해서 설명한다.
관련 자료 구조#
응용 프로그램에서의 Failover 관련 작업 작성을 지원하기 위해, Altibase는 다음의 Failover 이벤트 값과 콜백 함수를 위한 함수 포인터를 제공한다.
enum ALTIBASE_FAILOVER_EVENT#
Failover 이벤트를 담고 있는 열거형이다. 사용자가 Failover 콜백 함수를 등록했다면, 등록된 함수의 event 인자를 통해서 아래의 이벤트 값 중의 하나를 전달받을 것이다. 또한, Failover 콜백 함수에서 Failover의 다음 과정을 계속 진행할 것인지 여부를 클라이언트 라이브러리로 반환할 때에도 이 값을 사용하면 된다.
값 | 설명 |
---|---|
ALTIBASE_FO_BEGIN | STF (Service Time FailOver)가 시작됨을 FailOver 콜백에게 알려주는 이벤트 |
ALTIBASE_FO_END | STF가 성공하였음을 FailOver 콜백에게 알려주는 이벤트 |
ALTIBASE_FO_ABORT | STF가 실패하였음을 FailOver 콜백에게 알려주는 이벤트 |
ALTIBASE_FO_GO | STF의 다음 과정을 계속 진행할 것을 지시하는 이벤트로, FailOver 콜백이 클라이언트 라이브러리에 반환하는 값 |
ALTIBASE_FO_QUIT | STF의 다음 과정을 진행하지 말 것을 지시하는 이벤트로, FailOver 콜백이 클라이언트 라이브러리에 반환하는 값 |
콜백 함수 포인터#
다음은 Failover 콜백 함수 작성을 위해 Altibase에서 제공하는 함수 포인터이다.
typedef ALTIBASE_FAILOVER_EVENT (*altibase_failover_callback_func)
(
ALTIBASE altibase,
void *app_context,
ALTIBASE_FAILOVER_EVENT event
);
app_context 인자는 사용자가 작성한 Failover 콜백 함수 내에서 사용할 데이터를 전달받기 위해 사용된다. altibase_set_failover_callback() 으로 콜백 함수를 등록할 때 사용하고자 하는 자료 구조의 포인터를 전달했으면, 이 후 Failover 발생 시 콜백 함수가 호출되면서 app_context 인자로 이것이 다시 전달될 것이다.
event 인자는 어떤 콜백 이벤트가 발생되었는지를 콜백 함수에게 알려주는 역할을 한다. 이벤트에 대한 자세한 내용은 "enum ALTIBASE_FAILOVER_EVENT" 절을 참고한다.
Failover 콜백 등록#
이 절은 Failover 발생 시 사용될 콜백 함수와 콜백 함수가 참조할 데이터의 포인터를 등록하는 방법을 설명한다. 반드시 서버와의 연결에 성공한 후에 콜백 함수를 등록해야 한다.
아래는 콜백 함수를 등록하는 소스 코드 예제이다.
#define CONNSTR "DSN=127.0.0.1;PORT_NO=20300;UID=sys;PWD=manager;" \
"AlternateServers=(192.168.3.54:20300,192.168.3.53:20300);" \
"ConnectionRetryCount=3;ConnectionRetryDelay=5;" \
"LoadBalance=on;SessionFailOver=on;"
/* ... omit ... */
if ((altibase = altibase_init()) == NULL)
{
/* ... error handling ... */
}
rc = altibase_connect(altibase, CONNSTR);
/* ... check return value ... */
rc = altibase_set_failover_callback(altibase, my_callback_func, &my_context);
/* ... check return value ... */
/* ... omit ... */
rc = altibase_set_failover_callback(altibase, NULL, NULL);
/* ... check return value ... */
Failover는 명령문(statement)이 아닌 연결에 대해서 설정을 하는 것이므로, 콜백 함수 등록시에는 연결 핸들이 이용된다. 또한 Failover 작업은 해당 연결 핸들에 속한 모든 명령문에 영향을 준다. 만약 한 명령문에만 Failover를 적용하고자 한다면, 그 명령문만 속한 연결 핸들을 별도로 생성해서 사용해야 한다.
Failover 후처리#
Failover 후처리는 Failover 발생시에 사용자가 이전에 수행했던 prepare와 bind 작업을 다시 복원해 주는 것을 말한다.
SQL문 수행 중에 Failover가 발생하여 성공했다면, 클라이언트 라이브러리는 Failover 후처리를 통해서 prepare와 bind를 원래 상태로 복구하며 에러 코드로 ALTIBASE_FAILOVER_SUCCESS를 반환한다. 만약 클라이언트 라이브러리가 Failover를 실패하거나 Failover 후처리에 실패하면 실패 작업에 상응하는 에러 코드를 반환할 것이다. 이 때문에 altibase_stmt_execute() 또는 altibase_stmt_fetch() 수행 중에 prepare 또는 bind 실패와 관련된 에러 코드가 반환될 수도 있다. 이는 Failover에는 성공했지만 Failover 후처리 작업중에 실패한 것으로, 사용자는 Failover 설정과 서버의 상태 등을 확인해 볼 필요가 있다.
예제#
다음은 Failover 작업과 관련된 소스 코드 예제이다. 준비된 명령문 수행 중에 Failover가 발생하면 클라이언트 라이브러리에서 자동으로 prepare와 bind를 다시 수행해 주므로, 사용자는 execute부터 실행하면 된다.
rc = altibase_stmt_prepare(stmt, qstr);
/* ... check return value ... */
/* ... omit ... */
:retry
rc = altibase_stmt_execute(stmt);
if (ALTIBASE_NOT_SUCCEEDED(rc))
{
if (altibase_stmt_errno(stmt) == ALTIBASE_FAILOVER_SUCCESS)
{
/* 자동으로 prepare까지 해주므로 execute부터 다시 한다. */
goto retry;
}
else
{
/* ... error handling ... */
}
}
/* altibase_stmt_store_result() is optional */
rc = altibase_stmt_store_result(stmt);
if (ALTIBASE_NOT_SUCCEEDED(rc))
{
if (altibase_stmt_errno(stmt) == ALTIBASE_FAILOVER_SUCCESS)
{
/* 자동으로 prepare까지 해주므로 execute부터 다시 한다. */
goto retry;
}
else
{
/* ... error handling ... */
}
}
while (1)
{
rc = altibase_stmt_fetch(stmt)
if (ALTIBASE_NOT_SUCCEEDED(rc))
{
if (altibase_stmt_errno(stmt) == ALTIBASE_FAILOVER_SUCCESS)
{
/* execute부터 다시 해야한다. */
goto retry;
}
else
{
/* ... error handling ... */
break;
}
}
/* TODO something */
}