При закрытии подписчики были переданы в рассылку "СУБД Oracle "с нуля"" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
Информационный Канал Subscribe.Ru |
Уважаемые подписчики рассылки!
Не так давно мне пришло письмо с вопросом о том, как контролировать задания
(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 --------------------------
Он показывает:
Может иметь смысл использовать пакет DBMS_APPLICATION_INFO для задания значений столбцов action, client_info и module в представлении v$session - после этого при выполнении сценария showsql вы будете получать значения из этих столбцов, что поможет понять, на каком эхтапе выполнения сейчас находится программа.
Том,
я попытался использовать твой сценарий, но столкнулся с проблемой при
использовании его совместно с 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. Том Кайт ее рекомендовал (и рецензировал). Не зря, кстати. С разрешения издательства я собираюсь опубликовать в рассылке фрагменты перевода. Вам это интересно? Пишите...
Краткое содержание:
С наилучшими пожеланиями,
В.К.
http://subscribe.ru/
E-mail: ask@subscribe.ru | Отписаться |
В избранное | ||