DBMS_ALERT - работа в RAC
На нашем семинаре RAC DD4D мы говорили о том, что пакет DBMS_ALERT не работает в RAC, но выяснилось что эта информация уже устарела, то есть сейчас это не так, и в настоящий момент в 10gR2 RAC и 11gR1 RAC указанный пакет полностью работоспособен! Спасибо за детальную информацию Тузову С.И. (ОАО "Россельхозбанк")!
Небольшой testcase демонстрирует это.
Подключаемся к четвертому узлу и регистрируем наш сигнал.
conn system/oracle@racdb4
set serveroutput on
declare
v_xMessage varchar2(1800);
v_xStatus number;
begin
dbms_output.put_line('Connected to node => ' dbms_utility.current_instance);
dbms_alert.register('MyAlert');
dbms_alert.waitone(name => 'MyAlert',
message => v_xMessage,
status => v_xStatus,
timeout => dbms_alert.maxwait);
if (v_xStatus = 0) then
dbms_output.put_line('Message recieved: ' v_xMessage);
else
dbms_output.put_line('Message NOT recieved: ');
end if;
end;
/
Сессия зависает, бесконечно ожидая сигнала... Открываем сессию на первый узел кластера, и пошлем сигнал:
conn system/oracle@racdb1
set serveroutput on
begin
dbms_output.put_line('Connected to node => ' dbms_utility.current_instance);
dbms_alert.signal('MyAlert','Hello World!');
commit;
end;
/
Соединено.
Connected to node => 1
Процедура PL/SQL успешно завершена.
В этот момент зависшая сессия на четвертом узле магически оживает:
Connected to node => 4
Message recieved: Hello World!
Процедура PL/SQL успешно завершена.
Как вы видите: сигнал созданный на первом узле, был доступен подписчику на другом узел. Более детальный анализ показывает что в процессе работы с DBMS_ALERT мспользуется системная табличка DBMS_ALERT_INFO. В момент регистрации на сигнал (вызов dbms_alert.register) трассировочный файл содержит следующие вызовы:
DELETE FROM DBMS_ALERT_INFO
WHERE
SID = :B1
COMMIT;
SELECT DISTINCT SUBSTR(KGLNAOBJ,11) SID
FROM
X$KGLOB WHERE KGLHDNSP = 7 AND KGLNAOBJ LIKE 'ORA$ALERT$%' AND
BITAND(KGLHDFLG,128)!=0 UNION SELECT DISTINCT SID FROM DBMS_ALERT_INFO
DELETE DBMS_ALERT_INFO
WHERE
SID = :B1
INSERT INTO DBMS_ALERT_INFO
VALUES
(UPPER(:B2 ), :B1 , 'N', NULL)
Ну и при создании сигнала, снова видна интенсивная работа с таблицей DBMS_ALERT_INFO:
UPDATE DBMS_ALERT_INFO SET CHANGED = 'Y', MESSAGE = :B2
WHERE
NAME = UPPER(:B1 )
SELECT SID
FROM
DBMS_ALERT_INFO WHERE NAME = UPPER(:B1 )
Понятно, что если вы интенсивно используете пакет DBMS_ALERT, то при переходе в RAC таблица DBMS_ALERT_INFO мгновенно становится "горячей". Поэтому в целом, наше утверждение и workaround-ы относительно пакета DBMS_ALERT остаются в силе ! Проверка на использование пакета DBMS_ALERT все-таки была оставлена в утилите RACChecker
Комментариев нет:
Отправить комментарий