深入分析Oracle數(shù)據(jù)庫日志文件(2)
2024-08-29 13:37:59
供稿:網(wǎng)友
四、如何利用LogMiner分析Oracle8的日志文件
雖然說LogMiner是Oracle8i才推出來,但我們同樣可以用它來分析Oracle8的日志文件,只不過稍微麻煩了一點(diǎn),并且有一定的限制,下面是具體做法:
我們首先復(fù)制Oracle8i的$ORACLE_HOME/rdbms/admin/dbmslmd.sql腳本到Oracle8數(shù)據(jù)庫所在主機(jī)的同樣目錄;這個(gè)腳本用于創(chuàng)建dbms_logmnr_d包(注重,Oracle9i中還將創(chuàng)建dbms_logmnr包),假如是8.1.5腳本名字為dbmslogmnrd.sql。然后在Oracle8的數(shù)據(jù)庫上運(yùn)行這個(gè)腳本,之后使用dbms_logmnr_d.build過程創(chuàng)建字典信息文件。現(xiàn)在我們就可以把Oracle8的歸檔日志連同這個(gè)字典信息文件復(fù)制到Oracle8i數(shù)據(jù)庫所在的主機(jī)上,之后在Oracle8i數(shù)據(jù)庫中從上面分析過程的第三步開始分析Oracle8的日志,不過
dbms_logmnr.start_logmnr()中使用的是Oracle8的字典信息文件。
按照我前面所說的那樣,假如不是字典文件,我們則可以直接將Oracle8的歸檔日志復(fù)制到Oracle8i數(shù)據(jù)庫所在主機(jī),然后對(duì)它進(jìn)行分析。
其實(shí)這里涉及到了一個(gè)跨平臺(tái)使用LogMiner的問題,筆者做過試驗(yàn),也可以在Oracle9i中來分析Oracle8i的日志。但這些都是有所限制的,主要表現(xiàn)在:
1、LogMiner所使用的字典文件必須和所分析的日志文件是同一個(gè)數(shù)據(jù)庫所產(chǎn)生的,并且該數(shù)據(jù)庫的字符集應(yīng)和執(zhí)行LogMiner數(shù)據(jù)庫的相同。這很好理解,假如不是同一個(gè)數(shù)據(jù)庫所產(chǎn)生就不存在對(duì)應(yīng)關(guān)系了。
2、生成日志的數(shù)據(jù)庫硬件平臺(tái)和執(zhí)行LogMiner數(shù)據(jù)庫的硬件平臺(tái)要求一致,操作系統(tǒng)版本可以不一致。筆者做試驗(yàn)時(shí)(假如讀者有愛好可以到我網(wǎng)站http://www.ncn.cn上下載試驗(yàn)全過程,因?yàn)樘L(zhǎng)就不放在這里了),所用的兩個(gè)數(shù)據(jù)庫操作系統(tǒng)都是Tru64 UNIX,但一個(gè)是 V5.1A,另一個(gè)則是V4.0F。假如操作系統(tǒng)不一致則會(huì)出現(xiàn)下面的錯(cuò)誤:
ORA-01284: file /data6/cyx/logmnr/arch_1_163570.arc cannot be opened
ORA-00308: cannot open archived log '/data6/cyx/logmnr/arch_1_163570.arc'
ORA-27048: skgfifi: file header information is invalid
ORA-06512: at "SYS.DBMS_LOGMNR", line 63
ORA-06512: at line 1
五、分析v$logmnr_contents
前面我們已經(jīng)知道了LogMiner的分析結(jié)果是放在v$logmnr_contents中,這里面有很多信息,我們可以根據(jù)需要追蹤我們感愛好的信息。那么我們通常感愛好的有哪些呢?
1、追蹤數(shù)據(jù)庫結(jié)構(gòu)變化情況,即DDL操作,如前所述,這個(gè)只有Oracle9i才支持:
SQL> select timestamp,sql_redo from v$logmnr_contents2
where upper(sql_redo) like '%CREATE%';
TIMESTAMP
-------------------
SQL_REDO
-------------------------
2003-09-21 10:01:55
create table t (c1 number);
2、追蹤用戶誤操作或惡意操作:
例如我們現(xiàn)實(shí)中有這樣需求,有一次我們發(fā)現(xiàn)一位員工通過程序修改了業(yè)務(wù)數(shù)據(jù)庫信息,把部分電話的收費(fèi)類型改成免費(fèi)了,現(xiàn)在就要求我們從數(shù)據(jù)庫中查出到底是誰干的這件事?怎么查?LogMiner提供了我們分析日志文件的手段,其中v$logmnr_contents的session_INFO列包含了下面的信息:
login_username=NEW_97
client_info= OS_username=oracle8 Machine_name=phoenix1
OS_terminal=ttyp3 OS_PRocess_id=8004 OS_program name=sqlplus@phoenix1
(TNS V1-V3)
雖然其中信息已經(jīng)很多了,但在我們的業(yè)務(wù)數(shù)據(jù)庫中,程序是通過相同的login_username登錄數(shù)據(jù)庫的,這樣單從上面的信息是很難判定的。
不過我們注重到,因?yàn)楣緫?yīng)用服務(wù)器不是每個(gè)人都有權(quán)限在上面寫程序的,一般惡意程序都是直接通過他自己的PC連到數(shù)據(jù)庫的,這就需要一個(gè)準(zhǔn)確的定位。ip追蹤是我們首先想到的,并且也滿足我們的實(shí)際要求,因?yàn)楣緝?nèi)部IP地址分配是統(tǒng)一治理的,能追蹤到IP地址我們就可以準(zhǔn)確定位了。但從面的SESSION_INFO中我們并不能直接看到IP,不過我們還是有辦法的,因?yàn)檫@個(gè)SESSION_INFO里面的內(nèi)容其實(shí)是日志從V$SESSION視圖里提取的,我們可以在生產(chǎn)數(shù)據(jù)庫中創(chuàng)建一個(gè)追蹤客戶端IP地址的觸發(fā)器:
create or replace trigger on_logon_trigger
after logon on database
begin
dbms_application_info.set_client_info(sys_context('userenv', 'ip_address'));
end;
/
現(xiàn)在,我們就可以在V$SESSION視圖的CLIENT_INFO列中看到新登錄的客戶端IP地址了。
那么上面的提出的問題就可以迎刃而解了。假如被更新的表名為HMLX,我們就可以通過下面的SQL來找到所需信息:
SQL > select session_info ,sql_redo from v$logmnr_contents
2 where upper(Operation) = 'UPDATE' and upper(sql_redo) like '%HMLX%'
3 /
SESSION_INFO
-----------------------------------------
SQL_REDO
-----------------------------------------
login_username=C client_info=10.16.98.26 OS_username=sz-xjs-chengyx Machine_name
=GDTEL/SZ-XJS-CHENGYX
update "C"."HMLX" set "NAME" = 'free' where "NAME" = 'ncn.cn' and ROWID = 'AAABhTAA
FAAABRaAAE';