есть возможность создания 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 - не помню :)))
Комментариев нет:
Отправить комментарий