有时候,某个用户无意间drop了一张表,或者是truncate一张表,delete 忘加where,update 忘加 where, 这个时候们就可能执行不完全恢复,或者进行数据库的flashback.但是我们怎么能知道他干坏事的具体时间呢?只要redo log 存在,我们就能通过logminer这个工具找到干坏事的具体时间,然后执行不完全恢复,恢复数据库到干坏事之前的那一时刻。又或者公司领导提出要求,我要查看某个人在某个时间干了什么事情,只要redo log 存在,我们都能够通过logminer查看到某个人做的所有事情。
使用Logminer的步骤(10gr2,数据库处于online,archive 状态,并且数据库对象不会被更改):
这是一个很简单的实验,首先用户robinson有一个test表,表结构和数据如下
SQL> show user;
USER 为 "ROBINSON"
SQL> select * from test;
NAME ADDRESS
---------- ----------
luobingsen China
robinson ChongQing
为了进行试验,我删除这个表中的数据
SQL> delete from test;
已删除2行。
SQL> commit;
提交完成。
下面用logminer来查看robinson干坏事的准确时间
1.查看是否给数据库添加了追加日志的功能
SQL> SELECT SUPPLEMENTAL_LOG_DATA_MIN FROM V$DATABASE;
SUPPLEME
--------
NO ---默认为no,如果为no,使用如下语句添加日志追加功能
SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA; -----如果不启用日志追加,就无法查看DML,只能查看DDL
数据库已更改。
2.以sys用户执行以下脚本
SQL> EXECUTE DBMS_LOGMNR.START_LOGMNR( -
> STARTTIME => to_date('2009-11月-5 17:00:00','YYYY-MON-DD HH24:MI:SS'), -
> ENDTIME => sysdate, -
> OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + -
> DBMS_LOGMNR.PRINT_PRETTY_SQL + -
> DBMS_LOGMNR.CONTINUOUS_MINE + -
> DBMS_LOGMNR.NO_ROWID_IN_STMT);
PL/SQL 过程已成功完成。
3.查看v$logmnr_contents视图,得到robinson 干坏事的时间和干了什么坏事情
SQL> select username ,operation,sql_redo,sql_undo,SCN from v$logmnr_contents where seg_owner='ROBINSON';
USERNAME OPERATION SQL_REDO SQL_UNDO SCN
---------- ---------- ------------------------------ ------------------------------ -------
ROBINSON DELETE delete from "ROBINSON"."TEST" insert into "ROBINSON"."TEST" 625126
where values
"NAME" = 'luobingsen' and "NAME" = 'luobingsen',
"ADDRESS" = 'China';
"ADDRESS" = 'China';
ROBINSON DELETE delete from "ROBINSON"."TEST" insert into "ROBINSON"."TEST" 625126
where values
"NAME" = 'robinson' and "NAME" = 'robinson',
"ADDRESS" = 'ChongQing'; "ADDRESS" = 'ChongQing';
可以看到干的坏事情是delete操作,干坏事情的具体SCN为625126,可以把scn转换为timestamp
SQL> select scn_to_timestamp('625126') from dual;
SCN_TO_TIMESTAMP('625126')
---------------------------------------------------------------------------
05-11月-09 05.36.42.000000000 下午
这个时候我们就可以利用备份,或者使用闪回功能,将数据库闪回到09年11月5日下午5点36分42秒之前,或者,我们可以执行
sql_undo的语句,将数据还原回去。
这里只是简单介绍Logminer,详细信息和用法请参考官方文档Utilities