Professional Documents
Culture Documents
Carl Dudley
Staffordshire University, UK
Online Log
Files
Data
Dictionary Archive
Log Files
LogMiner
Dictionary
File
~~~~~~~~~~~
~~~~~~~~~~~
~~~~~~~~~~~
~~~~~~~~~~~ Fixed (v$) View
~~~~~~~~~~~
EXECUTE dbms_logmnr_d.build
(dictionary_filename => orcldict.ora
,dictionary_location => c:\lmnr);
Created by dbmslogmnr.sql
(dbmslm.sql/prvtlm.plb on 8.1.6)
EXECUTE dbms_logmnr.add_logfile
(Options => dbms_logmnr.NEW
,logfilename => log1orcl.ora);
EXECUTE dbms_logmnr.add_logfile
(Options => dbms_logmnr.ADDFILE
,logfilename => log2orcl.ora);
EXECUTE dbms_logmnr.add_logfile
(Options => dbms_logmnr.ADDFILE
,logfilename => log3orcl.ora);
BEGIN
file_out := UTL_FILE.FOPEN(log_dir,log_list,'w');
FOR log_rec IN log_cur LOOP
IF counter = 1 THEN
file_buff := 'DBMS_LOGMNR.ADD_LOGFILE
('''||LOG_REC.NAME||''',DBMS_LOGMNR.NEW);';
ELSE
file_buff := 'DBMS_LOGMNR.ADD_LOGFILE
('''||LOG_REC.NAME||''',DBMS_LOGMNR.ADDFILE);';
END IF;
UTL_FILE.PUT_LINE(file_out,'BEGIN');
UTL_FILE.PUT_LINE(file_out,file_buff);
UTL_FILE.PUT_LINE(file_out,'END;');
UTL_FILE.PUT_LINE(file_out,'/');
counter := counter + 1;
END LOOP;
UTL_FILE.FCLOSE(file_out);
END;
Contents of listlogs.sql
BEGIN
DBMS_LOGMNR.ADD_LOGFILE('D:\ORACLE\ORADATA\ORAC\ARCHIVE\ORACT001S00192.ARC
,DBMS_LOGMNR.NEW);
END;
/
BEGIN
DBMS_LOGMNR.ADD_LOGFILE('D:\ORACLE\ORADATA\ORAC\ARCHIVE\ORACT001S00193.ARC
,DBMS_LOGMNR.ADDFILE);
END;
/
...
EXECUTE dbms_logmnr.start_logmnr
(Dictfilename => orcldict.ora
,StartTime => 01-dec-1999 09:00:00
,EndTime => 01-dec-1999 09:30:00);
SQL_REDO
--------
delete from EMP where EMPNO = 7777 and ROWID = `AAACOOAEBAADPCACA';
SQL_UNDO
--------
insert into EMP(EMPNO, SAL) values (7777,1500)
Without a dictionary file, you can expect to see this kind of output
SELECT username
,scn
,TO_CHAR(timestamp
,'dd-mon-yyyy hh24:mi:ss') time
,sql_redo
,sql_undo
FROM v$logmnr_contents
WHERE username = 'FRED'
AND TO_CHAR(timestamp
,'dd-mon-yyyy hh24:mi:ss')
BETWEEN 01-DEC-1999 09:02:00'
AND 01-DEC-1999 09:04:00';
Log Miner generates low-level SQL, not what was actually issued
Cannot fully trace an application
-- If an update statement updates three rows, three separate
row-level update statements are shown in SQL_UNDO column
3 rows updated.
SQL_UNDO
------------------------------------------------------------
update EMP set SAL = 2450 where rowid = `AAACOOAEBAADPCACI';
update EMP set SAL = 1300 where rowid = `AAACOOAEBAADPCACN';
update EMP set SAL = 5000 where rowid = `AAACOOAEBAADPCACG';
Logminer can build a dictionary file from an Oracle 8.0 database using
dbms_logmnr_d.build
EXECUTE dbms_logmnr.start_logmnr(
StartTime => `07-Aug-99, EndTime => `15-Aug-99'
,DictFileName => `/usr/local/dict.ora');
v$logmnr_logs
Information on log files under analysis
Log sequence numbers for each log
-- If the log files do not have consecutive sequence
numbers, an entry is generated signifying a gap
High and low SCNs, high and low times of all currently
registered logs
v$logmnr_parameters
Current LogMiner session parameters
High and low SCNs, high and low times, info, status
v$logmnr_contents
Results of analysis
Contains masses of information ( > 50 columns! )
seg_type_name
Only tables are supported in the first release
rollback
1 represents a rollback operation otherwise 0
row_id
Only The ROWID of the affected row
EXECUTE dbms_logmnr.start_logmnr(
,DictFileName => `/usr/local/dict.ora
,Options => dbms_logmnr.USE_COLMAP);
Changes to the ename column in freds emp table will be shown in the
first set (PH1...) of placeholder columns
Undo and redo values for any transaction making changes to ename in
the emp table can be seen in the ph1_undo and ph1_redo columns
The SQL can also be seen in sql_redo and sql_undo, but the
placeholders make searching for the information much easier
EXECUTE dbms_logmnr_d.build
(options => dbms_logmnr_d.STORE_IN_REDO_LOGS);
No dictionary file to be managed
Dictionary is backed up via the redo logs
-- Produces lots of redo (minimum 12Mb) - but faster than flat file
Database must be in archivelog mode
No DDL allowed during extraction, so dictionary is consistent
The online data dictionary can also be used to analyze the logs
Available when database is open
Specify the following in dbms_logmnr.start_logmnr procedure
EXECUTE dbms_logmnr.start_logmnr
(options => dbms_logmnr.DICT_FROM_ONLINE_CATALOG);
Use this to analyze recent redo logs or when the structure of objects
under test has not changed
Absence of mismatches between online dictionary and redo
log contents is assumed
EXECUTE dbms_logmnr.start_logmnr
(options => dbms_logmnr.DICT_FROM_REDO_LOGS
+ dbms_logmnr.DDL_DICT_TRACKING);
SELECT dbms_logmnr.mine_value(redo_value,FRED.EMP.SAL)
,sql_redo
FROM v$logmnr_contents
WHERE dbms_logmnr.mine_value(redo_value,FRED.EMP.SAL) IS NOT NULL
OR (dbms_logmnr.mine_value(redo_value,FRED.EMP.SAL) IS NULL
AND dbms_logmnr.column_present(redo_value,FRED.EMP.SAL) = 1);
Populates the cscn column and can show rolled back transactions
SCN CSCN SQL_REDO
---- ---- -------------------------------------------------------------
2012 2017 insert into FRED.DEPT values(50,ARTS,PARIS);
2016 2017 delete from FRED.DEPT where ROWID = `AAACOOAEBAADPCACI;
Can be programmed to run continuously and wait for new redo logs
Set wait_for_log flag in
dbms_logmnr_session.create_session
Carl Dudley
Staffordshire University, UK