28 авг. 2011 г.

TAF Failover and commit

На очередном семинаре "RAC is simple" был получен интересный вопрос о странном поведении TAF в ситуации Failover (автоматического переключения сессии при сбое текущего узла) в случае, когда приложение выдает фиксацию транзакции (делает commit).

Действительно, есть особенность поведения TAF связанная с тем, что оператор COMMIT, помимо выдачи исключения ORA-25405, дополнительно еще и сбрасывает маркер активной транзакции на клиенте - собственно начинает новую транзакцию.

Но обо все по порядку...

Как вы хорошо знаете, при сбое текущего узла Oracle Client (конечно если была включена поддержка TAF в дескрипторе в файле tnsnames.ora), прозрачно для приложения открывает новую сессию на другой узел.
Если сессия до сбоя имела некоторый контекст либо активную транзакцию, то при обращении к Oracle Call Interface возникает исключение. Этих исключений несколько - все они начинаются с префикса ORA-254xx.
Самый распространенный случай - на клиенте была активная транзакция; в этом случае приложение получает исключение "ORA-25402 transaction must rollback".

Используем вот такой дескриптор соединения в tnsnames.ora
racdb_taf =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(host = rac-scan)(PORT = 1521))
      (FAILOVER = true)
    )
    (CONNECT_DATA =
      (failover_mode=
        (type=session)
        (method=basic)
        (retries=2)
      )
     (SERVICE_NAME = racdb.rac.com)
    )
  )


Подключаемся к кластеру по алиасу racdb_taf:
[oracle@racc ~]$ sqlplus rscott/rtiger@racdb_taf

SQL*Plus: Release 11.2.0.2.0 - Production on Sun Aug 28 19:07:27 2011

Copyright (c) 1982, 2010, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options

SQL> select dbms_utility.current_instance from dual;

CURRENT_INSTANCE
----------------
               1
SQL>rem Мы подключены к первому узлу


Выполняем вставку записей, но НЕ фиксируем транзакцию:
SQL> insert into taf_demo values(1);

1 row created.

SQL>
Подключаемся напрямую на узел, на котором "живет" наша сессия (в данном случае на первый узел), и аварийно завершаем экземпляр:
rac2-> ssh rac1
Last login: Sun Aug 28 18:38:50 2011 from 192.168.1.95
rac1-> sqlplus / as sysdba

SQL*Plus: Release 11.2.0.2.0 Production on Sun Aug 28 19:13:45 2011

Copyright (c) 1982, 2010, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options

SQL> shutdown abort;
ORACLE instance shut down.
SQL>

Возвращаемся в нашу сессию, которая была подключена к "погибшему" узлу, и пытаемся продолжить работу:
SQL> insert into taf_demo values(2);
insert into taf_demo values(2)
*
ERROR at line 1:
ORA-25402: transaction must roll back

SQL> select * from taf_demo;
select * from taf_demo
*
ERROR at line 1:
ORA-25402: transaction must roll back

SQL>


Все происходит согласно теории: маркер активной транзакции был установлен, но сессии уже нет, вернее есть (TAF автоматически произвел переключение на другой узел), - это уже другая сессия!

Попробуем сделать то, что сделал слушатель семинара: выдадим операцию commit:
SQL> commit;
commit
*
ERROR at line 1:
ORA-25405: transaction status unknown

SQL>

Мы получили другое исключение! Все верно - статус транзакции не определён, поскольку клиент имел незавершенную транзакцию и, незавершив ее, переключился на другой узел.
Теперь самое интересное: выдадим какой-нибудь DML-оператор:
SQL> insert into taf_demo values(2);

1 row created.

SQL> select * from taf_demo;

        ID
----------
         2

SQL> select dbms_utility.current_instance from dual;

CURRENT_INSTANCE
----------------
               2
SQL>rem Мы автоматически переключились к второму узлу

SQL>


После оператора commit работа может быть продолжена!
То есть оператор commit, помимо выдачи исключения, производит то, что он обычно делает - начинает новую транзакцию.

Поэтому, если в TAF после сбоя текущего узла первым будет выполнен оператор commit, то нужно обрабатывать другое исключение, и при этом делать rollback уже НЕ обязательно!

26 авг. 2011 г.

Oracle VM 3.0 released!

Наконец-то произошло это эпохальное событие: вышел OracleVM 3.0 !
Список новых возможностей можно почитать здесь.

Ключевое новшество, на мой взгляд, - это переход на ветку кода Xen 4.0, и все вытекающие отюда преимущества.

Скачать дистрибутив можно здесь.
Обращаю ваше внимание, что Oracle VM 3.0 поддерживает только x86_64 платформу, хотя сами виртуальные машины могут быть и 32-х битными!

И в очередной раз стоит напомнить, что OracleVM - это бесплатный продукт, платная только поддержка (приобретается если необходима).

15 авг. 2011 г.

dbms_session.is_session_alive in RAC

На семинаре RAC is simple один из слушателей заявил, что функция is_session_alive из пакета dbms_session не работает в RAC. Неужели есть еще один функционал, который не работает в RAC, и нужно будет добавлять новую проверку в утилиту RACChecker ?
Давайте проверим !

rac1-> sqlplus rscott/rtiger@racdb2

SQL*Plus: Release 11.2.0.3.0 Beta on Sun Aug 14 21:21:54 2011

Copyright (c) 1982, 2011, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Beta
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options


SQL> set serveroutput on
SQL> --Наша сессия открыта на втором узле:
SQL> exec dbms_output.put_line(dbms_utility.current_instance);
2

PL/SQL procedure successfully completed.

SQL> --Выясняем id нашей сессии:
SQL> exec dbms_output.put_line(dbms_session.unique_session_id);
002A00630002

PL/SQL procedure successfully completed.

SQL> --запускаем некую активность в этой сессии:
declare
  k number;
begin
  for i in 1..20000000
  loop
    dbms_lock.sleep(300);
    k := i;
  end loop;
end;
/

Оставив эту сессию выполняться, подключаемся к другому узлу кластера
(к первому узлу - к экземпляру racdb1), и пытаемся проверить статус нашей активной сессии:
rac1-> sqlplus rscott/rtiger@racdb1

SQL*Plus: Release 11.2.0.3.0 Beta on Sun Aug 14 21:24:21 2011

Copyright (c) 1982, 2011, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Beta
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options


SQL> set serveroutput on
SQL> --Наша сессия открыта на первом узле:
SQL> exec dbms_output.put_line(dbms_utility.current_instance);
1

PL/SQL procedure successfully completed.

SQL> begin
  if dbms_session.is_session_alive('002A00630002') then
    dbms_output.put_line('Session active !');
  else
    dbms_output.put_line('Session not active !');
  end if;
end;
/
Session active !

PL/SQL procedure successfully completed.

SQL> 
Как Вы видите, в сессии на первом узле прекрасно виден статус активности другой сессии,
которая выполняется на другом узле !

Таким образом вызов dbms_session.is_session_alive полностью поддерживает RAC!

Возможно проблема была связана с Bug 6440088 DBMS_SESSION.IS_SESSION_ALIVE does not work properly in RAC
Этот баг был устранен в 10.2.0.5.


P.S.
На фото - новое издание бестселлера Тома Кайта "Oracle для профессионалов" на русском языке, переработанное с учетом технологий Oracle 11g.

8 авг. 2011 г.

Oracle Linux 5 Update 7 released

Анонсирован выпуск Oracle Linux 5 Update 7

Oracle Linux 5.7 содержит исправление ошибок, а также обновление 18-ти сетевых драйверов и 12-ти драйверов для систем хранения данных.

Oracle Linux 5.7 доступен для загрузки на странице http://edelivery.oracle.com/linux (требуется регистрация).
Список изменений - здесь.