Отправляет email-рассылки с помощью сервиса Sendsay

Открыто о СУБД Oracle на русском

  Все выпуски  

Открыто о СУБД Oracle на русском : контроль заданий


Информационный Канал Subscribe.Ru

Выпуск 70

Уважаемые подписчики рассылки!

Не так давно мне пришло письмо с вопросом о том, как контролировать задания (jobs) в Oracle. Вот почему в этом выпуске я решил представить перевод ответа Тома Кайта на давно заданный аналогичный вопрос... Кроме того, я хочу представить вам новую книгу, над переводом которой я сейчас работаю.

Мониторинг заданий

Как понять, что реально делает задание? Я хотел бы получать признаки жизни от посланного на выполнение SQL-оператора. Не видно никаких блокировок, которые мешали бы ему работать - я работаю на новом и практически не используемом сервере. Этот сервер должен заменить текущий производтсвенный, поэтому я, по сути, скопировал все настройки. Пришлось внести несколько изменений в файл INIT.ORA, в основном, связанных с изменением каталогов: ранее значение compatible было 7.3.2.3.0, а теперь - 7.3.4.5.0; ресурсов enqueue было 16000, а теперь - 32000 (я просто выполнил "diff" для двух файлов). Я уверен, что никаких блокировок не может быть, но ЧТО делает задание, мне непонятно.

Я пытался просматривать все обнаруженные представления динамической производительности V$; где взять их полный список? В одной из книг, которую я читал, написано, что надо обращаться к представлению X$KQFVI, но его, похоже, нет...

Ответ Тома Кайта

Чтобы узнать, какие задания сейчас выполняются, используйте следующее представление:

 
ops$tkyte@8i> desc dba_jobs_running 
 Name                          Null?    Type 
 ----------------------------- -------- -------------------- 
 SID                                    NUMBER 
 JOB                                    NUMBER 
 FAILURES                               NUMBER 
 LAST_DATE                              DATE 
 LAST_SEC                               VARCHAR2(8) 
 THIS_DATE                              DATE 
 THIS_SEC                               VARCHAR2(8) 
 INSTANCE                               NUMBER 

Чтобы узнать, какой sql-оператор выполняет задание, и выполняет ли оно что-то вообще, можно использовать такой сценарий sqlplus:

 
------ begin of showsql.sql -------------------------- 
 
column status format a10 
set feedback off 
set serveroutput on 
select username, sid, serial#, process, status 
from v$session 
where username is not null 
/ 
column username format a20 
column sql_text format a55 word_wrapped 
set serveroutput on size 1000000 
declare 
    x number; 
begin 
    for x in 
    ( select username||'('||sid||','||serial#|| 
                ') ospid = ' ||  process || 
                ' program = ' || program username, 
             to_char(LOGON_TIME,' Day HH24:MI') logon_time, 
             to_char(sysdate,' Day HH24:MI') current_time, 
             sql_address, LAST_CALL_ET 
        from v$session 
       where status = 'ACTIVE' 
         and rawtohex(sql_address) <> '00' 
         and username is not null order by last_call_et ) 
    loop 
        for y in ( select max(decode(piece,0,sql_text,null)) || 
                          max(decode(piece,1,sql_text,null)) || 
                          max(decode(piece,2,sql_text,null)) || 
                          max(decode(piece,3,sql_text,null)) 
                               sql_text 
                     from v$sqltext_with_newlines 
                    where address = x.sql_address 
                      and piece < 4) 
        loop 
            if ( y.sql_text not like '%listener.get_cmd%' and 
                 y.sql_text not like '%RAWTOHEX(SQL_ADDRESS)%') 
            then 
                dbms_output.put_line( '--------------------' ); 
                dbms_output.put_line( x.username ); 
                dbms_output.put_line( x.logon_time || ' ' || 
                                      x.current_time|| 
                                      ' last et = ' || 
                                      x.LAST_CALL_ET); 
                dbms_output.put_line( 
                          substr( y.sql_text, 1, 250 ) ); 
            end if; 
        end loop; 
    end loop; 
end; 
/ 
column username format a15 word_wrapped 
column module format a15 word_wrapped 
column action format a15 word_wrapped 
column client_info format a30 word_wrapped 
select username||'('||sid||','||serial#||')' username, 
       module, 
       action, 
       client_info 
from v$session 
where module||action||client_info is not null; 
 
------------------------ eof -------------------------- 

Он показывает:

  • кто зарегистрирован;
  • если сеансы активны, какой sql-оператор они выполняют;
  • сколькор времени они это делают (столбец last_call_et)

Может иметь смысл использовать пакет DBMS_APPLICATION_INFO для задания значений столбцов action, client_info и module в представлении v$session - после этого при выполнении сценария showsql вы будете получать значения из этих столбцов, что поможет понять, на каком эхтапе выполнения сейчас находится программа.

Не могу получить текст SQL. Комментарий читателя от 22 июня 2004 года

Том,

я попытался использовать твой сценарий, но столкнулся с проблемой при использовании его совместно с FGA (Fine Grained Auditing). Вот мой сценарий:

 
exec DBMS_FGA.ADD_POLICY(OBJECT_SCHEMA    => 'DEMO',OBJECT_NAME    => 
'REF_UR',POLICY_NAME    => 'POL_REF_UR',HANDLER_SCHEMA    => 
'DEMO',HANDLER_MODULE=> 'CAPTURE',ENABLE =>  TRUE) 

А вот и процедура Capture:

 
CREATE OR REPLACE procedure CAPTURE_FGA(V_SCHEMA VARCHAR2,V_TABLE 
VARCHAR2,V_POLICY VARCHAR2) 
AS 
    x number; 
    scenario number; 
    testsq varchar2(4000); 
 
begin 
 
    for x in 
    ( select username||'('||sid||','||serial#|| 
                ') ospid = ' || process || 
                ' program = ' || program, username, 
             to_char(LOGON_TIME,' Day YYYY-MM-DD HH24:MI:SS') logon_time , 
             to_char(sysdate,' Day YYYY-MM-DD HH24:MI:SS') current_time, 
sql_address,prev_sql_addr,LAST_CALL_ET,MACHINE,TERMINAL,process,program, 
audsid,sid,serial#,osuser,a.module,b.CPU_TIME,b.EXECUTIONS,b.FETCHES,b.INVALIDATIONS, b.LOADS, 
b.OPTIMIZER_COST,b.OPTIMIZER_MODE,b.sorts,b.OPEN_VERSIONS,b.ROWS_PROCESSED, 
b.BUFFER_GETS,b.DISK_READS,b.PARSE_CALLS,b.ELAPSED_TIME,b.USERS_EXECUTING,b.USERS_OPENING, 
b.LOADED_VERSIONS,b.FIRST_LOAD_TIME,b.LAST_LOAD_TIME 
        from v$session a,v$sql b 
        where status = 'ACTIVE' 
        and rawtohex(prev_sql_addr) <> '00' 
        and b.address = prev_sql_addr 
        and username is not null order by last_call_et) 
     loop 
        for y in ( select max(decode(piece,0,sql_text,null)) || 
                          max(decode(piece,1,sql_text,null)) || 
                          max(decode(piece,2,sql_text,null)) || 
                          max(decode(piece,3,sql_text,null)) 
                          sql_text 
                     from v$sqltext_with_newlines 
                     where 
                     piece < 4 
                     --and address =x.sql_address 
                     and address in 
                     (select prev_sql_addr from v$session 
                     where sid = 18 
                     and serial# = 475) 
                     ) 
       loop 
            if ( y.sql_text not like '%listener.get_cmd%' and 
                 y.sql_text not like '%rawtohex(sql_addresse)%' ) 
            then 
                insert into rt_suivi_consult_aas 
(trc_schema,trc_table,trc_policy,dt_trace,sql_text_line,terminal, 
machine,username,process,program,sid,serial#,osuser,module,logon_time, 
CPU_TIME,EXECUTIONS,FETCHES,INVALIDATIONS,LOADS,OPTIMIZER_COST,OPTIMIZER_MODE, 
sorts,OPEN_VERSIONS,ROWS_PROCESSED,BUFFER_GETS,DISK_READS,PARSE_CALLS,ELAPSED_TIME, 
USERS_EXECUTING,USERS_OPENING,LOADED_VERSIONS,FIRST_LOAD_TIME,LAST_LOAD_TIME) 
                values 
(v_schema,v_table,v_policy,x.current_time,y.sql_text,x.terminal, 
x.machine,x.username,x.process,x.program,x.sid,x.serial#,x.osuser, 
x.module,x.logon_time,x.cpu_time,x.EXECUTIONS,x.FETCHES,x.INVALIDATIONS, 
                x.LOADS,x.OPTIMIZER_COST,x.OPTIMIZER_MODE, 
                x.sorts,x.OPEN_VERSIONS,x.ROWS_PROCESSED, 
                x.BUFFER_GETS,x.DISK_READS,x.PARSE_CALLS, 
                x.ELAPSED_TIME,x.USERS_EXECUTING,x.USERS_OPENING, 
                x.LOADED_VERSIONS,x.FIRST_LOAD_TIME,x.LAST_LOAD_TIME); 
            end if; 
        end loop; 
    end loop; 
end; 
/ 

Затем, я выполняю

 
select * from ref_ur 

и обращаюсь к таблице rt_suivi_consult_aas, чтобы проверить, перехвачен ли текст SQL-оператора, оказывается, что там следующий текст:

 
select max(decode(piece,0,sql_text,null)) || 
                          max(decode(piece,1,sql_text,null)) || 
                          max(decode(piece,2,sql_text,null)) || 
                          max(decode(piece,3,sql_text,null)) 
                          sql_text 

а не "select * from ref_ur"

Не подскажешь, в чем дело?

Ответ Тома Кайта

Пакет dbms_fga уже ЗАХВАТИЛ текст SQL-оператора - он уже в журнале аудита (audit trail). Всё уже сделано, просто выкиньте ваш код. Именно это и делает пакет dbms_fga.

Оригинал обсуждения этого вопроса можно найти здесь. Я не переводил часть, не относящуюся непосредственно к использованию нескольких индексов для выполнения запроса.


Copyright © 2004 Oracle Corporation


Прежние выпуски

Все вышедшие выпуски рассылки можно найти на сайте рассылки. Там же реализована возможность поиска материалов по ключевым словам (с помощью Google...)

Обращение к подписчикам

Уважаемые подписчики. Занялся я переводом очередной хорошей книги по СУБД Oracle, Mastering Oracle PL/SQL: Practical Solutions. Том Кайт ее рекомендовал (и рецензировал). Не зря, кстати. С разрешения издательства я собираюсь опубликовать в рассылке фрагменты перевода. Вам это интересно? Пишите...

Краткое содержание:

  • Глава 1. Эффективность PL/SQL
  • Глава 2. Объедините все в пакет
  • Глава 3. Бесконечная тема курсоров
  • Глава 4. Эффективная обработка данных
  • Глава 5. Методы оптимизации PL/SQL
  • Глава 6. Триггеры
  • Глава 7. Пакеты АБД
  • Глава 8. Пакеты для защиты
  • Глава 9. Пакеты для Web-приложений
  • Глава 10. Отладка PL/SQL
  • Приложение А. Создание утилиты DEBUG

С наилучшими пожеланиями,

  В.К.


http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться

В избранное