Log miner database’ in kurulumu ile birlikte gelen ve
bir package yardımıyla create edilen bir opsiyon olarak düşünebiliriz.
Yapabilirlikleri aslında kimi zaman herhangi bir geri dönüş operasyonuna
kalkışmadan hızlı bir şekilde yapılmış olan bir hatayı düzeltebilmemize olanak
sağlar.
Log miner database seviyesinde yapılan bir takım işlemlerin geri
alınabilmesi için izlenilen bir yöntemdir. Kullanımı ile ilgili olarak
genelde yanlışlıkla yapıldığı düşünülen bir DML işlemini geri almak için
kullanılabilir diyebiliriz.
Log Miner’ ın kurulumu ve konfigure edilmesi ;
Log Miner’ ın çalışması için SUPPLEMENTAL_LOG_DATA_MIN değerinin
database’ de açık olması gerekmektedir. Aşağıdaki gibi kontrol edebilirsiniz ;
SQL> select SUPPLEMENTAL_LOG_DATA_MIN from v$database;
SUPPLEMENTAL_LOG_DATA_MIN
-------------------------------------
NO
Sonucun NO dönmesi durumunda aşağıdaki şekilde Alter edebiliriz ;
SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
Database altered.
Database altered.
Sonrasında log_miner’ ın ihtiyaç duyduğu nesnelerin create edilmesi için
aşağıdaki dizindeki sql dosyası çalıştırılır.
SQL>@$ORACLE_HOME/rdbms/admin/dbmslm.sql
Paket yaratıldı.
Erişim Yetkisi verme başarılı.
Aşağıdaki yetkinin ilgili kullanıcıya
GRANT EXECUTE_CATALOG_ROLE TO kamil;
Grant complete.
Package kolay erişim için public synonym tanımlanabilir. (schema name’ i
kullanılarak da erişilebilir.)
CREATE PUBLIC SYNONYM DBMS_LOGMNR FOR SYS.DBMS_LOGMNR;
Synonym created.
Log_miner’ ın redologları okuması için log_miner’ a tanıtılması, eklenmesi
gerekmektedir. Bunun için önce loglarımıza bakalım ;
SQL> SELECT distinct member LOGFILENAME FROM V$LOGFILE;
LOGFILENAME
C:\ORACLE\10GR2\ORADATA\TEST\REDO02.LOG
C:\ORACLE\10GR2\ORADATA\TEST\REDO01.LOG
C:\ORACLE\10GR2\ORADATA\TEST\REDO03.LOG
Log_miner package’ ina okuması için dahil etmek için;
BEGIN DBMS_LOGMNR.ADD_LOGFILE
('C:\ORACLE\10GR2\ORADATA\TEST\REDO01.LOG');
DBMS_LOGMNR.ADD_LOGFILE
('C:\ORACLE\10GR2\ORADATA\TEST\REDO02.LOG');
DBMS_LOGMNR.ADD_LOGFILE
('C:\ORACLE\10GR2\ORADATA\TEST\REDO03.LOG');
END;
/
PL/SQL procedure successfully
completed.
Bakacağı son archive’ ı görmek için ;
SELECT NAME FROM V$ARCHIVED_LOG
WHERE FIRST_TIME = (SELECT MAX(FIRST_TIME) FROM V$ARCHIVED_LOG);
WHERE FIRST_TIME = (SELECT MAX(FIRST_TIME) FROM V$ARCHIVED_LOG);
NAME
C:\ORACLE\10GR2\FLASH_RECOVERY_AREA\TEST\ARCHIVELOG\2011_02_08\O1_MF_1_11_6O2RV9M1_.ARC
C:\ORACLE\10GR2\FLASH_RECOVERY_AREA\TEST\ARCHIVELOG\2011_02_08\O1_MF_1_12_6O2RVHG5_.ARC
Log_Miner kurulumu tamamlanmış oldu, şimdi start ediyoruz ;
BEGIN
DBMS_LOGMNR.START_LOGMNR
(options =>
dbms_logmnr.dict_from_online_catalog);
END;
/
DBMS_LOGMNR.START_LOGMNR
(options =>
dbms_logmnr.dict_from_online_catalog);
END;
/
PL/SQL procedure successfully
completed.
Sonuçları Select etmek içinse v$logmnr_contents view’ ini
kullanabiliriz.
SELECT username,
TO_CHAR (timestamp, 'mm/dd/yy hh24:mi:ss') timestamp,
seg_type_name,
seg_name,
table_space,
session# SID,
serial#,
operation,
sql_redo,
sql_undo,
session_info
FROM v$logmnr_contents
Şimdi bir test yapalım, user_test adında bir userımız var, bu userla önce
bir tablo create edelim, sonrasında içerisinde data insert edelim. En son
olarak da yaptığımız bu işlemin yanlış olduğunu varsayıp nasıl
düzeltebileceğimize bakalım.
create table log_miner_test as select * from dba_tables where rownum < 2 ;
Table created.
insert into log_miner_test select * from log_miner_test ;
1 row created.
commit
Commit complete.
v$logmnr_contents tablosundan select ediyoruz.
SELECT username,
TO_CHAR (timestamp, 'mm/dd/yy hh24:mi:ss') timestamp,
seg_type_name,
seg_name,
table_space,
session# SID,
serial#,
operation,
sql_redo,
sql_undo,
session_info
FROM v$logmnr_contents
where seg_name = 'LOG_MINER_TEST'
and username = 'USER_TEST'
Selectin çıktısı olarak
sql_redo, sql_undo ve session_info kısımlarını ayrı olarak ekliyorum ;
USERNAME
|
TIMESTAMP
|
SEG_NAME
|
TABLE_SPACE
|
SID
|
SERIAL#
|
OPERATION
|
USER_TEST
|
02.08.2011 17:59
|
LOG_MINER_TEST
|
128
|
49
|
DDL
|
|
USER_TEST
|
02.08.2011 18:00
|
LOG_MINER_TEST
|
TEST_TBS
|
128
|
49
|
INSERT
|
Sql_redo;
insert into "USER_TEST"."LOG_MINER_TEST"("OWNER","TABLE_NAME","TABLESPACE_NAME","CLUSTER_NAME","IOT_NAME","STATUS","PCT_FREE","PCT_USED","INI_TRANS","MAX_TRANS","INITIAL_EXTENT","NEXT_EXTENT","MIN_EXTENTS","MAX_EXTENTS","PCT_INCREASE","FREELISTS","FREELIST_GROUPS","LOGGING","BACKED_UP","NUM_ROWS","BLOCKS","EMPTY_BLOCKS","AVG_SPACE","CHAIN_CNT","AVG_ROW_LEN","AVG_SPACE_FREELIST_BLOCKS","NUM_FREELIST_BLOCKS","DEGREE","INSTANCES","CACHE","TABLE_LOCK","SAMPLE_SIZE","LAST_ANALYZED","PARTITIONED","IOT_TYPE","TEMPORARY","SECONDARY","NESTED","BUFFER_POOL","ROW_MOVEMENT","GLOBAL_STATS","USER_STATS","DURATION","SKIP_CORRUPT","MONITORING","CLUSTER_OWNER","DEPENDENCIES","COMPRESSION","DROPPED")
values
('SYS','CON$','SYSTEM',NULL,NULL,'VALID','10','40','1','255','65536',NULL,'1','2147483645',NULL,'1','1','YES','N','2786','12','0','0','0','20','0','0','
1',' 1','
N','ENABLED','2786',TO_DATE('30/08/2005', 'DD/MM/RRRR'),'NO',NULL,'N','N','NO','DEFAULT','DISABLED','YES','NO',NULL,'DISABLED','YES',NULL,'DISABLED','DISABLED','NO');
sql_undo;
delete from "USER_TEST"."LOG_MINER_TEST" where
"OWNER" = 'SYS' and "TABLE_NAME" = 'CON$' and
"TABLESPACE_NAME" = 'SYSTEM' and "CLUSTER_NAME" IS NULL and
"IOT_NAME" IS NULL and "STATUS" = 'VALID' and
"PCT_FREE" = '10' and "PCT_USED" = '40' and
"INI_TRANS" = '1' and "MAX_TRANS" = '255' and
"INITIAL_EXTENT" = '65536' and "NEXT_EXTENT" IS NULL and
"MIN_EXTENTS" = '1' and "MAX_EXTENTS" = '2147483645' and
"PCT_INCREASE" IS NULL and "FREELISTS" = '1' and
"FREELIST_GROUPS" = '1' and "LOGGING" = 'YES' and
"BACKED_UP" = 'N' and "NUM_ROWS" = '2786' and
"BLOCKS" = '12' and "EMPTY_BLOCKS" = '0' and
"AVG_SPACE" = '0' and "CHAIN_CNT" = '0' and
"AVG_ROW_LEN" = '20' and "AVG_SPACE_FREELIST_BLOCKS" = '0'
and "NUM_FREELIST_BLOCKS" = '0' and "DEGREE" = '
1' and "INSTANCES" =
' 1' and "CACHE" =
' N' and "TABLE_LOCK" = 'ENABLED' and
"SAMPLE_SIZE" = '2786' and "LAST_ANALYZED" =
TO_DATE('30/08/2005', 'DD/MM/RRRR') and "PARTITIONED" = 'NO' and
"IOT_TYPE" IS NULL and "TEMPORARY" = 'N' and "SECONDARY"
= 'N' and "NESTED" = 'NO' and "BUFFER_POOL" = 'DEFAULT' and
"ROW_MOVEMENT" = 'DISABLED' and "GLOBAL_STATS" = 'YES' and
"USER_STATS" = 'NO' and "DURATION" IS NULL and
"SKIP_CORRUPT" = 'DISABLED' and "MONITORING" = 'YES' and
"CLUSTER_OWNER" IS NULL and "DEPENDENCIES" = 'DISABLED' and
"COMPRESSION" = 'DISABLED' and "DROPPED" = 'NO' and ROWID =
'AAAMmXAAHAAAAKNAAA';
session_info;
login_username=USER_TEST client_info= OS_username=WINDB\Administrator
Machine_name=CB\WINDB OS_terminal=WINDB OS_process_id=4720:488
OS_program_name=toad.exe
görüldüğü üzere yapmış olduğumuz insert işlemine karşılık sorunu düzeltmek
adına delete scriptini verdi, delete işlemi yapmış olsaydık insert scriptini
verecekti.
Son olarak log miner’ ın çalışma
şeklinden biraz bahsetmek gerekirse, ana mantığı redologları okumaktan geçiyor
sonrasında ise çıkan archive’ lar üzerinden okumaya devam ediyor. Dolayısıyla
geçmişe dönük ne kadar archive’ ınız var ise o kadar geriye gidebilirsiniz
demektir.
Hiç yorum yok:
Yorum Gönder