Chinaunix首页 | 论坛 | 博客
  • 博客访问: 24785859
  • 博文数量: 271
  • 博客积分: 10025
  • 博客等级: 上将
  • 技术积分: 3358
  • 用 户 组: 普通用户
  • 注册时间: 2007-11-12 15:28
文章分类

全部博文(271)

文章存档

2010年(71)

2009年(164)

2008年(36)

我的朋友

分类: Oracle

2010-05-20 17:05:19

对数据库做不完全恢复的时候,如果我们能够精确的定位到出错的时间点的话,那么,我们可以在很大的程度上一次性地保证不完全恢复成功。所以,问题也就是我们应该怎么能够准确定位这个人为错误(如误删除表,错误的提交DML)发生的时间?接下来,要跟大家分享一下关于10g里LogMiner这个“日志挖掘器”的用法,也就是,在Oracle 10g版本的数据库,应该怎么使用LogMiner

首先:简单介绍一下LogMiner工具。LogMiner 是Oracle公司从产品8i以后提供的一个非常有实用价值的分析工具,使用该工具可以轻松获得Oracle Online redo logs或者Archived logs日志文件中的具体内容。日志文件中记录了所有对数据库的数据块儿进行过改变的操作,而Logminer正是可以挖掘日志文件的利器。

其次:该如何使用Logminer?在早期的数据库版本里,LogMiner在默认情况下,并没有安装,需要手工的以SYSDBA身份去执行$ORACLE_HOME/rdbms/admin/dbmslm.sql以及$ORACLE_HOME/rdbms/admin/dbmslmd.sql这两个脚本。前者是创建DBMS_LOGMNR package,后者用于创建DBMS_LOGMNR_D这个包。在10g版本的数据库,这两个PL/SQL 包默认已经创建,我们就无须再去执行那两个脚本,可以直接对其调用。

然后:需要说明的一点,在Oracle 10g数据库版本里面,默认情况下,联机日志文件记录的内容并非提供任何的Supplemental logging,也就是说默认情况下使用LogMiner只能看到DDL操作。要想看到DML操作的话,在DML操作产生新的日志记录之前我们要启用最低的Supplemental logging,而启用这一特性又分为在数据库级别以及表级别,以下简单演示在全库级别启用最低Supplemental logging:

确认当前数据库Supplemental logging:

1 SQL> select supplemental_log_data_min from v$database;
2 SUPPLEME
3 --------
4 NO

启用Supplemental logging,以便可以通过LogMiner看到日志文件中记录的关于DML操作的相关信息:

1 SQL> alter database add supplemental log data;
2 Database altered.
3 SQL> select supplemental_log_data_min from v$database;
4 SUPPLEME
5 --------
6 YES

日志“挖掘”结束,可以禁用Supplemental logging:

1 SQL> alter database drop supplemental log data;
2 Database altered.

接下来:该说说具体使用LogMiner的方法了:
使用方法1:
1.1确认数据库当前的日志文件信息:

01 SQL> select * from v$log;
02     GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS           FIRST_CHANGE# FIRST_TIM
03 ---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ---------
04          1          1          5   52428800          1 YES INACTIVE                674382 16-MAY-10
05          2          1          4   52428800          1 YES INACTIVE                660045 15-MAY-10
06          3          1          6   52428800          1 NO  CURRENT                 691344 20-MAY-10
07 SQL> select * from v$logfile;
08     GROUP# STATUS  TYPE    MEMBER                                   IS_
09 ---------- ------- ------- ---------------------------------------- ---
10          3         ONLINE  /u01/app/oradata/helen/redo03.log        NO
11          2         ONLINE  /u01/app/oradata/helen/redo02.log        NO
12          1         ONLINE  /u01/app/oradata/helen/redo01.log        NO

1.2从上面的结果可以确定当前数据库使用的是第3组日志,其对应的日志文件成员为/u01/app/oradata/helen/redo03.log ,也就是说,当前情况下,所有接下来对数据库的操作都将记录在第3个日志组所对应文件成员中,直到该日志组被写满为止。把该组的日志成员添加到LogMiner的”挖掘”范围之内:

1 SQL> exec dbms_logmnr.add_logfile
2 (logfilename=>'/u01/app/oradata/helen/redo03.log',
3 options=>dbms_logmnr.new);
4 PL/SQL procedure successfully completed.

可以通过v$logmnr_logs数据字典表验证:

1 SQL> select filename from v$logmnr_logs;
2 FILENAME
3 ----------------------------------------
4 /u01/app/oradata/helen/redo03.log

想继续添加其他日志文件成员进来,只需重新执行上述PL/SQL package,把对应的参数修改为新的日志文件成员名称,并且把new以addfile取代。删除对某个日志文件成员的挖掘,只需以removefile取代new之。
1.3执行LogMiner:

1 SQL> exec dbms_logmnr.start_logmnr
2 (options=>dbms_logmnr.dict_from_online_catalog);
3 PL/SQL procedure successfully completed.

1.4开启另外一个会话,而且一定是新开第二个会话,不能跟刚才执行的调用Logminer在同一个会话,并且执行DML操作:

1 SQL> conn hr/hr;
2 Connected.
3 SQL> insert into test values(20);
4 1 row created.
5 SQL> insert into test values(21);
6 1 row created.
7 SQL> delete from test where id=21;
8 1 row deleted.
9 SQL>

1.5这时HR执行的操作已经被记录到日志文件里了,再切回到第一个会话,执行下述操作:

01 SQL> select timestamp,table_name,sql_redo,sql_undo,operation
02   from v$logmnr_contents
03   where username='HR'
04   
05 TIMESTAMP           TABLE SQL_REDO                                      SQL_UNDO                                 OPERATIO
06 ------------------- ----- --------------------------------------------- ---------------------------------------- --------
07 2010/05/20 01:56:33       set transaction read write;                                                            START
08 2010/05/20 01:56:33 TEST  insert into "HR"."TEST"("ID") values ('20');  delete from "HR"."TEST" where "ID" = '20 INSERT
09                                                                         ' and ROWID = 'AAAM39AAEAAAAGNAAA';
10   
11 2010/05/20 01:56:36 TEST  insert into "HR"."TEST"("ID") values ('21');  delete from "HR"."TEST" where "ID" = '21 INSERT
12                                                                         ' and ROWID = 'AAAM39AAEAAAAGNAAB';
13   
14 2010/05/20 01:56:42 TEST  delete from "HR"."TEST" where "ID" = '21' and insert into "HR"."TEST"("ID") values ('2 DELETE
15                            ROWID = 'AAAM39AAEAAAAGNAAB';                1');

1.6显然,我们可以看到准确的有用信息,当然V$logmnr_contents字典表中还可能有我们更为关心的字段,我们可以根据需要自行选取查看。挖掘完成之后,可以显示停止对Logminer工具的调用,也可以断开当前会话隐式停止对Logminer工具的使用,因为V$logmnr_contents表里的内容是存放在当前会话PGA里的。这也是为什么在调用Logminer的时候,其他会话是看不到v$logmnr_contents表里的内容,也解释了在第4步骤中为什么必须新开一个会话的原因。

1 SQL> exec dbms_logmnr.end_logmnr;
2 PL/SQL procedure successfully completed.
3 SQL> select filename from v$logmnr_logs;
4 no rows selected

关于LogMiner使用的另外一种方法,将在另外一篇日志里同大家齐分享

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