Çoğu zaman herkez alert log dosyalarında neler döndüğünü merak eder. Bu merakı gidermenin en kısa yolu dosyayı işletim sistemi ortamında açmak ve okumaktır. Yada alert log dosyalarını okuyan işleyen bir tool kullanmak olabilir. Ben bu yazım da kendi SQL cümlelerimiz ile alert loglarını okumanın birkaç yolunu göstermeye çalışacağım.
Alert log dosyasına ne için ihtiyacımız olduğunu kısaca soylemek gerekir ise DB de olan olayları yakalamamızı sağla ne zaman açıldı hangi hataları aldı DB parametreleri neler gibi....
Alert log dosyaları eğer siz konumunu değiştirmediyseniz
C:\ORACLE\PRODUCT\10.2.0\ADMIN\ORCL\BDUMP dizininde bulabilirsiniz. Ama ben yerini değiştirdim ve şu anda nerede olduğunu bilmiyorum diyorsanız
SELECT value FROM v$parameter WHERE name='background_dump_dest';
sorgusu ile konumunu görebiliriz. Farkettiyseniz v$parameter view'inde database için tanımladığız parametleri bulacaksınız.
select * from dba_directories
Sorgusu ile directories'lere bakıyoruz. Eğer ilgili directory yok ise oluşturacağiz.
Asagidaki kod ile bir DIRECTORIES olusturuyorum. Daha sonra scott kullanicisi için bu directory okuma hakki veriyoruz. Sonrasinda SCOTT kullanici için bir external tablo olusturuyorum.Asagidaki islemleri tek tek de yapabiliriz.
DECLARE
--alert_SID.log dosyasinin oldugu dizin
bdump_dizini VARCHAR2(200);
--Hangi SID ilebagli oldugumuz bunu kullanmamizdaki amaç alert_SID.log (alert_orcl.log) seklinde bir dosya olmasi.SID ismi dinamik olarak veriliyor.
v_sid VARCHAR2(16);
--bunu External table olusturma sirasinda dogru script üretim üretmedigimi görmek için tanimladim.
v_dyn_sql VARCHAR2(5000);
--hatalar için tanimlamalar.
objectexists EXCEPTION;
PRAGMA EXCEPTION_INIT(objectexists,-955);
BEGIN
-- alert_orcl.log dosyasinin konumunu ögreniyorruz.
SELECT VALUE
INTO bdump_dizini
FROM v$parameter
WHERE NAME = 'background_dump_dest';
--ekrana dizini yazdiriyorum.
dbms_output.Put_line(bdump_dizini);
-- database'e yeni bir directory tanimliyoruz.
EXECUTE IMMEDIATE 'CREATE OR REPLACE DIRECTORY bdump_dir AS '''
||bdump_dizini
||'''';
--bu directory için SCOTT kullanicina okuma (erisim) hakki veriyorum.
EXECUTE IMMEDIATE 'GRANT READ ON DIRECTORY bdump_dir TO scott
';
--Database'e baglandigim SID ismini ögreniyorum.
SELECT instance_name
INTO v_sid
FROM v$instance;
--ekrana V_SID'yi yazdiriyorum kontrol amaçli.
dbms_output.Put_line(v_sid);
COMMIT;
-- yukarida external table için olusturdugum parametlerler ile simdi external tablomu olusturyorum.
v_dyn_sql := 'CREATE TABLE scott.ALERT_LOG_EXTERNAL
(TEXT VARCHAR2(255)
) ORGANIZATION EXTERNAL
(TYPE ORACLE_LOADER
DEFAULT DIRECTORY BDUMP_DIR
ACCESS PARAMETERS
(records delimited by newline
nobadfile
nologfile
)
LOCATION (''alert_'
||v_sid
||'.log'')
)
REJECT LIMIT UNLIMITED';
--dogru script üretip üretmedgimi kontrol için ekrana basiyorum.
dbms_output.Put_line(v_dyn_sql);
EXCEPTION
WHEN objectexists THEN
NULL;
END;
/
External tablomuzu oluşturduktan sonra artık alert loglarımız okuyabiliriz.
SELECT rownum row_num ,text FROM SCOTT.alert_log_external order by 1 desc;
İlk olarak log filemizi okumayı başardık fakat bu çokda kullanışlı görünmüyor şu aşamada. Çeşitli süslemeler ile daha okunabilir bir hale getirmeyeçalışacağiz.
alert log zamanlarını yakalamak için aşağıdaki gibi bir foksiyon oluşturalım.
CREATE OR REPLACE FUNCTION scott.Alert_log_date
(text IN VARCHAR2)
RETURN DATE
IS
invaliddate EXCEPTION;
PRAGMA EXCEPTION_INIT(invaliddate,-1846);
BEGIN
RETURN To_date(text,'Dy Mon DD HH24:MI:SS YYYY','NLS_DATE_LANGUAGE=AMERICAN');
EXCEPTION
WHEN invaliddate THEN
RETURN NULL;
END;
/
Şimdi bu fonksiyonu kullarak alert loglarımızı okuyalım , burada tarih gördüğü satırlarda tarih column'u ekliyor.
SELECT ROWNUM row_num ,scott.alert_log_date(text) alert_date, text
FROM scottt.alert_log_external
WHERE ROWNUM <50
Yukarıdaki sorguda tarih alanı boş gelen yerlere tarihi eklemek için aşağıdaki yapıyı kullanmabiliriz. Burada iki tarih arasına bir önceki tarihi ekleyerek her satırın başına tarih değerini atıyor. Bu sayede olayların hangi tarihte meydana geldiğini daha iyi gözlemleyebiliyoruz (monitor edebiliyoruz).
SELECT row_num ,LAST_VALUE(alert_date IGNORE NULLS) OVER(ORDER BY row_num
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) alert_date
,alert_text
FROM (SELECT ROWNUM row_num
,SCOTT.alert_log_date(text) alert_date
,text alert_text
FROM SCOTT.alert_log_external
)
WHERE ROWNUM < 50>
Aşağıdaki sorguda ise her bir hatanın ,olayın gerekleştiği zamanıki ilk satırın numarasını diğer satırlara yayıyor.
SELECT row_num
,LAST_VALUE(low_row_num IGNORE NULLS)
OVER(ORDER BY row_num ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) start_row
,LAST_VALUE(alert_date IGNORE NULLS)
OVER(ORDER BY row_num ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) alert_date
,alert_text
FROM (SELECT ROWNUM row_num
,NVL2(SCOTT.alert_log_date(text),ROWNUM,NULL) low_row_num
,SCOTT.alert_log_date(text) alert_date
,text alert_text
FROM SCOTT.alert_log_external
)
WHERE ROWNUM < 50
en son oluşturduğumuz sorgu sonucundan bir view oluşturuyoruz.
CREATE OR REPLACE FORCE VIEW scott.alert_log as
SELECT row_num
,LAST_VALUE(low_row_num IGNORE NULLS)
OVER(ORDER BY row_num ROWS BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW) start_row
,LAST_VALUE(alert_date IGNORE NULLS)
OVER(ORDER BY row_num ROWS BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW) alert_date
,alert_text
FROM (SELECT ROWNUM row_num
,NVL2(scott.alert_log_date(text),ROWNUM,NULL) low_row_num
,scott.alert_log_date(text) alert_date
,text alert_text
FROM scott.alert_log_external
);
--SYNONYM oluşturuyorum.
DECLARE
objectexists EXCEPTION;
PRAGMA EXCEPTION_INIT(objectexists,-955);
BEGIN
EXECUTE IMMEDIATE 'CREATE PUBLIC SYNONYM alert_log FOR scott.alert_log:';
-- E?er böyle bir synonym var ise silip yeniden yarat?yoruz.
EXCEPTION
WHEN objectexists THEN
EXECUTE IMMEDIATE 'DROP PUBLIC SYNONYM alert_log
';
EXECUTE IMMEDIATE 'CREATE PUBLIC SYNONYM alert_log FOR scott.alert_log
';
END;
/
--evet gerekli hazırlıkalrı yaptıktan sonra şimdi artık view üzerinde çeşitli sorgular yapabiliriz.
SELECT row_num,
alert_text
FROM alert_log
WHERE alert_date > SYSDATE - 1 / 24
/
ora hatalarını görmek için aşağıdaki sorguyu kullanabiliriz
regexp_like kullanımı ile ilgi bilgi için buraya bakabilrisiniz
SELECT row_num,
alert_date,
alert_text
FROM alert_log
WHERE start_row IN (SELECT start_row
FROM alert_log
WHERE Regexp_like(alert_text,'ORA-'))
AND alert_date > Trunc(SYSDATE,'MON')
/
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment