есть возможность создания 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 (опционально)
Сделаю несколько замечаний. Технология 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 был аварийно прекращен
... 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 - не помню :)))
Комментариев нет:
Отправить комментарий