在对数据库做不完全恢复的时候,如果我们能够精确的定位到出错的时间点的话,那么,我们可以在很大的程度上一次性地保证不完全恢复成功。所以,问题也就是我们应该怎么能够准确定位这个人为错误(如误删除表,错误的提交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 ; |
启用Supplemental logging,以便可以通过LogMiner看到日志文件中记录的关于DML操作的相关信息:
1 |
SQL> alter database add supplemental log data; |
3 |
SQL> select supplemental_log_data_min from v$ database ; |
日志“挖掘”结束,可以禁用Supplemental logging:
1 |
SQL> alter database drop supplemental log data; |
接下来:该说说具体使用LogMiner的方法了:
使用方法1:
1.1确认数据库当前的日志文件信息:
01 |
SQL> select * from v$log; |
02 |
GROUP # THREAD# SEQUENCE # BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM |
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_ |
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; |
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操作:
3 |
SQL> insert into test values (20); |
5 |
SQL> insert into test values (21); |
7 |
SQL> delete from test where id=21; |
1.5这时HR执行的操作已经被记录到日志文件里了,再切回到第一个会话,执行下述操作:
01 |
SQL> select timestamp ,table_name,sql_redo,sql_undo,operation |
02 |
2 from v$logmnr_contents |
05 |
TIMESTAMP TABLE SQL_REDO SQL_UNDO OPERATIO |
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' ; |
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' ; |
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; |
关于LogMiner使用的另外一种方法,将在另外一篇日志里同大家齐分享
阅读(2060) | 评论(0) | 转发(0) |