0% found this document useful (0 votes)
255 views

Using Oracle LogMiner

LogMiner allows you to analyze redo logs and archived redo logs to view DML and DDL statements. You need to configure the UTL_FILE_DIR parameter and build a LogMiner dictionary. Then add the necessary logs and start a LogMiner session to query views like V$LOGMNR_CONTENTS to see SQL statements from the logs. LogMiner shows DML but you need to check DML on data dictionary objects to see DDL statements as well.

Uploaded by

Jabras Guppies
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
255 views

Using Oracle LogMiner

LogMiner allows you to analyze redo logs and archived redo logs to view DML and DDL statements. You need to configure the UTL_FILE_DIR parameter and build a LogMiner dictionary. Then add the necessary logs and start a LogMiner session to query views like V$LOGMNR_CONTENTS to see SQL statements from the logs. LogMiner shows DML but you need to check DML on data dictionary objects to see DDL statements as well.

Uploaded by

Jabras Guppies
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 8

Using Oracle LogMiner ===================== LogMiner allows you to look inside your redo logs and review DML

and DDL stateme nts. Setting up LogMiner Check if you have configured a directory where Oracle can read and write (this a re not the directories created with CREATE DIRECTORY): SQL> show parameter utl_file_dir NAME TYPE VALUE ------------------------------------ ----------- ----------------------------utl_file_dir string Value is empty? Set Oracle parameter UTL_FILE_DIR in (server) parameter file, bo unce the instance and run utlfile.sql: $ sqlplus / as sysdba SQL> SQL> SQL> SQL> alter system set utl_file_dir = '/tmp' scope = spfile; shutdown startup @?/rdmbs/admin/utlfile

Next you need to setup LogMiner dictionary four your instance to map object ids to names and provide human-readable insight to the logs if you don t build it you see something like this: SQL> select sql_redo from v$logmnr_contents; SQL_REDO ------------------------------------------------------------------------------set transaction read write; insert into UNKNOWN.Objn:25128(Col[1]) values (HEXTORAW('c102')); commit; instead of: SQL> select sql_redo from v$logmnr_contents; SQL_REDO ------------------------------------------------------------------------------set transaction read write; insert into test1 values (1); commit; Build the dictionary with DBMS_LOGMNR_D.BUILD: SQL> exec dbms_logmnr_d.build(dictionary_filename => 'dictionary.ora', dicti onary_location => '/tmp'); PL/SQL procedure successfully completed. LogMiner views What data dictionary views do we have got?

SQL> select view_name from all_views where view_name like '%LOGMNR%'; VIEW_NAME -----------------------------V_$LOGMNR_CALLBACK V_$LOGMNR_CONTENTS V_$LOGMNR_DICTIONARY V_$LOGMNR_DICTIONARY_LOAD V_$LOGMNR_LATCH V_$LOGMNR_LOGFILE V_$LOGMNR_LOGS V_$LOGMNR_PARAMETERS V_$LOGMNR_PROCESS V_$LOGMNR_REGION V_$LOGMNR_SESSION V_$LOGMNR_STATS V_$LOGMNR_TRANSACTION DBA_LOGMNR_LOG DBA_LOGMNR_PURGED_LOG DBA_LOGMNR_SESSION 13 rows selected. I will just use V$LOGMNR_CONTENTS in this blog entry. See V$LOGMNR_CONTENTS in O racle Database Reference 11g Release 2 (11.2) for an explanation of all columns in this view. A simple session with LogMiner Take a look at the available logfile by querying V$LOGFILE and V$ARCHIVED_LOG: SQL> select sequence#,name,status,deleted from v$archived_log; SEQUENCE# NAME S DEL ---------- -------------------------------------------------------------------------- - --7 /u04/app/oracle/orafra/PROD/archivelog/2011_05_11/o1_mf_1_7_6wnn7 thl_.arc A NO 8 /u04/app/oracle/orafra/PROD/archivelog/2011_05_11/o1_mf_1_8_6wnt0 o61_.arc A NO 9 /u04/app/oracle/orafra/PROD/archivelog/2011_05_11/o1_mf_1_9_6wnt1 fr5_.arc A NO [...] 40 /u04/app/oracle/orafra/PROD/archivelog/2011_05_13/o1_mf_1_40_6wsq ps23_.arc A NO 41 /u04/app/oracle/orafra/PROD/archivelog/2011_05_13/o1_mf_1_41_6wsq sccn_.arc A NO 42 /u04/app/oracle/orafra/PROD/archivelog/2011_05_13/o1_mf_1_42_6wsq sgxv_.arc A NO SQL> select f.group#,l.sequence#,f.member from v$logfile f inner join v$log l on f.group# = l.group#; GROUP# SEQUENCE# ---------- ------------------------1 43 o_.log 1 43 MEMBER -----------------------------------------------------/u02/app/oracle/oradata/PROD/onlinelog/o1_mf_1_6wlfqxh /u02/app/oracle/oradata/PROD/onlinelog/o1_mf_1_6wlfqxw

w_.log 2 0_.log 2 y_.log We can see that logs from sequence #7 up to #42 are archived and they are NOT DE Leted, so they are available for analysis. The actual log sequence #43 is availa ble in redo log group #1. Start LogMiner At first add the logfiles you want to analyze, take care: first logfile is added with option DBMS_LOGMNR.NEW, others with DBMS_LOGMNR.ADDFILE. I want to analyze the last four log sequences (3 archived, 1 online log sequence): SQL> exec dbms_logmnr.add_logfile(logfilename => '/u04/app/oracle/orafra/PRO D/archivelog/2011_05_13/o1_mf_1_40_6wsqps23_.arc', 2 options => dbms_logmnr.new); PL/SQL procedure successfully completed. SQL> exec dbms_logmnr.add_logfile(logfilename => '/u04/app/oracle/orafra/PRO D/archivelog/2011_05_13/o1_mf_1_41_6wsqsccn_.arc', 2 options => dbms_logmnr.addfile); PL/SQL procedure successfully completed. SQL> exec dbms_logmnr.add_logfile(logfilename => '/u04/app/oracle/orafra/PRO D/archivelog/2011_05_13/o1_mf_1_42_6wsqsgxv_.arc', 2 options => dbms_logmnr.addfile); PL/SQL procedure successfully completed. SQL> exec dbms_logmnr.add_logfile(logfilename => '/u02/app/oracle/oradata/PR OD/onlinelog/o1_mf_1_6wlfqxho_.log', 2 options => dbms_logmnr.addfile); PL/SQL procedure successfully completed. Start a session using the previously created dictionary logfile for the instance : SQL> exec dbms_logmnr.start_logmnr(dictfilename => '/tmp/dictionary.ora'); SQL> select scn, sql_redo from v$logmnr_contents where ... ; Alternatively you can start a session and give some contraints on time or SCN: SQL> exec dbms_logmnr.start_logmnr(dictfilename => '/tmp/dictionary.ora' 2 , starttime => to_date('01-Feb-2011 08:00:00', 'DD-MON-YYYY HH:MI:SS') 3 , endtime => to_date('01-Feb-2011 10:00:00', 'DD-MON-YYYY HH:MI:SS')); LogMiner shows only DML statements and transaction control from redo and undo. D DL (i.e. DROP TABLE) is a DML on data dictionary items! To find DDL statements y ou have to query for DML against SYS.TAB$ for example. SQL> SQL> SQL> SQL> column seg_name format a25 trunc col seg_name format a10 col seg_owner format a20 col table_space format a15 42 /u02/app/oracle/oradata/PROD/onlinelog/o1_mf_2_6wlfr21 42 /u02/app/oracle/oradata/PROD/onlinelog/o1_mf_2_6wlfr06

SQL> col operation format a11 SQL> select seg_name , seg_type , seg_owner , table_name , table_space , operation , scn from v$logmnr_contents where operation != 'INTERNAL' and seg_name in ('COL$','OBJ$','TAB$') group by seg_name , seg_type , seg_owner , table_name , table_space , operation , scn order by scn; SEG_NAME SEG_TYPE SEG_OWNER TABLE_SPACE OPERATION SCN ---------- ---------- ---------------------------------- ----------- ---------OBJ$ 2 SYS SYSTEM INSERT 407518 OBJ$ 2 SYS SYSTEM UPDATE 407521 OBJ$ 2 SYS SYSTEM INSERT 407524 OBJ$ 2 SYS SYSTEM INSERT 407528 OBJ$ 2 SYS SYSTEM UPDATE 407535 OBJ$ 2 SYS SYSTEM UPDATE 407539 OBJ$ 2 SYS SYSTEM UPDATE 407543 OBJ$ 2 SYS SYSTEM INSERT 407594 OBJ$ 2 SYS SYSTEM UPDATE 407596 OBJ$ 2 SYS SYSTEM UPDATE 407598 OBJ$ 2 SYS SYSTEM UPDATE 407600 TABLE_NAME -------------------------------OBJ$ OBJ$ OBJ$ OBJ$ OBJ$ OBJ$ OBJ$ OBJ$ OBJ$ OBJ$ OBJ$

End your session with DBMS_LOGMNR.END_LOGMNR or just start a new one with DBMS_L OGMNR.START_LOGMNR. SQL> exec dbms_logmnr.end_logmnr; I can t find a dropped table with LogMiner Maybe you re using the Flashback feature and the table was moved into recycle bin:

SQL> show parameter flashback NAME TYPE VALUE ------------------------------------ ----------- ----------------------------db_flashback_retention_target SQL> show parameter recyclebin NAME TYPE VALUE ------------------------------------ ----------- ----------------------------recyclebin string on The recyclebin is turned on. So dropped tables will not be dropped, they are ren amed: SQL> show recyclebin ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME ---------------- ------------------------------ ------------ -----------------TEST 3:36 Recover it using the FLASHBACK TABLE command: SQL> flashback table ttt to before drop; Finding a log sequence by time To find certain statements you need to locate the needed logfile(s). At first yo u may know the time when a statement was issued. The data dictionary views V$ARC HVIED_LOG and V$BACKUP_REDOLOG give a lot of information on what log sequence an d SCNs (system change numbers) belong to which time frame: SQL> SQL> SQL> SQL> [...] NAME SEQU ENCE# FIRST_CHANGE# FIRST_TIME ---------------------------------------------------------------------- --------- ------------- -------------35 36 37 38 39 270339 15.02.11 15:04 270523 15.02.11 15:08 275453 15.02.11 15:26 278957 15.02.11 15:28 283483 15.02.11 16:37 set linesize 132 col name format a70 alter session set nls_date_format = 'DD.MM.YY HH24:MI'; select name, sequence#, first_change#, first_time from v$archived_log; BIN$oyQvIAiLn73gQCi8yGgVVw==$0 TABLE 2011-05-13:09:2 integer 1440

40 283681 15.02.11 16:43 /u02/app/oracle/fra/AOC/archivelog/2011_02_16/o1_mf_1_41_6or9x348_.arc

41 283705 15.02.11 16:43 /u02/app/oracle/fra/AOC/archivelog/2011_02_16/o1_mf_1_42_6orb7r4w_.arc 42 337380 16.02.11 20:38 /u02/app/oracle/fra/AOC/archivelog/2011_02_17/o1_mf_1_43_6otb8y65_.arc 43 337619 16.02.11 20:43 /u02/app/oracle/fra/AOC/archivelog/2011_02_18/o1_mf_1_44_6ox4wn28_.arc 44 397223 17.02.11 14:56 /u02/app/oracle/fra/AOC/archivelog/2011_02_18/o1_mf_1_45_6ox4xqth_.arc 45 450667 18.02.11 16:43 39 rows selected. This query shows us that log sequences from 41 to 45 are available on disk in th e FRA (flash recovery area). Our online redo logs are: SQL> SQL> SQL> SQL> er from v$log l inner join v$logfile f on l.group# = f.group# group by l.group#, sequence#, first_change#, first_time; GROUP# SEQUENCE# FIRST_CHANGE# ---------- ---------- ---------------------------------------------2 46 450705 OC/onlinelog/o1_mf_2_6om6m588_.log 1 45 450667 OC/onlinelog/o1_mf_1_6om6m1tr_.log FIRST_TIME MEMBER ----------------- --------------------18.02.11 16:43:51 /u02/app/oracle/fra/A 18.02.11 16:43:15 /u02/app/oracle/fra/A set linesize 132 col member format a70 alter session set nls_date_format = 'DD.MM.YY HH24:MI:SS'; select l.group#, sequence#, first_change#, first_time, min(member) memb

Use LogMiner like shown above to take a look into the log. Now I want to see the statements, look at the column SQL_REDO in V$LOGMNR_CONTENTS: SQL> select sql_redo from v$logmnr_contents where scn=407518; SQL_REDO -------------------------------------------------------------------------------------------------------------------------commit; set transaction read write; insert into "SYS"."SCHEDULER$_EVENT_LOG"("LOG_ID","LOG_DATE","TYPE#","NAME", "OWNER","CLASS_ID","OPERATION","STATUS","USER_NAME","CLI ENT_ID","GUID","DBID","FLAGS","CREDENTIAL","DESTINATION","ADDITIONAL_INFO") values ('99',TO_TIMESTAMP_TZ('12-MAY-11 10.00.06.423812 PM +02:00'),'66','DRA_REEVALUATE_OPEN_FAILURES','SYS','12166','RUN','SUCCEED ED',NULL,NULL,NULL,NULL,'0',NULL,NULL,NULL); insert into "SYS"."SCHEDULER$_JOB_RUN_DETAILS"("LOG_ID","LOG_DATE","REQ_STAR T_DATE","START_DATE","RUN_DURATION","INSTANCE_ID","SESSI ON_ID","SLAVE_PID","CPU_USED","ERROR#","ADDITIONAL_INFO","CREDENTIAL","DESTI NATION") values ('99',TO_TIMESTAMP_TZ('12-MAY-11 10.00.0 6.536282 PM +02:00'),NULL,TO_TIMESTAMP_TZ('12-MAY-11 10.00.03.047298 PM EURO PE/VIENNA'),TO_DSINTERVAL('+000 00:00:03'),'1','160,747' ,'22112',TO_DSINTERVAL('+000 00:00:00.08'),'0',NULL,NULL,NULL); insert into "SYS"."OBJ$"("OBJ#","DATAOBJ#","OWNER#","NAME","NAMESPACE","SUBN AME","TYPE#","CTIME","MTIME","STIME","STATUS","REMOTEOWN ER","LINKNAME","FLAGS","OID$","SPARE1","SPARE2","SPARE3","SPARE4","SPARE5"," SPARE6") values ('13098',NULL,'0','ORA$AT_OS_OPT_SY_7','

1',NULL,'66',TO_DATE('12-MAY-11', 'DD-MON-RR'),TO_DATE('12-MAY-11', 'DD-MONRR'),TO_DATE('12-MAY-11', 'DD-MON-RR'),'1',NULL,NULL,'0' ,NULL,'6','65535','0',NULL,NULL,NULL); If you need to backout that change, query the column SQL_UNDO: SQL_UNDO -------------------------------------------------------------------------------------------------------------------------delete from "SYS"."SCHEDULER$_EVENT_LOG" where "LOG_ID" = '99' and "LOG_DATE " = TO_TIMESTAMP_TZ('12-MAY-11 10.00.06.423812 PM +02:00 ') and "TYPE#" = '66' and "NAME" = 'DRA_REEVALUATE_OPEN_FAILURES' and "OWNER " = 'SYS' and "CLASS_ID" = '12166' and "OPERATION" = 'RU N' and "STATUS" = 'SUCCEEDED' and "USER_NAME" IS NULL and "CLIENT_ID" IS NUL L and "GUID" IS NULL and "DBID" IS NULL and "FLAGS" = '0 ' and "CREDENTIAL" IS NULL and "DESTINATION" IS NULL and ROWID = 'AAABbfAACA AAAzOAAO'; delete from "SYS"."SCHEDULER$_JOB_RUN_DETAILS" where "LOG_ID" = '99' and "LO G_DATE" = TO_TIMESTAMP_TZ('12-MAY-11 10.00.06.536282 PM +02:00') and "REQ_START_DATE" IS NULL and "START_DATE" = TO_TIMESTAMP_TZ('12 -MAY-11 10.00.03.047298 PM EUROPE/VIENNA') and "RUN_DURA TION" = TO_DSINTERVAL('+000 00:00:03') and "INSTANCE_ID" = '1' and "SESSION_ ID" = '160,747' and "SLAVE_PID" = '22112' and "CPU_USED" = TO_DSINTERVAL('+000 00:00:00.08') and "ERROR#" = '0' and "ADDITIONAL_INFO " IS NULL and "CREDENTIAL" IS NULL and "DESTINATION" IS NULL and ROWID = 'AAABbjAACAAAAztAAI'; delete from "SYS"."OBJ$" where "OBJ#" = '13098' and "DATAOBJ#" IS NULL and " OWNER#" = '0' and "NAME" = 'ORA$AT_OS_OPT_SY_7' and "NAM ESPACE" = '1' and "SUBNAME" IS NULL and "TYPE#" = '66' and "CTIME" = TO_DATE ('12-MAY-11', 'DD-MON-RR') and "MTIME" = TO_DATE('12-MAY -11', 'DD-MON-RR') and "STIME" = TO_DATE('12-MAY-11', 'DD-MON-RR') and "STAT US" = '1' and "REMOTEOWNER" IS NULL and "LINKNAME" IS NU LL and "FLAGS" = '0' and "OID$" IS NULL and "SPARE1" = '6' and "SPARE2" = '6 5535' and "SPARE3" = '0' and "SPARE4" IS NULL and "SPARE 5" IS NULL and "SPARE6" IS NULL and ROWID = 'AAAAASAABAAAEg1AAL'; Optimize It s best to create a (temporary) table of the contents of v$logmnr_contents to sa ve time and performance when querying the logs: SQL> create table mylog as select ... from v$logmnr_contents; Take care It s very important to end the LogMiner session with DBMS_LOGMNR.END_LOGMNR, as yo u will get an ORA-600 error when logging off: SQL> exec dbms_logmnr.end_logmnr(); Trying to use LogMiner concurrently from another session will give a ORA-01306: dbms_logmnr.start_logmnr() must be invoked before selecting from v$logmnr_conten ts. See MOS Note 62508.1 The LogMiner Utility for details. Recover the database using RMAN After finding the correct log sequence or SCN use it with RMAN s UNTIL-clause like

this: RMAN> recover database until scn 220123; or RMAN> recover database until logseq 43;

You might also like