Chinaunix首页 | 论坛 | 博客
  • 博客访问: 11681982
  • 博文数量: 8065
  • 博客积分: 10002
  • 博客等级: 中将
  • 技术积分: 96708
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-16 17:06
文章分类

全部博文(8065)

文章存档

2008年(8065)

分类: 服务器与存储

2008-07-17 09:42:15

一、安装Oracle LogMiner包:
$sqlplus '/as sysdba'
SQL> @?/rdbms/admin/dbmslm.sql     --用来创建DBMS_LOGMNR包,该包用来分析日志文件。
SQL> @?/rdbms/admin/dbmslmd.sql     --用来创建DBMS_LOGMNR_D包,该包用来创建数据字典文件。

二、安装脚本包:(sql脚本见下)
$sqlplus '/as sysdba'
SQL> @tab_trace.sql
SQL> @sp_trace.sql

三、使用前提:(sp_trace_begin过程里会检查)
1. 数据库归档模式
2. 设置了参数 utl_file_dir

四、使用步骤:
$sqlplus '/as sysdba'
SQL> set serveroutput on;
SQL> set timing on;
SQL> set lines 1000;
1. exec sp_trace_begin;
2. 操作DB,或前台受理业务,下面可以查出业务期间发生的sql操作
3. exec sp_trace_end;  --新生成字典文件,速度较慢,首次使用
or
  exec sp_trace_end(false); --用原先的字典文件,速度加快
4. select * from mv_trace; --查看跟踪的sql

五、相关SQL:
show parameter utl_file_dir;
archive log list;
alter system set utl_file_dir = '/opt/oracle/db04' scope = spfile;
shutdown immediate
startup mount
alter database archivelog;
alter database open;
select * from tab_scn;

六、附脚本

tab_trace.sql:
drop table sys.tab_scn;
CREATE TABLE sys.tab_scn
(
startscn NUMBER,
endscn NUMBER
);
grant select on sys.tab_scn to public;
drop public synonym tab_scn;
create public synonym tab_scn for sys.tab_scn;
drop table sys.logmnr_contents;
create table sys.logmnr_contents as select * from sys.v$logmnr_contents where 1=2;
drop public synonym logmnr_contents;
create public synonym logmnr_contents for sys.logmnr_contents;
drop materialized view sys.mv_trace;
--where过滤条件可以根据实际情况更改

create materialized view sys.mv_trace
Build deferred
refresh complete with rowid
as
SELECT TIMESTAMP,REPLACE (sql_redo, '"') sql_redo,session_info
FROM SYS.logmnr_contents
WHERE seg_owner NOT IN ('SYS')
AND operation NOT IN ('INTERNAL', 'UNSUPPORTED')
ORDER BY TIMESTAMP;
grant select on sys.mv_trace to public;
drop public synonym mv_trace;
create public synonym mv_trace for sys.mv_trace;


sp_trace.sql:
CREATE OR REPLACE PROCEDURE sp_trace_begin
/*
SQLPLUS:
set serveroutput on;
set timing on;
exec sp_trace_begin;
*/

AS
  v_sql VARCHAR2 (1000);
  v_temp VARCHAR2 (1000);
  e_not_utl_file_dir EXCEPTION;
  e_not_archivelog EXCEPTION;
BEGIN
  
-- check parameter utl_file_dir

  SELECT VALUE
   INTO v_temp
   FROM SYS.v$parameter
  WHERE NAME = 'utl_file_dir';
  IF v_temp IS NULL
  THEN
    RAISE e_not_utl_file_dir;
  END IF;
  
-- check archive mode

  SELECT log_mode
   INTO v_temp
   FROM v$database;
  IF v_temp = 'NOARCHIVELOG'
  THEN
    RAISE e_not_archivelog;
  END IF;
  IF v_temp IS NULL
  THEN
    RAISE e_not_utl_file_dir;
  END IF;
  
-- manual archive

  v_sql := 'alter system archive log current';
  EXECUTE IMMEDIATE v_sql;
  
-- insert start scn

  DELETE tab_scn;
  INSERT INTO tab_scn
        (startscn, endscn
        )
    VALUES (DBMS_FLASHBACK.get_system_change_number, NULL
        );
  COMMIT;
EXCEPTION
  WHEN e_not_utl_file_dir
  THEN
    raise_application_error (-20000, 'parameter utl_file_dir not setup.');
  WHEN e_not_archivelog
  THEN
    raise_application_error (-20001, 'database not archive mode.');
END;
/
CREATE OR REPLACE PROCEDURE sp_trace_end
/*
SQLPLUS:
set serveroutput on;
set timing on;
set lines 1000;
exec sp_trace_end;
or
exec sp_trace_end(false);
*/

(i_gen_dict BOOLEAN DEFAULT TRUE)
AS
  v_sql VARCHAR2 (1000);
  v_utl_file_dir VARCHAR2 (1000);
  v_dict_file VARCHAR2 (1000) := 'trace.dat';
  v_dict_pathfile VARCHAR2 (1000);
  
-- cursor which get archive file

  CURSOR cur_archive
  IS
   SELECT *
     FROM SYS.v$archived_log
     WHERE next_change# >= (SELECT startscn
                 FROM tab_scn
                 WHERE ROWNUM = 1)
      AND next_change# <= (SELECT endscn
                 FROM tab_scn
                 WHERE ROWNUM = 1)
   ORDER BY completion_time DESC;
  rec_archive cur_archive%ROWTYPE;
  
-- print data

  PROCEDURE sp_print (i_string IN VARCHAR2)
  IS
    p_string LONG DEFAULT i_string;
  BEGIN
    LOOP
     EXIT WHEN p_string IS NULL;
     DBMS_OUTPUT.put_line (RPAD ('-', 80, '-'));
     DBMS_OUTPUT.put_line (SUBSTRB (p_string, 1, 255));
     p_string := SUBSTR (p_string, 256);
   END LOOP;
  END;
BEGIN
  DBMS_OUTPUT.ENABLE (1000000);
  
-- manual archive

  v_sql := 'alter system archive log current';
  EXECUTE IMMEDIATE v_sql;
  
-- update endScn

  UPDATE SYS.tab_scn
   SET endscn = DBMS_FLASHBACK.get_system_change_number;
  COMMIT;
  
-- get utl_file_dir parameter value

  SELECT VALUE
   INTO v_utl_file_dir
   FROM SYS.v$parameter
  WHERE NAME = 'utl_file_dir' AND ROWNUM = 1;
  
-- generate dictionary file (long long time)

  IF i_gen_dict = TRUE
  THEN
    DBMS_LOGMNR_D.BUILD (dictionary_filename => v_dict_file,
              dictionary_location => v_utl_file_dir
             );
  END IF;
  
-- add archive logfile

  OPEN cur_archive;
  LOOP
    FETCH cur_archive
    INTO rec_archive;
   EXIT WHEN cur_archive%NOTFOUND;
   IF cur_archive%ROWCOUNT = 1
   THEN
     DBMS_LOGMNR.add_logfile (logfilename => rec_archive.NAME,
                  options => DBMS_LOGMNR.NEW
                 );
   ELSE
     DBMS_LOGMNR.add_logfile (logfilename => rec_archive.NAME,
                  options => DBMS_LOGMNR.addfile
                 );
   END IF;
    sp_print ( 'Archive File Name '
        || TO_CHAR (cur_archive%ROWCOUNT)
        || ': '
        || rec_archive.NAME
        );
  END LOOP;
  CLOSE cur_archive;
  IF SUBSTRB (v_utl_file_dir, -1) != '/'
  THEN
    v_dict_pathfile := v_utl_file_dir || '/' || v_dict_file;
  ELSE
    v_dict_pathfile := v_utl_file_dir || v_dict_file;
  END IF;
  
-- analyze archive logfile

  DBMS_LOGMNR.start_logmnr (dictfilename => v_dict_pathfile);
  
-- save data to logmnr_contents,

  
-- because other sessions donnt have select privilege on v$logmnr_contents

  DELETE FROM SYS.logmnr_contents;
  INSERT INTO SYS.logmnr_contents
   SELECT *
    FROM SYS.v$logmnr_contents;
  COMMIT;
  
--filter data

  dbms_mview.REFRESH ('sys.mv_trace');
END;
/

阅读(372) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~