设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

深入了解数据库之LogMiner

2014-12-31 15:34| 发布者: joejoe0332| 查看: 1163| 评论: 0|原作者: 杨宝秋|来自: hrb_qiuyb's blog

摘要: LogMiner 是Oracle公司从产品8i以后提供的一个实际非常有用的分析工具,使用该工具可以轻松获得Oracle 重做日志文件(归档日志文件)中的具体内容,LogMiner分析工具实际上是由一组PL/SQL包和一些动态视图组成,可以 ...

  LogMiner 是Oracle公司从产品8i以后提供的一个实际非常有用的分析工具,使用该工具可以轻松获得Oracle 重做日志文件(归档日志文件)中的具体内容,LogMiner分析工具实际上是由一组PL/SQL包和一些动态视图组成,可以通过它分析在线日志和归档日志获取数据库过往详细、具体的操作,非常有用。


为什么会用到LogMiner?

主要出于以下几个缘由:

  1. 当数据库发生了误操作,需要不完全恢复,为确认误操作准确的时间点或SCN号,此时需用到LogMiner。
  2. 传统恢复一个上TB或是恢复一个几百GB表空间中的一个小表,标准的操作是把整个表空间恢复到之前的状态,然后再应用归档日志,加上搭建恢复环境的时间,整个时间会很长。通过LogMiner可以换一种恢复思维,能通过它解析到这个表上所有的DML操作,可以做反向修复。合理的使用会大幅降低此情况恢复的复杂度和时间。
  3. 可以把LogMiner当成最强大的数据库审计工具。
  4. 在过去的某个时间数据库很忙或是产生了大量的归档日志,通过LogMiner可以知道是哪些操作,哪个表占比较大,主要矛盾在哪。

几个概念

源库:生成归档日志和在线日志的库

目标库:执行LogMiner进行日志分析的库

字典:英文名为CATALOG,用于把日志中的内部信息翻译成实际的表名、列名等有价值信息

源库与目标库可以是同一个,也可以是不同的。如果不同,要求目标库数据库版本高于或等于源库;字符集要相同;操作系统、硬件平台要相同。

源库需做的调整

  1. 源库需运行在归档模式下
  2. 源库需启用追加日志
  1. ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;  
  2.    
  3. 查看一下结果:  
  4. SQL> SELECT SUPPLEMENTAL_LOG_DATA_MIN FROM V$DATABASE;  
  5. SUPPLEMENTAL_LOG_DATA_MIN  
  6. --------------------------------  
  7. YES  
客观的说追加日志不是必需,如果不启用追加日志SESSION_INFO等很多有用的信息解析后都没有,显示会为“UNKNOWN”。

 LogMiner字典模式

  1. 使用在线字典

这种方式是Oracle推荐的,适用于在源库做LogMiner,也是最易用的一种方式。

举例:

  1. EXECUTE DBMS_LOGMNR.START_LOGMNR(-  
  2. OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG);  

 2.  把字典放到在线日志文件

适用于源库与目标库不同这样的方式

举例:

  1. EXECUTE DBMS_LOGMNR_D.BUILD( -  
  2. OPTIONS=> DBMS_LOGMNR_D.STORE_IN_REDO_LOGS);  
  3.    
  4. 看字典存放到了哪个归档日志:  
  5. SELECT NAME FROM V$ARCHIVED_LOG WHERE DICTIONARY_BEGIN='YES';  
  6. SELECT NAME FROM V$ARCHIVED_LOG WHERE DICTIONARY_END='YES';  

 3.  把字典生成OS上的一个文件

这样的方式是要是为了兼容9i及之前的版本,实际使用中这样的方式需要在源库设定UTL_FILE_DIR参数,不方便。

  1. EXECUTE DBMS_LOGMNR_D.BUILD('dictionary.ora', -  
  2. '/oracle/database/', -  
  3. DBMS_LOGMNR_D.STORE_IN_FLAT_FILE);  
Oracle已不推荐这样方式。

以一个例子说明一下LogMiner流程

1.从磁带库恢复出所需的日志

  1.  run  
  2. {  
  3.  ALLOCATE channel t1 type 'SBT_TAPE' parms 'ENV=(NSR_SERVER=linuxbak,NSR_CLIENT=jfdb1,NSR_DATA_VOLUME_POOL=jfdb)';  
  4.  set archivelog destination to '/jfdb_arch/yang';  
  5.  restore archivelog from logseq 247761 until logseq 247763 thread 1;  
  6.  release channel t1;  
  7. }  
2.使用在线字典解析日志
  1. SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME =>'/zhjf02_dlbk/yang/zhjf2_2_202749_570073317.arc',OPTIONS => DBMS_LOGMNR.NEW)  
  2. PL/SQL procedure successfully completed.  
  3.    
  4. SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME =>'/zhjf02_dlbk/yang/zhjf2_2_202750_570073317.arc',OPTIONS => DBMS_LOGMNR.ADDFILE)  
  5. PL/SQL procedure successfully completed.  
  6.    
  7. SQL> EXECUTE DBMS_LOGMNR.START_LOGMNR(OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + DBMS_LOGMNR.COMMITTED_DATA_ONLY);  
  8. PL/SQL procedure successfully completed.  
3. 查询解析结果
  1. SQL> create table qiuyb.logcontents_2_202749 nologging tablespace TBSI_RAT_32M  as select * from V$LOGMNR_CONTENTS ;  
  2. Table created.  
需要说明的是V$LOGMNR_CONTENTS是会话期存在的,其它会话是查不到结果的。因此本例子把结果存放在了一个实体表中。另外,每次查询V$LOGMNR_CONTENTS这个视图都会实际触发一次日志解析,也就是说这个视图的内容不是START_LOGMNR生成的,而是每次查生成的,生成一个实体表也可以大幅降低系统开销。

4.结束LogMiner解析

  1. SQL> EXECUTE DBMS_LOGMNR.END_LOGMNR();  
  2. PL/SQL procedure successfully completed.  
整个LogMiner会话结束。

一些有用的选项

1. COMMITTED_DATA_ONLY

顾名思义就是只显示已经提交了的,那些正在进行中的及Oracle内部操作都忽略掉了,5的举例里使用的就是这个选项。

2.PRINT_PRETTY_SQL

SQL_REDO和SQL_UNDO中SQL以易读的方式显示,举例如下:

  1. SQL>  EXECUTE DBMS_LOGMNR.START_LOGMNR(OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + DBMS_LOGMNR.COMMITTED_DATA_ONLY+DBMS_LOGMNR.PRINT_PRETTY_SQL);  
  2. PL/SQL procedure successfully completed.  
  3.    
  4. SQL> SELECT USERNAME, SEG_OWNER, SEG_NAME, SQL_REDO, SQL_UNDO  
  5.   2    FROM v$LOGMNR_CONTENTS;  
  6.   3   WHERE SEG_OWNER NOT IN ('SYS''SYSTEM')  
  7.   4     AND SEG_NAME = 'T2'  
  8.   5  /  
  9. USERNAME  SEG_OWNER   SEG_NAME   SQL_REDO                      SQL_UNDO  
  10. --------- ----------- ---------- ----------------------------- ------------------------------------  
  11. QIUYB     QIUYB       T2         insert into "QIUYB"."T2"      delete from "QIUYB"."T2"  
  12.                                  values                        where  
  13.                                     "ID" = 105,                   "ID" = 105 and  
  14.                                     "NAME" = 'test 105',          "NAME" = 'test 105' and  
  15.                                     "FLAG" = 5;                   "FLAG" = 5 and  
  16.                                                                   ROWID = 'AAAUcRAAFAAABj1AAA';  
  17.    
  18. SQL>  

4.DDL_DICT_TRACKING

适用于在线日志存放LogMiner字典的情况,当表发生了添加字段等情况,字典自动更新。

举例:

  1. EXECUTE DBMS_LOGMNR.START_LOGMNR(OPTIONS => -  
  2. DBMS_LOGMNR.DDL_DICT_TRACKING + DBMS_LOGMNR.DICT_FROM_REDO_LOGS);  
4. NO_SQL_DELIMITER
去掉SQL_REDO及SQL_UNDO中SQL语句最后的分号,以CURSOR方式循环执行解析出的SQL会很方便和快捷。
举例:
  1. EXECUTE DBMS_LOGMNR.START_LOGMNR(OPTIONS => -  
  2. DBMS_LOGMNR.NO_SQL_DELIMITER + DBMS_LOGMNR.DICT_FROM_REDO_LOGS);  
5. NO_ROWID_IN_STMT
在SQL_REDO和SQL_UNDO列语句中去掉ROWID。举例:
  1. EXECUTE DBMS_LOGMNR.START_LOGMNR(OPTIONS => -  
  2. DBMS_LOGMNR.NO_ROWID_IN_STMT + DBMS_LOGMNR.DICT_FROM_REDO_LOGS);  

适用于在源库以外的其它库重新执行解析出的SQL,因为相应的ROWID在目标库是不存在的。

有用视图

  1. V$LOGMNR_LOGS 添加的需解析的日志列表
  2. V$LOGMNR_CONTENTS 解析结果

本文作者杨宝秋,Oracle ACE,十多年的TB级数据库设计、建设、管理、运行维护、调优经验,也做了7年的Hp和IBM Rs6000的系统管理员,而且是获得了BCFP认证的SAN管理员,现为中国联通黑龙江分公司数据库主管。

原文链接:http://www.qiuyb.com/archives/171


酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部