TAF и Oracle TimesTen

Продолжаем тему высокой доступности. Для обеспечения высокой доступности в Oracle TimesTen
есть возможность создания Active - Standby pair репликации, которая обеспечивает быстрое переключение standby узла в состояние active ( Здесь я писал о том, как настроить Active - Standby pair репликацию и Oracle Clusterware).

Но, что же будет происходить с приложением в момент сбоя и как данную ситуацию обработать?

В Oracle Database (RAC), есть технологии TAF (Transparent Application Failover) и FAN (Fast Application Notification) с помощью которых можно обработать ситуацию падения узла на уровне приложения.

Есть ли в TimesTen что то похожее?


Ответ - Есть!

В версии 11G появилась возможность "Automatic client failover" - это возможность автоматического преключения на резервный узел.

В клиентском DSN появились новые атрибуты:
  • Failover Server Name or Network Address - ip адрес или имя хоста, на котором будет находиться standby. Не забудьте про порт серверного процесса - если порт не по умолчанию, то нужно прописать TCP_Port
  • Failover Server DSN - база данных (data store)
  • Failover Port Range - порт для failover notifications (опционально)
Соотвественно, для включения Automatic client failover необходимо прописать данные атрибуты для соединения. Вот собственно и все - TAF включен!


Сделаю несколько замечаний. Технология TAF есть в Oracle TimesTen и она похожа на TAF в Oracle RAC, но ТОЛЬКО похожа (это не одно и тоже)! Поэтому рассмотрим работу TAF в TimesTen.

Предположим, что у вас есть следующий код (есть statement и result set):
statement = connection.createStatement();
resultSet = statement.executeQuery("select 1 from dual");
В случае сбоя узла, получаем следующую ошибку:
java.sql.SQLException: [TimesTen][TimesTen 11.2.1.4.0 CLIENT]Statement handle invalid due to client failover

При чем, это происходит в любом случае (даже если транзакция не открывалась и выполнялись только запросы), т.е. ничего подобного TAF TYPE SELECT в TimesTen нет.
Кроме этого, во время failover-а инвалидируется statement, поэтому нужно не забыть создать его еще раз в обработчике исключения. Еще один нюанс - если сбой произошел когда приложение начало транзакцию, TimesTen неявно ее откатывает, т.е. приложение никогда не узнает о том, нужно ли ему откатывать транзакцию или нет, оно узнает только о факте failover-а.

Все эти нюансы нужно учитывать!

Теперь вернемся к вопросу обработки исключения "Statement handle invalid due to client failover".
Согласно документации Oracle® TimesTen In-Memory Database Java Developer's Guide Release 11.2.1, TimesTen JDBC поддерживает два механизма для обнаружения failover:
  • Синхронное обнаружение (Synchronous detection)
  • Асинхронное обнаружение (Asynchronous detection)

Синхронное однаружение осуществляется путем перехвата исключения "Statement handle invalid due to client failover".
Например:
try {
  // ...
  // Execute a query on a previously prepared statement.
  ResultSet theResultSet = theStatement.executeQuery("select * from dual");
  // ...
} catch (SQLException sqlex) {
  sqlex.printStackTrace();
  if (sqlex.getErrorCode() == TimesTenVendorCode.TT_ERR_FAILOVERINVALIDATION) {
    // Automatic client failover has taken place; discontinue use of this object.
  }
}

Асинхронное обнаружение failover-а основано на использовании callback функции (client failover event listener) и регистрации ее в соединении. Все аналогично callback функциям в Oracle RAC, разные только интерфейсы (com.timesten.jdbc.ClientFailoverEventListener вместо oracle.jdbc.OracleOCIFailover) и методы.

Пример (callback функция):
private class MyCFListener implements ClientFailoverEventListener {
    
    public void notify(ClientFailoverEvent event) {

        // Process connection failover type
        switch(event.getTheFailoverType()) {
            case TT_FO_CONNECTION:               
               System.out.println("This should be a connection failover type " + event.getTheFailoverType());
               break;
            default:
               break;
        }

        // Process connection failover events
        switch(event.getTheFailoverEvent()) {
            case BEGIN:
                System.out.println("This should be a BEGIN event " + event.getTheFailoverEvent());
                    /* Applications cannot use Statement, PreparedStatement, ResultSet,
                       etc. created on the failed Connection any longer.
                    */
                break;
            case END:
                System.out.println("This should be an END event " + event.getTheFailoverEvent());
                    /* Applications may want to re-create Statement and PreparedStatement                       
                       objects at this point as needed.
                    */
                break;
            case ABORT:
                System.out.println("This should be an ABORT event " + event.getTheFailoverEvent());
                break;
            case ERROR:
                System.out.println("This should be an ERROR event " + event.getTheFailoverEvent());
                break;
            default:
                break;
        }
    }
}
Как видно из примера, вызов event.getTheFailoverType() возвращает тип failover-а. В настоящее время поддерживается только один тип - это connection failover (TT_FO_CONNECTION). Вызов event.getTheFailoverEvent() возвращяет событие.
Существует 4 события:
  • BEGIN - если начался client failover
  • END - если client failover удачно завершился
  • ERROR - если client failover завершился неудачно, но будет перезапущен
  • ABORT - если client failover был аварийно прекращен
Пример (регистрация callback функции):
...
TimesTenConnection conn = null;            
MyCFListener m = new MyCFListener();        
DriverManager.registerDriver(new com.timesten.jdbc.TimesTenClientDriver());                
conn = (TimesTenConnection)DriverManager.getConnection("jdbc:timesten:client:cl_ha","app","app");        
conn.addConnectionEventListener(m);                        
Statement stmt = conn.createStatement();
...

ИТОГ

В Oracle TimesTen существуют инструменты для построения систем высокой доступности - как на стороне сервера (Active - Standby pair репликация + Clusterware), так и на стороне приложения - технологии TAF и FAN (к теме FAN я еще думаю вернусь) для обработки ситуаций сбоя узла.
Только нужно понимать, что технологии в TimesTen имеют ряд "нюансов" и не полностью повторяют данные технологии в Oracle RAC.

PS. На фото Париж (лето или осень 2010 - не помню :)))

Комментариев нет: