在对数据库做不完全恢复的时候,如果我们能够精确的定位到出错的时间点的话,那么,我们可以在很大的程度上一次性地保证不完全恢复成功。所以,问题也就是我们应该怎么能够准确定位这个人为错误(如误删除表,错误的提交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:
SQL> select supplemental_log_data_min from v$database; SUPPLEME -------- NO
启用Supplemental logging,以便可以通过LogMiner看到日志文件中记录的关于DML操作的相关信息:
SQL> alter database add supplemental log data; Database altered. SQL> select supplemental_log_data_min from v$database; SUPPLEME -------- YES
日志“挖掘"结束,可以禁用Supplemental logging:
SQL> alter database drop supplemental log data; Database altered.
接下来:该说说具体使用LogMiner的方法了: 使用方法1: 1.1确认数据库当前的日志文件信息:
SQL> select * from v$log; GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM ---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- --------- 1 1 5 52428800 1 YES INACTIVE 674382 16-MAY-10 2 1 4 52428800 1 YES INACTIVE 660045 15-MAY-10 3 1 6 52428800 1 NO CURRENT 691344 20-MAY-10 SQL> select * from v$logfile; GROUP# STATUS TYPE MEMBER IS_ ---------- ------- ------- ---------------------------------------- --- 3 ONLINE /u01/app/oradata/helen/redo03.log NO 2 ONLINE /u01/app/oradata/helen/redo02.log NO 1 ONLINE /u01/app/oradata/helen/redo01.log NO
1.2从上面的结果可以确定当前数据库使用的是第3组日志,其对应的日志文件成员为/u01/app/oradata/helen/redo03.log ,也就是说,当前情况下,所有接下来对数据库的操作都将记录在第3个日志组所对应文件成员中,直到该日志组被写满为止。把该组的日志成员添加到LogMiner的"挖掘"范围之内:
SQL> exec dbms_logmnr.add_logfile (logfilename=>'/u01/app/oradata/helen/redo03.log', options=>dbms_logmnr.new); PL/SQL procedure successfully completed.
可以通过v$logmnr_logs数据字典表验证:
SQL> select filename from v$logmnr_logs; FILENAME ---------------------------------------- /u01/app/oradata/helen/redo03.log
想继续添加其他日志文件成员进来,只需重新执行上述PL/SQL package,把对应的参数修改为新的日志文件成员名称,并且把new以addfile取代。删除对某个日志文件成员的挖掘,只需以removefile取代new之。 1.3执行LogMiner:
SQL> exec dbms_logmnr.start_logmnr (options=>dbms_logmnr.dict_from_online_catalog); PL/SQL procedure successfully completed.
1.4开启另外一个会话,而且一定是新开第二个会话,不能跟刚才执行的调用Logminer在同一个会话,并且执行DML操作:
SQL> conn hr/hr; Connected. SQL> insert into test values(20); 1 row created. SQL> insert into test values(21); 1 row created. SQL> delete from test where id=21; 1 row deleted. SQL>
1.5这时HR执行的操作已经被记录到日志文件里了,再切回到第一个会话,执行下述操作:
SQL> select timestamp,table_name,sql_redo,sql_undo,operation 2 from v$logmnr_contents 3 where username='HR' TIMESTAMP TABLE SQL_REDO SQL_UNDO OPERATIO ------------------- ----- --------------------------------------------- ---------------------------------------- -------- 2010/05/20 01:56:33 set transaction read write; START 2010/05/20 01:56:33 TEST insert into "HR"."TEST"("ID") values ('20'); delete from "HR"."TEST" where "ID" = '20 INSERT ' and ROWID = 'AAAM39AAEAAAAGNAAA'; 2010/05/20 01:56:36 TEST insert into "HR"."TEST"("ID") values ('21'); delete from "HR"."TEST" where "ID" = '21 INSERT ' and ROWID = 'AAAM39AAEAAAAGNAAB'; 2010/05/20 01:56:42 TEST delete from "HR"."TEST" where "ID" = '21' and insert into "HR"."TEST"("ID") values ('2 DELETE ROWID = 'AAAM39AAEAAAAGNAAB'; 1');
1.6显然,我们可以看到准确的有用信息,当然V$logmnr_contents字典表中还可能有我们更为关心的字段,我们可以根据需要自行选取查看。挖掘完成之后,可以显示停止对Logminer工具的调用,也可以断开当前会话隐式停止对Logminer工具的使用,因为V$logmnr_contents表里的内容是存放在当前会话PGA里的。这也是为什么在调用Logminer的时候,其他会话是看不到v$logmnr_contents表里的内容,也解释了在第4步骤中为什么必须新开一个会话的原因。
SQL> exec dbms_logmnr.end_logmnr; PL/SQL procedure successfully completed. SQL> select filename from v$logmnr_logs; no rows selected
关于LogMiner使用的另外一种方法,将在另外一篇日志里同大家齐分享!