30 Haziran 2010 Çarşamba

Physical Standby Automatic Archivelog Deletion / Maintenance

Selamlar,

Genelde yazılarımın başlıklarını Türkçe, içeriği Türkçe ve mümkün olan bütün kelimeleri de yine Türkçe yazmaya özen ve dikkat gösteriyorum. Ancak bu sefer başlığı İngilizce yazmamın nedeni birçok insanın İngilizce olarak arama yapması ancak Türkçe bulduğu zaman daha işlerine yaramasını sağlayabilmek. Etiket olarakta ayrıca ekledim.

Geçtiğimiz gün tarafıma iletilen bir soru üzerine çözüm ürettim ancak ürettiğim çözümün internet üzerinde, bu başlık ile ilişkilendirilmediğini gördüm. Konu şu; bir fiziksel veritabanımız var ve veritabanınızın v$archived_log fixed view'ını görüntülediğiniz zaman "applied" başlığı altındaki en güncel archivelog'un, fiziksel veritabanınıza işlendiğini gördünüz. v$dataguard_status view'ında da işler yolunda gidiyor. Peki bu oluşan archivelog'lar neden silinmiyor? Buradaki önemli sorulardan birisi budur aslında. Archivelog'ların bakımı (silinmesi, yedeklenmesi) ile ilgili inanılmaz boyutlarda soru - cevap internet üzerinde mevcut ancak data guard söz konusu olunca işler değişiyor.

Bunu sağlayabilmenin iki tane yolu var. Archivelog'ları Oracle'a otomatik olarak sildirtebilirsiniz ya da yedeği alınırken silinebilir. Her iki yolu da anlatacağım.

1) Archivelog'ların Oracle Tarafından Otomatik Olarak Silinmesi:

Bunu sağlayabilmek için 2 tane parametre tanımlamamız gerekiyor. Bir tanesi db_recovery_file_dest ve diğeri de db_recovery_file_dest_size. Bu parametreleri 10g için SGA_TARGET, 11g için MEMORY_TARGET gibi düşünebilirsiniz (mantık aynı, görevleri farklı). Oracle oluşan archivelog'ları tanımlamış olduğunuz db_recovery_file_dest alanına;

/db_recovery_file_dest/ORACLE_SID/archivelog/DATE/%arc_%s_%t şeklinde tanımlar. Buradaki archivelog formatını ise log_archive_format parametresi belirler. Oracle oluşan archivelog'ları gün gün ayırır, silinmesi gerekenleri siler. Silinmesi gerekenler nedir? db_recovery_file_dest_size parametresine tanımladığınız bilgi eğer %100'e yaklaşmış ise size uyarıda bulunur. Tepki vermezseniz kendisi otomatik olarak siler! Bu arada bu iki parametreyi de eğer spfile kullanıyorsanız dinamik olarak tanımlayabilirsiniz. (alter system ... scope=both);

Bu uyarının çıktısı ise şöyle olacaktır;

Errors in file /usr/ORACLE/u01/oracle/admin/smstby/udump/smstby_rfs_18686.trc:
ORA-19815: WARNING: db_recovery_file_dest_size of 1073741824 bytes is 97.09% used, and has 31258624 remaining bytes available.
************************************************************************
You have following choices to free up space from flash recovery area:
1. Consider changing RMAN RETENTION POLICY. If you are using Data Guard,
then consider changing RMAN ARCHIVELOG DELETION POLICY.
2. Back up files to tertiary device such as tape using RMAN
BACKUP RECOVERY AREA command.
3. Add disk space and increase db_recovery_file_dest_size parameter to
reflect the new space.
4. Delete unnecessary files using RMAN DELETE command. If an operating
system command was used to delete files, then use RMAN CROSSCHECK and
DELETE EXPIRED commands.
************************************************************************

Uyarının nedeni db_recovery_file_dest_size'ın neredeyse dolmuş olması. Yukarıdaki örnekte %97 dolu durumda gözüküyor. Peki bu 4 maddeyi yapmazsanız Oracle ne yapıyor? O da aşağıda;

Wed Jun 30 09:31:40 2010
RFS[13]: Archived Log: '/usr/ORACLE/archive/SMSTBY/flash_recovery_area/SMSTBY/archivelog/2010_06_30/o1_mf_1_48375_62oqpf58_.arc'
Primary database is in MAXIMUM PERFORMANCE mode
Deleted Oracle managed file /usr/ORACLE/archive/SMSTBY/flash_recovery_area/SMSTBY/archivelog/2010_06_30/o1_mf_1_48372_62on259d_.arc
Deleted Oracle managed file /usr/ORACLE/archive/SMSTBY/flash_recovery_area/SMSTBY/archivelog/2010_06_30/o1_mf_1_48373_62oojwrq_.arc

Veritbanının devamlılığını sağlayabilmek için bu archivelog dosyalarını otomatik olarak siliyor.

Bu veritabanı için db_recovery_file_dest parametresini /usr/ORACLE/archive/SMSTBY/ olarak tanımladım ancak Oracle archivelog'ları /usr/ORACLE/archive/SMSTBY/flash_recovery_area/SMSTBY/archivelog/2010_06_30/ altında oluşturdu. Bu da kendisinin yönettiğini gösteriyor. Bunu da yapabilmek için ilgili dizinde Oracle kullanıcısının (unix) okuma ve yazma hakkının olması gerekiyor. Bu bilgiyi işletim sistemi yöneticisinden alabilirsiniz.

2) RMAN ile Archivelog'ların Silinmesi:

Bir diğer yöntem ise her zaman geçerli olan Recovery Manager ile archivelog'ların yedeklenmesi. Bu başlıkta kendi içerisinde ikiye ayrılabilir. Birincisi kişinin *nix üzerinde oluşan archivelog'ları elle silmesi, diğer de bu log'ları RETENTION PERIOD belirleyerek "obsolete" hale getirerek Recovery Manager tarafından sildirmesi. Ben ikinci yolu her zaman daha olumlu buluyorum çünkü elle silindiği zaman ek işler ve masraf devreye giriyor.

Elle sildiğimiz zaman bunu Oracle'a bildirmek zorundayız. Oracle otomatik olarak bu archivelog'ların silindiğini anlayamaz. Yedekleme yaparken hata alırsınız ve yedeklemeye çalışır sonra da bulamıyorum der. Bunun için;

RMAN> crosscheck archivelog all;

Komutunu amacı archivelog'ları Oracle'a göstertmek ve varlığını öğretmek. Crosscheck komutundan sonra "obsolete" archivelog'ları silebilmek için;

RMAN> delete noprompt obsolete;

Bu yöntemler eski archivelog'lardan kurtulabilirsiniz. Diğer yöntemde ise recovery catalog değil de control dosyasını yedek listelemede kullandığınızı varsayıyorum. Control dosyasının yedek bilgilerini tuttuğunu ve aşağıdaki parametreye göre bakımını yapması gerektiğini söyleyebilirim;

RMAN> CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 7 DAYS;

Yukarıdaki komut aldığınız yedeklerin, archivelog'ların vb. 7 gün boyunca "expired" ya da "obsolete" olmayacağını garanti eder.

RMAN> CONFIGURE RETENTION POLICY TO REDUNDANCY 5;

Yukarıdaki komut ise aldığınız 5 tane veritabanı yedeğinden sonraki 6ncı ile birlikte, 1ncinin "expired" yani aslında kullanılamaz olarak etiketlenmesini sağlar.

Peki bu komutların standby archivelog'ları ile ne ilgisi var? Bir diğer parametrenin tanımlanması ile;

RMAN> CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON STANDBY;

Varsayılan değeri NONE olan yukarıdaki parametreyi APPLIED ON STANDBY ile değiştirirseniz eğer "obsolete" olan archivelog'lar yedekleme sırasında standby veritabanından silinecektir.

Eğer yedekleme işlemini birincil veritabanında yapıyorsanız;

Birincil veritabanında;

RMAN> CONFIGURE ARCHIVELOG DELETION POLICY TO NONE;

Yedek veritabanında;

RMAN> CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON STANDBY;

Eğer yedeklemeyi yedek veritabanında yapıyorsanız;

Birincil veritabanında;

RMAN> CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON STANDBY;

Yedek veritabanında;

RMAN> CONFIGURE ARCHIVELOG DELETION POLICY TO NONE;

Oracle dokümantasyonuna göre (11g) yedekleme işlemine gerek kalmadan, APPLIED ON STANDBY derseniz mantıksal ya da fiziksel yedeğin archivelog'ları silinecektir.

Yukarıdaki genel bilgiler ışığında benim tercih ettiğim method ilk olarak anlattığım. "Flash recovery area" bilgisinin tanımlanmış olması önemli bir kriter zira birçok veritabanı archivelog'ların şişmesi ve eksik bakım yapıldığından çökebiliyor. Ölümcül bir hata değil, veritabanı bir süre daha varlığını devam ettirebiliyor ancak bir süre sonra ARCHn görevi ölüyor ve archive alınması işlemini veritabanı terk ediyor. Bu durumda veritabanını kapatmanız, archivelog'ların artık bulunmadığını Oracle'a öğretmeniz (eğer elle silmişseniz) ve veritabanını yeniden açmanız gerekecektir.

İyi çalışmalar,

Ogan

23 Haziran 2010 Çarşamba

Automatic Workload Repository & Create Snapshot

Merhabalar,

Oracle 10g ile birlikte aramıza katılan bir özellik olan Automatic Workload Repository (AWR), diagnostic pack bedelini ödediğiniz zaman kullanabileceğiniz bir özelliktir. AWR ve statspack farklı araçlardır ancak amaçları aynıdır ve istenildiği zaman statspack kullanımı yine söz konusudur.

Bugün bahsetmek istediğim konu bu raporları elle nasıl yaratabiliriz? Oracle aslında bizim için bunu her saat başı yapıyor ve sistemi kontrol edebilmemiz bir bize bir AWR raporu sunuyor. Bu noktada çok kısa bahsetmek istiyorum ki AWR dışında bir de ADDM denen bir kavram vardır, yani Automatic Database Diagnostic Monitor. ADDM'in amacı AWR raporlarını inceleyerek, bize taleplerde bulunması. Örneğin AWR raporunda bir SQL veritabanını çok fazla yormuş. ADDM bu SQL'i inceleyerek bize; tablo üzerinde index mi yaratmalıyız, index var ancak bitmap olmalı ya da yeni bir SQL profili geliştirmek gibi faydalı bilgiler sunar.

Gelelim konumuza. AWR raporlarını genelde enterprise manager (EM) aracılığı ile kontrol edebilirsiniz. Ancak bazı durumlarda saatlik alınan AWR raporunu okumayı değil, kendi aldığınız AWR raporunu incelemeyi tercih edebilirsiniz. Bunu tercih etmenizdeki en büyük etken ise o andaki performans problemlerini teşhis edebilmek olabilir.

Aşağıdaki komut ile manuel olarak snapshot'ımızı alabiliriz;

BEGIN
DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT ();
END;
/

Ya da

EXEC DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT ();

Bir snapshot aralığını silmek ve veritabanının bilgisinden çıkartmak isterseniz eğer;

BEGIN
DBMS_WORKLOAD_REPOSITORY.DROP_SNAPSHOT_RANGE (low_snap_id => 1, high_snap_id => 10 dbid => 1921262300);
END;
/

Peki bu noktada şöyle bir soru sorabilirsiniz; "Neden AWR raporları Oracle tarafından her saatinde başında alınmakta ve bunu değiştiremez miyiz?" Cevap, evet değiştirebilirsiniz. Hemen bir örnek göstereyim;

BEGIN
DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS( retention => 14400,
interval => 15, dbid => 1921262300);
END;
/

Retention period değeri AWR raporunun kaç gün boyunca saklanacağını, internal değeri ise kaç dakikada bir snapshot alınması gerektiğini temsil etmektedir. Daha sık ya da daha geç AWR raporu görmek isterseniz eğer yukarıdaki MODIFY_SNAPSHOT_SETTINGS sizin için biçilmiş kaftan diyebilirim.

DBA_HIST_WR_CONTROL data dictionary view'u ise size veritabanınızın AWR ayarlarını gösterecektir. MODIFY_SNAPSHOT_SETTINGS ile herhangi bir değişikliği yerine getirmeniz durumunda DBA_HIST_WR_CONTROL view'unu sorgulayarak en son halini görüntüleyebilirsiniz.

AWR snapshot'larını aldıktan sonra da awrrpt.sql isimli script'i koşmanız gerekiyor. Bu script'in amacı size bir AWR raporu hazırlamak.

awrrpt.sql scripti ise aşağıdaki dizinde bulunmaktadır;

$ORACLE_HOME/rdbms/admin/

Bu script'i çalıştırmak için;

cd $ORACLE_HOME/rdbms/admin/

sqlplus / as sysdba

SQL> @awrrpt.sql

İyi çalışmalar,

Ogan

14 Haziran 2010 Pazartesi

Dynamic Sampling - Nested Loops & CBO

Selamlar,

Dynamic Sampling, bir Oracle hint'idir ve optimizer'a yapması gerekenleri öğretmek için kullanılır. Dynamic sampling bir yön belirtici değildir, sadece optimizer'a query'i çalıştırdığınız anda geçerli olması üzerine bir istatistik toplanması gerçekleştirir. Hard parser yaptırabileceği gibi daha iyi bir plan da çıkarabilir. Dynamic sampling hint'i ile optimizer'a sadece istatistikleri güncelle diyebilirsiniz ve eğer güncelleme oluşmuşsa ve explain plan'de bir yol değişikliği olmuş ise bunu sağlayan dynamic sampling değildir, sadece optimizer daha iyi bir yol keşfetmiştir.

Dynamic Sampling ile ilgili güzel bir yazı ve cevap Thomas Kyte'dan gelmiş.

Kullanım şekli ise diğer Oracle hint'leri ile aynıdır;

/*+ dynamic_sampling(,2) */

Bir diğer hint ise Nested Loop. Bununla ilgili süper bir örnek gösterebilirim;

Aşağıdaki sorguyu inceleyelim;

SQL>
SELECT
A.DATETIME, A.IPADDRESS,
DECODE (A.IPADDRESS,'212.156.116.117', '06_ulus_t1_1', '212.156.116.118','06_ulus_t1_2', '212.156.116.119', '00_gayrettepe_t1_1', '212.156.116.120', '00_gayrettepe_t1_2','212.156.116.121' , '34_acibadem_t1_1', '212.156.116.122', '34_acibadem_t1_2', '212.156.116.123', '35_izmir_t1_1', '212.156.116.124', '35_izmir_t1_2', '212.156.116.125', '01_adana_t1_1', '212.156.116.126', '01_adana_t1_2') MACHINE,
SUBSTR(A.IDX,0,INSTR(A.IDX,'.')-1) IFINDEX, DECODE (SUBSTR(A.IDX,INSTR(A.IDX,'.')+1),'2.97.102','Af','2.98.101','Be','2.101.102','Ef','2.104.49','H1','2.104.50','H2','2.108.49','L1', '2.108.50','L2','2.110.99','Nc') FORW_CLASS,
SUBSTR(A.IDX,INSTR(A.IDX,'.')+1) IDX,
A.JNXCOSIFQTOTALREDDROPPKTS,
A.JNXCOSIFQTXEDBYTES,
CASE
WHEN (A.JNXCOSIFQTXEDBYTES - B.JNXCOSIFQTXEDBYTES) < datetime =" B.DATETIME" ipaddress =" B.IPADDRESS" idx =" B.IDX" style="font-weight: bold;">Execution Plan

----------------------------------------------------------
Plan hash value: 3451555024

--------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 700K| 62M| | 32094 (15)|
00:02:03 | | |
|* 1 | HASH JOIN | | 700K| 62M| 39M| 32094 (15)| 00:02:03 | | |
| 2 | PARTITION RANGE ALL| | 700K| 31M| | 10400 (28)| 00:00:40 | 1 | 107 |
|* 3 |
TABLE ACCESS FULL | TRAFFIC | 700K| 31M| | 10400 (28)| 00:00:40 | 1 | 107 |
| 4 | PARTITION RANGE ALL| | 14M| 628M| | 8738 (14)| 00:00:34 | 1 | 107 |
| 5 |
TABLE ACCESS FULL | TRAFFIC | 14M| 628M| | 8738 (14)| 00:00:34 | 1 | 107 |
--------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - access("A"."DATETIME"=INTERNAL_FUNCTION("B"."DATETIME")+.01041666666666666666666666666666
66666667 AND "A"."IPADDRESS"="B"."IPADDRESS" AND "A"."IDX"="B"."IDX")
3 - filter(SUBSTR("A"."IDX",0,INSTR("A"."IDX",'.')-1) IS NOT NULL)

İki defa full table scna yapıldı, çok yavaş.

Bir de dynamic sampling hint'ini eklediğimiz zaman neler oluyor, ona bakalım (sorgu aynı, sadece hint var ve her iki ana tablo için);

Execution Plan
----------------------------------------------------------
Plan hash value: 3451555024

--------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14M| 1256M| | 43788 (13)|
00:02:48 | | |
|* 1 | HASH JOIN | | 14M| 1256M| 788M| 43788 (13)| 00:02:48 | | |
| 2 | PARTITION RANGE ALL| | 14M| 628M| | 10532 (29)| 00:00:41 | 1 | 107 |
|* 3 | TABLE ACCESS FULL | TRAFFIC | 14M| 628M| | 10532 (29)| 00:00:41 | 1 | 107 |
| 4 | PARTITION RANGE ALL| | 14M| 628M| | 8738 (14)| 00:00:34 | 1 | 107 |
| 5 | TABLE ACCESS FULL | TRAFFIC | 14M| 628M| | 8738 (14)| 00:00:34 | 1 | 107 |
--------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - access("A"."DATETIME"=INTERNAL_FUNCTION("B"."DATETIME")+.01041666666666666666666666666666
66666667 AND "A"."IPADDRESS"="B"."IPADDRESS" AND "A"."IDX"="B"."IDX")
3 - filter(SUBSTR("A"."IDX",0,INSTR("A"."IDX",'.')-1) IS NOT NULL)

Note
-----
- dynamic sampling used for this statement

Dynamic sampling ile hash join maliyetimiz arttı. Bu durumda daha farklı bir yol izlemeliyiz. Hash Join yerine Nested Loop ile bu iki ana tabloyu daha hızlı çekebiliriz. Bu iki tabloyu bir nested loop ile çok daha hızlı görüntüleyebiliriz çünkü yığın olarak kümelediğimiz zaman full table scan yapmakta;

Bunun için sorguyu aşağıdaki gibi değiştiriyorum;

SQL>

SELECT
/*+ USE_NL(A) USE_NL(B)*/
A.DATETIME, A.IPADDRESS,
DECODE (A.IPADDRESS,'212.156.116.117', '06_ulus_t1_1', '212.156.116.118','06_ulus_t1_2', '212.156.116.119', '00_gayrettepe_t1_1', '212.156.116.120', '00_gayrettepe_t1_2','212.156.116.121' , '34_acibadem_t1_1', '212.156.116.122', '34_acibadem_t1_2', '212.156.116.123', '35_izmir_t1_1', '212.156.116.124', '35_izmir_t1_2', '212.156.116.125', '01_adana_t1_1', '212.156.116.126', '01_adana_t1_2') MACHINE,
SUBSTR(A.IDX,0,INSTR(A.IDX,'.')-1) IFINDEX, DECODE (SUBSTR(A.IDX,INSTR(A.IDX,'.')+1),'2.97.102','Af','2.98.101','Be','2.101.102','Ef','2.104.49','H1','2.104.50','H2','2.108.49','L1', '2.108.50','L2','2.110.99','Nc') FORW_CLASS,
SUBSTR(A.IDX,INSTR(A.IDX,'.')+1) IDX,
A.JNXCOSIFQTOTALREDDROPPKTS,
A.JNXCOSIFQTXEDBYTES,
CASE
WHEN (A.JNXCOSIFQTXEDBYTES - B.JNXCOSIFQTXEDBYTES) < datetime =" B.DATETIME" ipaddress =" B.IPADDRESS" idx =" B.IDX" style="font-weight: bold;">45:05:57 | | |
| 1 |
TABLE ACCESS BY LOCAL INDEX ROWID| TRAFFIC | 1 | 47 | 3 (0)| 00:00:01 | | |
| 2 | NESTED LOOPS | | 700K| 62M| 42M (2)| 45:05:57 | | |
| 3 | PARTITION RANGE ALL | | 14M| 628M| 8738 (14)| 00:00:34 | 1 | 107 |
| 4 | TABLE ACCESS FULL | TRAFFIC | 14M| 628M| 8738 (14)| 00:00:34 | 1 | 107 |
| 5 | PARTITION RANGE ITERATOR | | 1 | | 2 (0)| 00:00:01 | KEY | KEY |
|* 6 |
INDEX RANGE SCAN | TRAFFIC_PK | 1 | | 2 (0)| 00:00:01 | KEY | KEY |
----------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

6 - access("A"."DATETIME"=INTERNAL_FUNCTION("B"."DATETIME")+.0104166666666666666666666666666666666667
AND "A"."IPADDRESS"="B"."IPADDRESS" AND "A"."IDX"="B"."IDX")
filter(SUBSTR("A"."IDX",0,INSTR("A"."IDX",'.')-1) IS NOT NULL AND "A"."IDX"="B"."IDX")

Maliyetin inanılmaz arttığını göreceksiniz. Yalnız Oracle'da maliyetin yüksek olması sorgunun da yavaş olacağı anlamına asla ve asla
GELMEZ! USE_NL hint'ine sahip olmayan sorgunun cevabı 1 dakika 15 saniyede dönerken, USE_NL hint'ine sahip sorgunun cevabı 240 milisaniye gibi çok farklı bir sonuçla geliyor. Tek bir full scan yapıldı, ikinciye gerek kalmadan bütün veriler rowid'lerine erişilerek (index ile) elde edildi. Bunun dışında CPU'da geçirilecek sürede de inanılmaz bir azalma görülüyor.

Oracle dokümantasyonlarına göre CBO (cost based optimizer)
her zaman, her zaman maliyeti düşük olan sorgu planını seçer ve uygular. Bunu değiştirmenin tek yolu optimizer hint'leridir. Optimizer'ın her zaman en optimum sorguyu getireceği asla garanti edilmez, edilemez. Çünkü optimizer'ın etkilendiği birçok durum vardır. Örneğin;

1) CBO tablo ve indeks üzerindeki istatistiklere göre bir sorgu planı oluşturur. İstatistikler eksik ya da toplanmamış ise farklı ve daha kötü planlar ortaya çıkabilir.
2) CBO bir sütunun içeriğine bakarakta plan oluşturabilir. Sütunun tipi varchar2 ise ve içerisinde sadece rakamsal değerler varsa bu optimizer'ı yanıltabilir!
3) CBO hint'leri kullanmak yerine ve duruma göre oldukça olumlu ve yüz güldüren sonuçlar elde etmenizi sağlar.
4) CBO sorgunun mantığının hatalı olduğunu, sorguda eksik eşitlik, hatalı bağlantılar ya da unutulmuş indeksler olduğunu anlamaz ve size öneride bulunmaz. Bunu yapan başka bir araç vardır (Detaylı bilgi için AWR). Bu sebepten dolayı önce SQL tuning sonra Oracle hint.

İyi çalışmalar,

Ogan

ORA-01547 ORA-01194 ORA-01110

Merhaba,

Başlıktaki hataların ne ifade ettiğini belirtmem gerekiyor;

ORA-01547: warning: RECOVER succeeded but OPEN RESETLOGS would get error below
ORA-01194: file 1 needs more recovery to be consistent
ORA-01110: data file 1: 'SYSTEM01.dbf'

Bu hatayı ne zaman almış olabilirsiniz?

SQL> recover database until cancel;

ORA-00279: change 22188599501 generated at 06/14/2010 01:01:50 needed for
thread 1
ORA-00289: suggestion : /backup/1_15651_679577014.dbf
ORA-00280: change 22188599501 for thread 1 is in sequence #15651

Burada önemli olan Oracle hata kodu "ORA-01194". Oracle veritabanının bu hatayı vermesinin nedeni system01.dbf datafile'ının control dosyası ile tutarlı olmaması ve daha fazla archivelog'a ihtiyacı olması. Archivelog'ları üzerine restore ederek bu hatadan kurtulup, veritabanınızı "open resetlogs" komutunu göndererek açabilirsiniz.

Öncelikle bu komutu göndermeye çalışalım;

SQL> alter database open resetlogs;
alter database open resetlogs
*
ERROR at line 1:
ORA-01194: file 1 needs more recovery to be consistent
ORA-01110: data file 1: 'SYSTEM01.dbf'

Şimdi recovery manager bağlantısını kuralım;

$ rman target /

Recovery Manager: Release 10.2.0.4.0 - Production on Mon Jun 14 10:50:05 2010

Copyright (c) 1982, 2007, Oracle. All rights reserved.

connected to target database: OPTTEST (DBID=750193206, not open)

Bu noktada "restore" işlemini yapmanıza gerek yok. Recover database demek yeterli zira sadece archivelog'u yama yapacağız.

RMAN> shutdown immediate;

RMAN> startup mount;

Oracle instance started
database mounted

Total System Global Area 2147483648 bytes

Fixed Size 2057568 bytes
Variable Size 738200224 bytes
Database Buffers 1392508928 bytes
Redo Buffers 14716928 bytes

RMAN> recover database;

Starting recover at 14-JUN-10
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=1487 devtype=DISK

starting media recovery

archive log thread 1 sequence 15651 is already on disk as file redo7.rdo
archive log filename=redo7.rdo thread=1 sequence=15651
media recovery complete, elapsed time: 00:00:30
Finished recover at 14-JUN-10

RMAN> alter database open resetlogs;

database opened

Recovery manager'ın gördüğü eksiklik redo7.rdo archivelog dosyasında bulundu ve gerekli olan datafile için bu güncelleştirme yapıldı. Bu bir çeşit incomplete recovery olduğu için resetlogs komutuyla veritabanını başarılı bir şekilde açabildik.

Yukarıdaki örnekte herhangi bir yedekten dönmedik ya da yararlanmadık. Kullandığımız tek şey bir adet archivelog'du ve bunun kararını da RMAN'e bıraktık.

İyi çalışmalar,

Ogan

2 Haziran 2010 Çarşamba

"Ask Tom Live" Semineri

Merhaba,

17-18 Mayıs tarihlerinde İstanbul'a Thomas Kyte geldi ve iki günlük bir seminer düzenledi. Seminer konuları arasında materialized view'lar, depolama teknikleri, binding (bind variables) gibi konular vardı. Gerçekten çok başarılı bir seminer oldu ve bana oldukça iyi bir vizyon kattı. Zaten bu seminer'lerin amacı genelde teknik bilgi yığını sağlamak değil, konuların ne olduğunu, püf noktalarının nasıl öğrenilmesi gerektiğini anlatmak. Bunu da çok çok iyi bir biçimde başardı.


Günün anısı bir fotoğraf çekilmişti ancak bulanık çıkmış. Onu da ekliyorum.
İyi çalışmalar,
Ogan
Takip et: @oganozdogan