29 Ağustos 2010 Pazar

Birden fazla MRP?

Merhaba,

Geçtiğimiz günlerde şu şekilde bir soru ile karşılaşmıştım;

"Data Guard replikasyonu ve senkronizasyonu için birden fazla MRP görevi çalıştırılabilir mi?"

Kişisel yorumum hayır, çalıştırılamaz. Açıkçası ben hiç MRP1, MRP2 gibi görevlere rastlamadım. Bir veritabanını açarken, media recovery sırasında parallel işlem yaptırabilirsiniz;

SQL> RECOVER DATABASE PARALLEL X;

Parallel işlemler devreye girerek, media recovery yapacaktır ancak bu işlemler sırasında göreceğiniz Oracle görevi muhtemelen P001 gibi bir isimle yer alacaktır, MRP1.. değil.

Hatta bu konunun tartışıldığı bir forum bulunmakta ve ben de birkaç cümle yazmıştım. Umarım okuyanlar için faydalı olur;

ora_p000_process

Recovery_parallelism parametresi ile MRP arasında hiçbir ilişki bulunmuyor, MRP görevlerinin sayısını da arttırmıyor. P ile başlayan görevler parallel işlem yapmakta olan görevlerdir. data guard replikasyonu için kullanılan görev MRP'dir, P ile başlayan parallel görevler değildir.

Media Recovery Process (MRP) bir komut ile devreye alınıp, yine bir komut ile devreden çıkarılabilir;

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL; --> MRP görevi sonlandırılır ve media recovery devam etmez.

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE [USING CURRENT LOGFILE] DISCONNECT FROM SESSION; --> Eğer bir standby redo log grubunuz varsa using current logfile diyerek, MRP görevini bu komut ile yeniden başlatabilirsiniz.

Dip not: Fiziksel beklemede bulunan bir veritabanını "read only", yani sadece okuma modunda açabilmek için MRP görevini öncelikle sonlandırmanız gerekmektedir. 11g'de bile bunu yapmadan read only olarak veritabanını açamazsınız, sorgu koşamazsınız ve raporlama yapamazsınız.

İyi geceler.

Ogan

28 Ağustos 2010 Cumartesi

Redolog Yaratmak, Taşımak, Silmek, Boyutlandırmak

Selamlar,

Bu yazımda veritabanında nasıl redolog boyutlandırabiliriz, taşıyabiliriz, silebiliriz ve nasıl yeniden yaratabiliriz, bu konuyu ele almak istiyorum.

Öncelikle neden redolog'larımıza bu işkenceyi yapmak isteyelim? Cevabı o kadar basit ki, "performans". Evet, performanstır bu sorunun cevabı zira "private strand flush not complete" veya aynı mantıkla "Checkpoint not complete" hatalarını alert.log dosyasında gördüğünüz zaman, "Configuration, Commit ya da Concurrency" başlığı altında bekleme olaylarını göremeye ve veritabanı çok yavaşladı, ne yapıyorsun gibi yorumları da almaya hazır olun.

Bu durumda yukarıda bahsettiğim hatalarla başlayalım. Bu hatalar nedir ve alındığı zaman nelere sebep olmaktadır?

1) Veritabanında "wait event" (bekleme olayı) yaratarak, genel veritabanı performansını negatif yönde etkiLEYEBİLİR. Kalın olarak belirtmemin sebebi ise kimi durumlarda da göz ardı edilebilir. Bu durumlar, veritabanında "commit ya da rollback" işlemlerinin yoğun olmadığı ancak logfile'ların çok hızlı değiştirildiği durumlar.
2) Genel veritabanı performansını ciddi ölçüde etkileyerek, diğer uygulamaların, sorguların ve işlemlerin de çalışmasını olumsuz yönde etkiLEYEBİLİR.

Örnek;

Günde 200 - 250 gigabyte archivelog'un oluştuğu bir veritabanınız var ve redolog boyutlandırmasını çok büyük ve grup adedini de az yaptınız diyelim. Başınıza gelecek felaketleri anlamak için yukarıda yazdıklarımı yeniden okuyunuz. Asıl sebep ne olabilir?

Bu durumun gerçek sebebi ise LGWR işleminin, henüz aktif olarak kullanılmakta olan online redolog'ları yeniden kullanmak istemesi ve DBWR'ın buna "engel" olması. Bildiğiniz gibi checkpoint dediğimiz bir yapı bulunmakta ve redolog dosyalarındaki verilerin, fiziksel datafile'lara yazılmasını sağlamakta. Ancak o kadar çok commit işlemi yapılıyor ve o kadar çok redo üretiliyor ki, DBWR, LGWR'ın hızına bir türlü yetişemiyor. Bu durumlarda da "Configuration" veya "Commit" hatta "Concurrency" bekleme olayları başlıkları altında ciddi zamanlar kaybedersiniz.

Peki gelelim redolog'ları nasıl değiştirebileceğimize. Aslında bu konu ile yukarıda yazdığım hataların konusu biraz birbiri ile alakalı zira bir redolog'u öncelikle veritabanından silebilmeniz için;

1) İlgili redolog'un statüsünün "INACTIVE" olması gerekiyor.
2) İlgili redolog'un mutlaka archivelog'unun oluşması gerekiyor.

Unutmadan, redolog'ları yeniden yaratmak için ya da boyutlandırmak için veritabanını kapatmanıza gerek yoktur. Bazı veritabanı yöneticileri redolog'ları taşımak için veritabanını kapatıyorlar ama aslında buna hiç, hiç gerek yok.

Adımları sırası ile yazalım;

1) V$LOG fixed görüntüsünü sorgulayalım. STATUS sütunu "INACTIVE" ve "ARCHIVED" sütunu "YES" olan bir redolog görüyorsanız eğer hemen düşürebilirsiniz. YALNIZ eğer redolog gruplarınızın adedi iki ise, drop ederken hata alırsınız çünkü bir veritabanında en az 2 adet online redolog grup bulunması şart.

a) Eğer iki adet redolog grup bulunuyorsa istenilen boyuttaki yeni log grubunu ekleyelim;

SQL> ALTER DATABASE ADD LOGFILE GROUP 3 ('/db/oracle/redo05.log','/db/oracle/redo06.log') SIZE 500M [REUSE];

Yukarıdaki komut, 3ncü bir redolog grubu yaratacak ve redo05 ve redo06 isimlerinde, toplam 500 megabyte boyutunda olacaktır. redo05 ve redo06 redolog'ları önceden yaratılmış ve verdiğimiz lokasyonda bulunmakta ise REUSE komutunu da sorgunun sonuna eklememiz gerekiyor.

b) Eğer iki adet redolog grup'tan fazlası bulunuyorsa;

SQL> ALTER DATABASE ADD LOGFILE GROUP 7 ('/db/oracle/redo10.log','/db/oracle/redo11.log') SIZE 500M [REUSE];

Eklerken yine bir problem ile karşılaşmadık. Ancak şimdi ise düşürmek isteyelim;

c) Veritabanından bir redolog grubu silmek istersek;

SQL> ALTER DATABASE DROP LOGFILE GROUP 6;

Alacağınız muhtemel sonuçlar ise;

1) Düşürmek istediğiniz redolog grubunun statüsü ACTIVE ise hata alırsınız (V$LOG --> STATUS).
2) Düşürmek istediğiniz redolog grubunun archivelog'u henüz oluşturulmamış ise yine hata alırsınız (V$LOG --> ARCHIVED).
3) Düşürmek istediğiniz redolog grubunun statüsü INACTIVE ve archivelog'u oluşturulmuş ise gönderdiğiniz drop logfile komutu başarılı olacaktır.

Bu redolog'ların yeniden yaratılması işini bir temp algoritması gibi de düşünebilirsiniz. Eğer 2 tane redolog grubunuz varsa ve bu redolog gruplarının sadece boyutunu arttırmak istiyorsanız eğer ve diyorsanız ki redo isimleri de aynı kalsın, sıradan bir redolog grubu yaratarak işe başlayabilirsiniz. Ardından bu geçici süre ile yarattığınız üçüncü redolog grubuna gelene kadar;

SQL> ALTER SYSTEM SWITCH LOGFILE;

komutunu gönderirsiniz. V$LOG görüntüsü size, üçüncü redolog grubunun aktif olduğunu söylediği zamansa birinci redolog grubunu düşürebilirsiniz FAKAT yine bahsettiğim gibi bu redolog grubu henüz ACTIVE ve archivelog'u üretilmemiş ise göndereceğiniz komut şudur;

SQL> ALTER SYSTEM CHECKPOINT;

Bu noktada hemen belirtmem gerekiyor. ALTER SYSTEM SWITCH LOGFILE komutu, bir sonraki redolog grubuna geçmemizi sağlar. Sonuçları ne olursa olsun veritabanı, yeni bir redolog grubunu kullanmaya zorlanmaktadır. ALTER SYSTEM CHECKPOINT komutu ise veritabanını bir checkpoint yapmaya zorlamaktadır ve commit edilmiş, redolog'larda bulunan bütün transaction'lar fiziksel datafile'lara yazılmak için ayrıca zorlanmaktadır. Bu komutun GLOBAL ve LOCAL ekleri de bulunmakta ancak bu ekler sadece real application cluster node'ları için geçerlidir, tek node'lu çalışan bir veritabanın da gözardı edilecektir ama komutunuz yine de çalışacak ve checkpoint gönderilecektir.

Yukarıdaki ilk komutu gönderdik ve geçici olarak yarattığımız redolog grubunu CURRENT olarak belirledik (V$LOG --> STATUS). Current bilgisini gördüğünüz zaman o redolog kullanılmata demektir. LGWR şu anda aktif olarak bu redolog'lara, commit edilen transaction'ların verilerini yazmaktadır. İkinci komutu göndermemizin nedeni ise hala ACTIVE olarak gözüken redolog gruplarının, checkpoint'i beklemeden checkpoint'e zorlanarak, statüsünü INACTIVE'e çekmektir. ARCH görevi ise bu esnada, ilgili redolog'un bir archivelog'unu üretmekle meşguldür. Archivelog'u üretilen ve statüsü INACTIVE'e geçen birinci redolog grubumuzu düşürelim;

SQL> ALTER DATABASE DROP LOGFILE GROUP 1;

Şimdi de yeniden yaratalım. Ancak bu sefer reuse komutunu kullanmazsak yine bir ORA hatası almaya hazır olmamız gerekiyor çünkü ilgili redolog'ları henüz fiziksel olarak silmedik.

SQL> ALTER DATABASE ADD LOGFILE GROUP 1 ('/db/oracle/redo01.log','/db/oracle/redo02.log') SIZE 750M REUSE;

İkinci redolog grubunu da değiştirmek için yine bu yolu izleyebilirsiniz.

Şimdiye kadar bir redolog grubu nasıl boyutlandırılır, nasıl silinebilir bu konuları inceledik. Redolog'u taşımak içinse yapmanız gereken tek şey, yeniden yaratırken lokasyonunu değiştirmek!

Yukarıdaki aşamalarda alınabilecek hata kodlarını merak eden okuyucular olabilir. Alabileceğiniz hata kodlarından hatırladığım, ORA-00350 hatası bulunmakta. Diğeri ise ORA-01624. Alert.log dosyanızda ise şu şekilde bir satır yazacaktır;

ORA-1624 signalled during: ALTER DATABASE (Statüsü ACTIVE olan redolog grubunu düşürmek isterseniz alacağınız hata).
ORA-350 signalled during: ALTER DATABASE (Archivelog'u henüz oluşmamış olan redolog grubunu düşürmek isterseniz alacağınız hata).

İyi çalışmalar dilerim.

Ogan

23 Ağustos 2010 Pazartesi

2PC Transaction

Selamlar,

Birkaç yazı öncesinde şüphede kalan adı altında çevirdiğim "in-doubt" transaction'lar ile ilgili biraz daha detaylı bilgi vermek istiyorum.

Neden şüpheli olacağını sorabilirsiniz. Bu tarz transaction'lar genelde bir db link ile başka bir veritabanına bağlanırlar ve o veritabanında güncelleme yaparak, commit işlemi de gerçekleştirebilirler. Bu kimi zaman o kadar yoğun olur ki, arada sırada hatalara ve beklemelere bile yol açabilir.

Aşağıdaki bu tarz transaction'lar ile ilgili bir örnek vermek istiyorum. Bu örnek bir veritabanının alert.log dosyasından alınmıştır;

Mon Aug 23 16:28:46 2010
Error 2068 trapped in 2PC on transaction 69.95.1106249. Cleaning up.
Error stack returned to user:
ORA-02068: following severe error from TABLE_NAME
ORA-03135: connection lost contact

"on transaction" sonrasında verdiği değer, ilgili transaction'ın tanımlanmasında kullanılabilir. Başlangıçtaki 2068 ise bir çeşit ORA hatasıdır. ORA hatasının ve ona eşlik eden hata ya da hataların tanımlarını da bir sonraki satırlarda görmektesiniz.

Benim genelde gördüğüm hata kodu 2068 ancak açıkçası 2068 dışında da bir hataya rastlamadım :) 3113 hatası alan görmüştüm ama bu hatayı ben almadım. 3113 aslında biraz daha tehlikeli bir hata zira "end-of file on communication channel" yani bağlantı kanalında sonlanma hatası genel bir hatadır ve teşhis etmesi de zor olabilir.

Peki bu hata neden oluşmakta? En büyük sebeplerinden birisi, db link ile bir transaction açılmış iken bu transaction'ın kötü bir şekilde sonlandırılması ya da rollback yapmaya zorlanması.

In-doubt transaction eğer hata geçerli ise kontrolünü yapabileceğiniz bir data dictionary görüntüsü mevcuttur;

dba_2pc_pending

Bu görüntüde transaction ile ilgili bilgileri görebilirsiniz. Eğer "pending" yani bir şekilde bekleyen ve takılmış bir transaction bulunuyorsa, daha önce yazdığım COMMIT FORCE başlığı altında neler yapılması gerektiğini görebilirsiniz. Aynı şekilde dilerseniz ROLLBACK FORCE komutunu da kullabilirsiniz.

Bir de hemen dip not eklemem gerekiyor ki, bir transaction'a isim verebilirsiniz ve bu şekilde uzun süren ve bir db link kullanmak zorunda olan transaction'ların takibini de kolaylayabilirsiniz.

Son olarak bu yazıda ekleyebileceğim bir bilgi ise unutmayınız ki "database link" ismini verdiğimiz hızlı geçiş bağlantıları, sonradan açılan bir sqlplus ekranından farksızdır. Database link'i yarattığınız kullanıcı ile bağlanır, onun hakları ile sorgulama yapar ve veri girişi sağlarsınız. SYS ile kendi veritabanınızda bağlı olmanızın hiçbir anlam ifade etmediğini, size tanımlanmış olan database link kullanıcısının haklarına sahip olarak sorgulama yaptığınızı unutmayınız.

İyi çalışmalar.

Ogan


20 Ağustos 2010 Cuma

TROUG

Merhabalar,

Başlarken hemen ilgili blog'u göstermek istiyorum;

http://tonguc.wordpress.com/2010/08/20/troug-hayal-mi-yoksa-gerceklesmesi-icin-yeterli-olgunluk-duzeyine-ulastik-mi/

Konuyla ilgili birkaç yorumda bulunmak istiyorum. Öncelikle Tonguç Yılmaz'a sonsuz teşekkürlerimi iletmek istiyorum. Türkiye'deki Oracle topluluğunun genişlemesinde ve paylaşımların artmasında ciddi katkıları olmuş ve hala olan bir gönüllüdür.

Açıkça belirtmem gerekiyor ki paylaşımın önemi ile tanışmam Tonguç Yılmaz sayesinde olmuştur.

Bilgi ve deneyim kazandıkça, bunları paylaşıyor ve birilerinin okuduğunu ve yararlandığını bilmek gerçekten çok güzel bir his. Bunun yanında Türkçe olarak yazdığım için insanların daha rahat okuduklarını düşünüyorum zira aramızda İngilizcesi çok iyi seviyede olmayan hatta hiç olmayan ama Oracle ile arasında bir bağ oluşturmak insanlar da var. Kişisel çabalarımın tamamını Türkçe olarak burada sonuna kadar paylaşmaya ve Türk Oracle topluluğunun daha da iyi seviyelere ulaşmasına destek olacağım.

Benden daha tecrübeli ve bilgili insanlardan ricam paylaşmaları. İnanın bana google'da bir başlık arttığınız zaman sizin yazdığınız yazının karşınıza çıkması kadar güzel bir şey olamaz. Bu demek oluyor ki birileri gerçekten bu konuyu aratıyor ve sizin yazını okuyarak fayda sağlayabiliyor. Gerçekten oldukça önemli bir katkı olduğunu düşünüyorum.

Ben TROUG'un bir hayal olmadığını ancak çok fazla çalışmamız gerektiğini düşünüyorum. Birlikçe çalışırsak eğer olmayacak, oluşturulamayacak bir girişim değildir. Birlikte çalışıldığı süre boyunca insanlar daha da tecrübe kazanacaklar, teknik yetkinliğimiz ve deneyimlerimiz artacak ve hatta iş imkanları konusunda bile önemli gelişmeler sağlanabilecektir.

Oluşum hakkında fikir elde etmek için;

http://www.ukoug.org/about/

Herkesin bu konuya özen göstermesini diliyorum ve Türk Oracle kullanıcılarının ciddi katkılarının olacağını düşünüyorum. Katkıda bulunacak insanlara şimdiden gönülden teşekkür ederim. İnşallah herşeyi çok çok daha iyi boyutlara taşıyacağız ancak biraz daha fazla çalışmamız ve daha ileriyi hedeflememiz gerekiyor.

İyi geceler.

Ogan





LOG FILE SYNC

Selamlar,

Birçoğunuza "log file sync" yazısı yabancı gelmeyecektir. Bu bir çeşit veritabanı bekleme olayıdır ve veritabanı üzerinde koşmakta olan bağlantıların takılabileceği bir olaydır. Bu beklemenin sebeplerini ve neler yapılması gerektiğini aşağıda belirteceğim yalnız şunu da eklemem gerekiyor ki; AWR raporundaki "Top 5 Wait Events" alanında bu olayı görüyorsanız eğer aksiyon almanız gerekebilir diyebilirim.

Bu kullanıcı commit ya da rollback komutunu gönderdiği zaman bu bağlantının redo bilgisi LGWR tarafından redo log dosyasına yazılır. Bu durumda veritabanı commit ya da rollback beklemeleri ile bu redo log'a yazma işlemini tamamlar.

Eğer log file sync bekleme olayı önemli ölçüde beklemeyi sistem üzerinde yaratmış ise ortalama beklemeyi gözlemlemek gerekmektedir. Eğer ortalama bekleme düşük ancak bekleyen bağlantı adedi fazla ise bu durumda uygulamanın her insert komutu ardından commit ettiğini söyleyebiliriz. Uygulama mantığı böyle bir yapı gerekiyor olabilir ancak transaction'ın atomik bir yapısı olduğunu ve bu yapı içerisindeki commit ya da rollback işlemlerinin ciddi anlamda önemli olduğunu da eklemek zorundayım. Bir bankacılık sisteminde paranın bir hesaptan diğerine aktarılırken kaybolması gibi birşey söz konusu olamaz ve buradaki en önemli ve sihirli kelime "commit" olacaktır. Sonuç olarak uygulama da bu bekleme adetlerini, her satırdan sonra commit etmek yerine 50-100 satır sonra commit ederekte çözebilir. Bu tamamen uygulamanın nasıl geliştirildiğine bağlıdır aslında.

Bu gözlemlemenin sonucunda eğer bekleme ciddi boyutlarda ise "log writer" bekleme olaylarını ayrı ayrı incelemek gerekmektedir. Bunun yanında, yukarıda özetlediğim durumun aksine, ortalama bekleme süresi yüksek ve I/O da yüksek ise aşağıdaki aşamaları sınamak gerekebilir;

1) Redo log'ların olduğu disk'ler üzerindeki aktiviteleri azaltın ya da redo log için ayrı bir disk kullanın.
2) Redo log lokasyonları için kullanacağınız başka disk'ler archiver'ın log writer üzerindeki etkisini minimize edecektir.
3) Redo log'ları daha hızlı disk'lere taşıyabilirsiniz. Örneğin RAID 5 disk'ten RAID 1 disk'e taşımak gibi.
4) "Raw device" kullanmayı, yazma işlemini hızlandırmak için düşünebilirsiniz.
5) Uygulamanın cinsine ve yapısına göre işlenen COMMIT'leri her N adet satır için yapmayı tercih edebilirsiniz. Her satır girişinden sonra yapılan commit, daha fazla log file sync beklemelerine sebep olabilirken, commit'leri biraz azaltmak daha az log file sync beklemelerine sebep olabilir.

İyi çalışmalar.

Ogan

18 Ağustos 2010 Çarşamba

SQL Profilleri / Otomatik SQL Tuning

Merhaba,

Oracle veritabanındaki SQL profilleri otomatik SQL tuning işlemi ile ayarlanmakta iken bu profilleri DBMS_SQLTUNE ile yönetebiliriz. DBMS_SQLTUNE Oracle içine gömülü bir pakettir.

SQL tuning advisor bize bir SQL profili kullanmamızı istediği, daha doğrusu tavsiye ettiği zaman bunu kabul edebiliriz. Bu advisor hem index hem de sql profil kullanımını bir arada tavsiye edebilir ve bu durumda ikisinin birden kullanılması iyidir. Unutmadan, SQL tuning advisor'ın tavsiye ettiği verileri "Enterprise Manager" konsolundan inceleyebilirsiniz.

DECLARE my_sqlprofile_name VARCHAR2(30);
BEGIN my_sqlprofile_name := DBMS_SQLTUNE.ACCEPT_SQL_PROFILE (task_name => 'my_sql_tuning_task', name => 'my_sql_profile', force_match => TRUE);
END;

Buradaki "my_sql_profile" kabul etmek istediğimiz SQL profilinin adıdır. my_sql_tuning_task ise SQL tuning görevinin adıdır.

Genel olarak kabul edilmiş bir SQL profili SQL cümlesi ile SQL imzası aracılığı ile birleştirilir. Bu birleştirme işleminde hash (yığın) fonksiyonu kullanılır. Bu hash fonksiyonu SQL cümlesinin tamamını büyük harfe çevirir ve bütün boşlukları silerek, bir imza oluşturulmadan önce tasarlar. Ortak olarak kabul edilen bütün SQL cümleleri için bu SQL profili kullanılabilir.

force_match özelliğini "true" olarak ayarladığımız zaman, SQL cümlesi içerisindeki bütün literal ve bind değerleri normalize edilir. Bu durumda SQL profili yaratılmış olan SQL cümlemiz içerisinde yer alan bind değerleri de gözardı edilmeden, yarattığımız SQL profilini, ilgili SQL cümleciğimiz içim kullanabiliriz. force_match false olarak bırakılırsa ki bu varsayılanıdır ve aksini söylemedikçe true olarak değer kazanmaz, bu durumda literal değerler normalize edilemez.

SQL profilleri ile ilgili değerleri öğrenmek ve profilleri takip etmek için DBA_SQL_PROFILES data dictionary görüntüsünü incelemeniz gerekmektedir.

ALTER komutu ile daha önceden yaratılmış bir SQL profilini değiştirebiliriz;

BEGIN
DBMS_SQLTUNE.ALTER_SQL_PROFILE(name => 'my_sql_profile', attribute_name => 'STATUS', value => 'DISABLED');
END;
/

DROP komutu ile de yarattığımız bir SQL profilini düşürebiliriz;

BEGIN
DBMS_SQLTUNE.DROP_SQL_PROFILE(name => 'my_sql_profile');
END;
/

Normal şartlar altında bir SQL profili yaratılmasının gerektiğini düşünmüyorum ancak 10g ve sonrası için satın alınan ve diagnostic pack ile gelen AWR'ın sunduğu ADDM bilgileri içerisinde bu talepleri de bulmanız mümkün. Ben genelde ADDM tavsiye ettiği zaman bir SQL profili yaratıyorum ve bununla birlikte indeks önerisi gelirse de dikkate alıyorum. Bunun yanında SQL Tuning Advisor otomatik olarak AWR yüksek yüklenen SQL cümleleri üzerinde çalıştırılmaktadır. Bir anlamda kombinasyonu sağlanarak ADDM üzerinde de SQL profilleri ve indekslemeler tavsiye edilmektedir.

SQL Tuning Advisor'ın çalıştırılması ise kapatılabilir veya yeniden açılabilir;

BEGIN
DBMS_AUTO_TASK_ADMIN.ENABLE(
client_name => 'sql tuning advisor',
operation => NULL,
window_name => NULL);
END;
/


DBMS_AUTO_TASK_ADMIN package:BEGIN
DBMS_AUTO_TASK_ADMIN.DISABLE(
client_name => 'sql tuning advisor',
operation => NULL,
window_name => NULL);
END;
/

11g veritabanı ile birlikte SQL Tuning Advisor otomatik olarak, belirli zamanlarda çalıştırılmaktadır. Bu çalıştırmalar zamanında yüksek yüklü SQL cümleleri üzerinde, nasıl bir tuning yapılacağı tavsiyesi hazırlanmaktadır. Daha önce de bahsettiğim gibi, en iyi gözlemleme ve kontrol etme yöntemi enterprise manager'ı kullanmaktır.

İyi çalışmalar.

Ogan

17 Ağustos 2010 Salı

Data Guard Datafile Taşıma İşlemi

Selamlar,

OTN forumlarını incelerden değişik bir soru ile karşılaştım. Soru şu;

"
Data Guard konfigüre edilmiş bir ortamda ana veritabanında bir datafile'ın yerini değiştirmek ya da yeni isim vermek istersem ne yapmam gerekiyor?
"

Aşağıdaki komutları ve yolu takip ederek hem ana hem de fiziksel yedek veritabanındaki datafile'ı taşıyabilirsiniz;


Bir ya da birden çok datafile'ı ana veritabanında isimlerini
değiştirdiğimiz zaman bu değişiklik, yedek veritabanında işleme
konulmaz.
Bu sebepten dolayı eğer bir datafile'ı yeniden adlandırmak
istiyorsanız aynı modifikasyonları yedek veritabanında da
yapmanız gerekmektedir, STANDBY_FILE_MANAGEMENT parametresi
"AUTO" olarak ayarlanmış olsa bile.
1.

Ana veritabanında ilgili tablespace'i offline
konumuna alıyoruz;

SQL> ALTER TABLESPACE tbs_4 OFFLINE;

2.

SQL prompt'undan çıkarak aşağıdaki unix komutunu
gönderiyoruz;

% mv /disk1/oracle/oradata/payroll/tbs_4.dbf
/disk1/oracle/oradata/payroll/tbs_x.dbf

3.

Datafile'ın adını değiştiriyoruz ve tablespace'i
online konumuna geri alıyoruz.
SQL> ALTER TABLESPACE tbs_4 RENAME DATAFILE

'/disk1/oracle/oradata/payroll/tbs_4.dbf'

TO
'/disk1/oracle/oradata/payroll/tbs_x.dbf';

SQL> ALTER TABLESPACE tbs_4 ONLINE;

4.

Yedek veritabanına bağlanın ve v$archived_log görüntüsünü
sorgulayarak, bütün archivelog'ların işlendiğini görüntüleyin
ve redo işlemesini durdurun.

SQL> SELECT SEQUENCE#,APPLIED
FROM V$ARCHIVED_LOG
ORDER BY SEQUENCE#;
SEQUENCE# APP
--------- ---
8 YES
9 YES
10 YES
11 YES
4 rows selected.

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

5.

Yedek veritabanını kapatın;

SQL> SHUTDOWN;

6.

Datafile'ın adını değiştiriyoruz ve unix komutu ileyapabiliriz

% mv /disk1/oracle/oradata/payroll/tbs_4.dbf
/disk1/oracle/oradata/payroll/tbs_x.dbf

7.

Fiziksel yedek veritabanını mount konumuna geri alıyoruz:

SQL> STARTUP MOUNT;

8.

Yedek kontrol dosyası içerisindeki datafile isim
değişikliğini tanıtmamız gerekiyor.
STANDBY_FILE_MANAGEMENT parametresinin MANUAL
olarak ayarlanmış olması gerekmekte;

SQL> ALTER DATABASE RENAME FILE

'/disk1/oracle/oradata/payroll/tbs_4.dbf'

TO
'/disk1/oracle/oradata/payroll/tbs_x.dbf';

9.

Fiziksel yedek veritabanındaki redo işlemesini yeniden
devreye alıyoruz;

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE
DISCONNECT FROM SESSION;

Yedek sisteminde taşıdığımız datafile'ın yeni ismini sisteme
tanıtmazsak eğer aşağıdaki gibi bir hata alma ihtimaliniz olacaktır;

ORA-00283: recovery session canceled due to errors
ORA-01157: cannot identify/lock datafile 4 - see DBWR trace file
ORA-01110: datafile 4: '/Disk1/oracle/oradata/payroll/tbs_x.dbf


İyi çalışmalar.

Ogan

16 Ağustos 2010 Pazartesi

Listener.log Dosyası ve Boyutları

Selamlar,

Oracle'da dikkat edilmesi gereken bir konu da listener.log dosyasının boyutları. Belli bir zaman sonra bu dosya korkunç boyutlara ulaşabiliyor ve üzerine yazılamadığı için silmek, yedeklemek, yani kurtulmak gerekebilir.

Siz listener.log dosyasından bir şekilde kurtulabilirsiniz yalnız siz bu dosyası sildiğiniz veya yedeklediğiniz zaman, yenisini yaratacaksınız. Bu yeni yarattığınız listener.log dosyasını eğer Oracle'a tanıtmazsanız Oracle bu yeni dosyaya yazmaya başlamayacaktır.

Aşağıdaki çıktıları kontrol ederek ne demek istediğimi daha detaylı olarak anlayabilirsiniz;

$ lsnrctl show log_file;

LSNRCTL for HPUX: Version 10.2.0.4.0 - Production on 16-AUG-2010 15:39:28

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

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=optdb)(PORT=1521)))
LISTENER parameter "log_file" set to listener.log
The command completed successfully

$ lsnrctl show log_file;

LSNRCTL for HPUX: Version 10.2.0.4.0 - Production on 16-AUG-2010 15:39:28

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

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=optdb)(PORT=1521)))
LISTENER parameter "log_file" set to listener.log
The command completed successfully
$ lsnrctl show log_directory;

LSNRCTL for HPUX: Version 10.2.0.4.0 - Production on 16-AUG-2010 15:39:52

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

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=optdb)(PORT=1521)))
LISTENER parameter "log_directory" set to /opt/oracle/product/10.2.0/db_1/network/log/
The command completed successfully

--> Listener'ın log dosyasının adı listener.log ve dizini /opt/oracle/product/10.2.0/db_1/network/log/
--> Şimdi listener.log dosyasından kurtulalım;

$ rm /opt/oracle/product/10.2.0/db_1/network/log/listener.log

--> Yeni bir listener.log dosyası yaratalım;

$ cat /opt/oracle/product/10.2.0/db_1/network/log/listener.log
$ --> Bu dosya şimdilik boş.

$ sqlplus sys/password@opttest as sysdba

SQL*Plus: Release 10.2.0.4.0 - Production on Mon Aug 16 15:41:23 2010

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.


Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> exit
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
$ cat /opt/oracle/product/10.2.0/db_1/network/log/listener.log
$ --> Bağlantı sağladık ama hala boş!

--> Yeni yarattığımız log dosyasını tanımlamamız gerekiyor;

$ lsnrctl set log_file /opt/oracle/product/10.2.0/db_1/network/log/listener.log

LSNRCTL for HPUX: Version 10.2.0.4.0 - Production on 16-AUG-2010 15:41:52

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

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=optdb)(PORT=1521)))
LISTENER parameter "log_file" set to /opt/oracle/product/10.2.0/db_1/network/log/listener.log
The command completed successfully

LSNRCTL> set log_status off;
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=optdb)(PORT=1521)))
LISTENER parameter "log_status" set to OFF
The command completed successfully
LSNRCTL> set log_status on;
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=optdb)(PORT=1521)))
LISTENER parameter "log_status" set to ON
The command completed successfully
LSNRCTL> exit
$ ls -lrt
total 89736
-rw-r----- 1 oracle oinstall 1480 Mar 5 2009 opttest.log
-rw-r----- 1 oracle oinstall 45932608 May 28 00:34 sqlnet.log
-rw-r----- 1 oracle oinstall 38 Aug 16 15:44 listener.log
$ cat listener.log
16-AUG-2010 15:44:31 * log_status * 0

$ sqlplus aircom/password@opttest

SQL*Plus: Release 10.2.0.4.0 - Production on Mon Aug 16 15:44:52 2010

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.


Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> exit
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
$ ls -lrt
total 89736
-rw-r----- 1 oracle oinstall 1480 Mar 5 2009 opttest.log
-rw-r----- 1 oracle oinstall 45932608 May 28 00:34 sqlnet.log
-rw-r----- 1 oracle oinstall 255 Aug 16 15:44 listener.log
$ cat listener.log
16-AUG-2010 15:44:31 * log_status * 0
16-AUG-2010 15:44:52 * (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=opttest)(CID=(PROGRAM=sqlplus@optdb)(HOST=optdb)(USER=oracle))) * (ADDRESS=(PROTOCOL=tcp)(HOST=10.6.105.131)(PORT=49787)) * establish * opttest * 0
$
İyi çalışmalar.

Ogan

13 Ağustos 2010 Cuma

COMMIT & Transaction

Selamlar,

Her Oracle veritabanında gönderebileceğiniz bir komut tipi olan "COMMIT" (işlemek), bir transaction'ın sonlandığını Oracle'a bildiren ve yaptığınız değişikliklerin kalıcı olacağını talep eden komuttur.

Transaction: Bir transaction; birden çok SQL sorgularının çalıştırıldığı ama Oracle'ın, bu sorguların tamamını bir ünite(set) olarak algıladığı mantıksal sorgu bloğudur. Bu blok rollback ya da commit ile parçalanabilir veya sonlandırılabilir.

Bir transaction'ı commit etmediğiniz zaman;

1) Kendi transaction'ınınızda yaptığınız bütün sorgusal değişiklikleri sadece kendiniz görebilirsiniz. Bu değişiklikler diğer kişiler için geçerli değildir. Commit; komutunu gönderdiğiniz zaman, transaction içerisinde yaptığınız tüm değişiklikler diğer kullanıcılar tarafından da görüntülenebilir hale getirilecektir.
2) Bu transaction içerisinde yaptığınız tüm değişiklikleri geri alabilirsiniz (Bkz. Rollback, Bkz. Undo).

Oracle DML (Data Manupilation Langugage) komutlarından sonra commit koşmaz ancak DDL (Data Definition Language) komutlarından önce ya da sonra saklı bir commit komutu gönderir.

Commit komutunu ayrıca;

1) Şüphede kalan bir transaction'ı elle sonlandırmak (Bkz. in-doubt transaction),
2) SET TRANSACTION komutu ile sadece okumak için oluşturulmuş bir transaction'ı sonlandırmak

için kullanabilirsiniz.

Oracle'ın tavsiyesi, her transaction'ın bir şekilde sonlandırılması yönündedir. Bu, commit ya da rollback ile gerçekleştirilebilir. Eğer Commit ya da Rollback göndermeden bağlantınız kötü bir şekilde sonlanmışsa, o anki transaction'da yaptığınız bütün değişiklikler otomatik olarak rollback yapılacaktır (Bkz. SMON (System Monitor Background Process)).

Oracle araçlarından yapacağınız normal bir çıkışla birlikte geçerli olan transaction commit edilmiş sayılmaktadır. Ayrıca commit komutunu koşabilmek için de hiçbir yetkiye sahip olmanıza gerek yoktur.

Şüphede kalmış bir transaction'ı sonlandırmak, yani commit etmeye zorlayabilmek için FORCE TRANSACTION sistem yetkisine ihtiyacınız varken, orjinal kullanıcısı tarafından commit gönderilmiş ve şüphede kalan transaction'ı sonlandırmak içinse FORCE ANY TRANSACTION sistem yetkisine ihtiyacınız vardır.

Commit sentaksı aşağıdaki gibidir;

commit::=

Description of commit.gif follows

WORK

COMMIT ve COMMIT WORK komutları aynı görevi yapmaktadır.

Bu arada Şüphede kalan yani in-doubt transaction için DBA_2PC_PENDING data dictionary görüntüsünü inceleyebilirsiniz.

COMMENT

Comment, yani yorumu bir transaction için kaydedebilirsiniz. Comment alanını kullanabileceğiniz en güzel nokta ise DBA_2PC_PENDING data dictionary görüntüsünde "text" alanında tutulan ve 255 byte içerebilen yorumu görme imkanı sağlar. Bu sayede in-doubt transaction'ları takip ederken, neyi COMMIT FORCE yapmanız gerektiğiniz görebilirsiniz.

WRITE

Redo log'a yazılacak ve commit operasyonu tarafından yaratılmış redo bilgilerinin sıralamasının belirlenmesinde kullanılan bir ifadedir. Bu ifade, oluşan I/O beklemelerini azaltarak, gecikmeleri azaltabilir. Aşağıdaki durumlarda performansı arttırabilir ve kullanabilirsiniz;

1) Gerçekleşen "update" transaction'ı eğer çok büyük ise ve redo log'ların disk'e yazılması çok sık ise.
2) Uygulamanın asenkron commit edilmiş transaction'ları tolere edebileceği durumlarda.
3) Redo log tarafından oluşturulan yazma bekleme sürelerini azaltmada.

WRITE IMMEDIATE

Immediate yazma seçeneğini seçmişseniz eğer LGWR'a gönderilen otomatik bir mesaj sayesinde I/O arttırılabilir ve commit edilen transaction'ın hemen yazılmasını sağlayabilirsiniz.

WRITE BATCH

Batch komutuyla redo, redolog'a yazılması için saklanır. Hiçbir I/O işlenmez.

WRITE WAIT

Wait komutuyla gönderdiğiniz COMMIT'in oluşturuğu redo, online redolog'lara yazılana kadar işlenmez. Bir anlamda gönderdiğiniz COMMIT tutarlı bir redo üretip, online redo log'lara yazılıncaya kadar gönderilmiş sayılmaz.

WRITE NOWAIT

WAIT komutunun tam tersidir ve COMMIT işleme, beklemeden alınır.

FORCE

Şüphede kalan bir transaction'ı elle commit'e zorlamaya yarar. Bu tarzda transaction'ları bulabilmek için DBA_2PC_PENDING data dictionary görüntüsü sorgulanır ve ilgili transaction commit'e zorlanır. COMMIT'e zorlanan transaction ile bulunduğunuz transaction arasında bir bağlantı yoktur ve kendi transaction'ınınız COMMIT edilmiş sayılmaz.

İyi çalışmalar.

Ogan

10 Ağustos 2010 Salı

11g: Yeni Özellik (Interval Partitioning)

Merhaba,

Oracle'ın Enterprise sürümü ile satın alınabilen ve 10g ile birlikte hayatımıza giren Partitioning'in yeni bir özelliğinden bahsedeceğim, "Interval Partitioning". Aslında partitioning konusu altındaki en ciddi geliştirme diyebilirim zira partitioning ile uğraşan kişilerin zaman zaman aldığı klasik hatalardan, sürekli partition yaratmaktan ve silme zahmetinden bizi kurtarıyor.

Bir range partition yaratmanın script'ini inceleyelim;

create table sales6
(
sales_id number,
sales_dt date
)
partition by range (sales_dt)
(
partition p0701 values less than (to_date('2007-02-01','yyyy-mm-dd')),
partition p0702 values less than (to_date('2007-03-01','yyyy-mm-dd'))
);

Yukarıda yarattığımız partition'lar Ocak ve Şubat aylarına aittir. Peki bu tabloya Mart ayına ait bir veri girmeye çalıştığımız zaman ne olacak? Aşağıdaki hatayı alacaksınız;

ORA-14400: inserted partition key does not map to any partition

Bu hatayı aldınız çünkü girmek istediğiniz veriyi kapsamakta olan bir partition, geçerli olan tabloda bulunmamaktadır. Bu veriyi eğer bu tabloya girmek istiyorsanız Mart ayına ait bir partition yaratmak zorundasınız. Aksi halde girmeye çalıştığınız veriyi, ilgili tabloya işlemenizin bir imkanı bulunmamakta. Şimdi size şu soruyu yöneltmek istiyorum. Partition ekleme işini sizin için Oracle yapsa, çok iyi olmaz mıydı? İşte 11g ile gelen partitioning özelliklerinden birisi de budur. Oracle eklemesi gerektiğini algılar ve ilgili tabloya partition'ı ekler. Interval Partitioned

create table sales6
(
sales_id number,
sales_dt date
)
partition by range (sales_dt)
interval (numtoyminterval(1,'MONTH'))

(
partition p0701 values less than (to_date('2007-02-01','yyyy-mm-dd'))
);

Yukarıdaki tabloyu yarattık ve tablomuzda olmayan bir partition'a ait veriyi girmeye çalıştık. Normal şartlarda (interval yazmadığımız zaman) bildiğiniz gibi hata almamız gerekiyordu ancak;

SQL> insert into sales6 values (1,'01-jun-07');

1 row created.

Oracle istediğimiz veriyi işledi ve hata vermeden! Peki işlediğimiz veri nereye gitti? Oracle'ın bu veriyi bizim yarattığımız Ocak partition'ına eklemesine imkan yok. Lütfen aşağıdaki çıktıyı inceleyin;

SQL> select partition_name, high_value
2 from user_tab_partitions
3 where table_name = 'SALES6'
PARTITION_NAME HIGH_VALUE
----------------------------------------------------------------
P0701 TO_DATE(' 2007-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P41 TO_DATE(' 2007-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA

Haziran'a ait partition Oracle tarafından otomatik olarak yaratıldı ve veri işlememize engel bir durum oluşmasını ortadan kaldırdı. Partition'a verilen isim de yine Oracle tarafından otomatik olarak şeçildi.

Yarattığımız bu partition'ları farklı tablespace'lerde saklamak istersek eğer aşağıdaki sorguyu koşabiliriz;

interval (numtoyminterval(1,'MONTH'))
store in (TS1,TS2,TS3)

TS1, TS2 ve TS3 arasında "round robin" adı verilen ortak bir paylaşım sağlanmaktadır.

"Interval Partitioning" özelliğine sahip bir tablo yaratıldığı zaman inceleyebileceğiniz data dictionary görüntüsü DBA_PART_TABLES olacaktır. 10g ile 11g arasında bu görüntü bazında farklılıklar bulunmaktadır. Örneğin 10g'de partitioning olmadığı için INTERVAL diye bir kolon bulunmuyordu. Ancak 11g'de bu özellik eklendiği için DBA_PART_TABLES görüntüsü de değiştirildi.

Burada gelebilecek en olası soru şudur; "Interval değerini değiştirebilir miyiz? Değiştirmek için ne yapmamız lazım?" Evet, interval değiştirebilirsiniz. Aylık değil, örneğin yıllık hale de getirebilirsiniz ve Oracle partition'ları bu şekilde yaratmaya başlayacaktır. Bakınız;

SQL> alter table mypart2 SET INTERVAL (NUMTOYMINTERVAL(1,'YEAR');

Son yönlenecek bir soru ise "interval partitioning'i iptal edebilir miyiz?" Evet, edebilirsiniz zira interval partitioning ile ilgili birkaç "logging" problemi olduğunu duymuştum. Bir örnekte ilgili tablo ve üzerinde partition'lar, indeks'ler nologging olarak yaratılmış iken, interval partitioning'in otomatik olarak yarattığı partition'lar logging oluyordu. İlginç ancak bu şekilde davranmaması gerekiyor. Bu durumda geçici çözüm olarak interval partitioning kapatılabilir ve yerine elle yapılandırma devreye alınabilir;

SQL> alter table mypart2 SET INTERVAL ();

"Interval Partitioning" dışında eklenmiş birkaç özel partitioning türü daha bulunmaktadır ancak bana göre en kıymetlisi ve en yapılmış en büyük geliştirme budur. Birçok insanı partition'ların map etmemesi ile boğuşurken görmüştüm, bu özellik, bu güreşe bir son verecektir, vermelidir zira bir miktar masrafı olacaktır partitioning'in :)

İyi çalışmalar,

Ogan

4 Ağustos 2010 Çarşamba

11g: Yeni Özellik (Data Guard)

Merhaba,

Bu yazımda 11g ile birlikte gelen Data Guard özelliklerinden bahsedeceğim. Aslında hepsinden bahsetmenin pek imkanı yok çünkü ciddi değişiklikler mevcut.

Bir standby veritabanının yaratılışı ile başlayalım.

Yeni Bir Yedek Veritabanı Yaratmak

11g ile birlikte data guard yedek (standby) veritabanının kurulumu tek bir komut ile yapılabilmekte! Aslına bakarsanız bu bir 11g özelliği sayılmayabilir zira 10g'de yedek alınması ve karşı tarafa taşınması dışında herşey aynı, komut bile.

Yapmanız gereken aşamalar ise sırasıyla;

1) Birincil veritabanında pfile dosyasını yaratıyoruz;

SQL> create spfile from pfile;

2) Standby redolog'larını yaratmak zorunda değilsiniz ancak yaratmayı bilmek ve çalışmak güzel olabilir. Bunun dışında maximum availability ve maximum protection data guard koruma seviyeleri için yaratmak zorundasınız.

SQL> alter database add standby logfile group 4 ('/db/oracle/stby_redo01.log') size 200M;
SQL> alter database add standby logfile group 5 ('/db/oracle/stby_redo02.log') size 200M;
SQL> alter database add standby logfile group 6 ('/db/oracle/stby_redo03.log') size 200M;

3) Yedek veritabanında bir listener tanımlamamız ve reload ya da stop / start yapmamız gerekmektedir.

SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = ORCLSTBY)
(ORACLE_HOME = /db/oracle/product/11g/db_1)
(SID_NAME=ORCLSTBY)
)
)

LISTENER =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = orclsb)(PORT = 1521))
)

4) Ana sunucudaki tnsnames.ora dosyasının içerisine ORCLSTBY'nin bilgilerini ekleyelim;

ORCLSTBY =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = orclsb)(PORT = 1521))
)
(CONNECT_DATA =
(SID = orclstby)
)
)

5) ORCLSTBY için kullanacağımız init.ora dosyasını yaratacağız. Yaratacağımız init.ora dosyasının içerisinde sadece aşağıdaki satır olacak;

db_name=prolin11

Bu noktada önemli bir not. Kuracağımız veritabanı fiziksel yedek olacağı için db_name parametresi, primary ile aynı olmak zorunda yoksa redolog ya da archivelog'ları standby veritabanına işleyemeyiz. Aynı zamanda db_unique_name parametrelerinin de farklı olması gerekmekte. Sadece mantıksal yedek (logical standby) veritabanı için db_name'lerin farklı olması gerekmektedir.

6) ORCLSB sunucusu üzerinde $ORACLE_BASE/admin dizinine gidelim. Burada orclstby isimli bir dizin yaratalım. Bu dizinin içerisinde de adump isimli başka bir dizin yaratlım. Bu dizin standby veritabanının audit dosyalarını tutan dizin olacak.

7) ORCL sunucusu üzerindeki $ORACLE_HOME/dbs dizinine gidelim. Burada orapworcl isimli bir password dosyası bulacaksınız. Bu dosyanın amacı sysdba ve sysoper'lerin şifrelerini tutmasıdır. Bu dosyayı ORCLSB sunucusundaki $ORACLE_HOME/dbs dizini altına, orapworclstby ismi ile kopyalayalım.

8) ORCLSB sunucusu üzerindeki orclstby veritabanını nomount modda açıyoruz.

$ sqlplus / as sysdba
SQL> startup nomount

Tabii bu komutu koşarken ORACLE_SID parametresinin ORCLSTBY olarak kaydedilmiş olması gerekmekte çünkü / as sysdba ile bağlanıyoruz, yani bulunduğumuz sunucu üzerindeki veritabanını işaret ediyoruz. Veritabanı anı (instance) başlatılacak ve SGA tahsis edilecek ancak veritabanı mount edilmeyecektir.

9) Veritabanını replike eden RMAN komutunu çalıştırıyoruz. Çalıştıracağımız yer ise ORCL sunucusu;

connect target sys/password@orcl
connect auxiliary sys/password@orclstby
run {
allocate channel c1 type disk;
allocate auxiliary channel s1 type disk;

duplicate target database
for standby
from active database
dorecover
spfile
parameter_value_convert 'orcl','orclstby'
set db_unique_name='orclstby'
set db_file_name_convert='/orcl/','/orclstby/'
set log_file_name_convert='/orcl/','/orclstby/'
set control_files='/oradata/orclstby/control01.ctl'
set fal_client='orclstby'
set fal_server='orcl'
set standby_file_management='AUTO'
set log_archive_config='dg_config=(orcl,orclstby)'
set log_archive_dest_2='service=orcl LGWR ASYNC valid_for
(ONLINE_LOGFILES,PRIMARY_ROLE) db_unique_name=orclstby'
set log_archive_dest_state_2='enable'
set log_archive_format='orclstby_%t_%s_%r.arc'
;
sql channel c1 "alter system archive log current";
sql channel s1 "alter database recover managed standby database using current logfile
disconnect";
}

Bir fiziksel veritabanı kurmak aslında bu kadar basit. Yukarıdaki aşamaları takip ederseniz eğer kurulumu rahatlıkla tamamlarsınız.

Active Data Guard

10g versiyonunda ve öncesinde fiziksel veritabanını sadece read only olarak açabiliyordunuz. Bunu yapabilmeniz içinse recovery işlemini tamamen sonlandırmanız gerekiyordu.

SQL> alter database recover managed standby database cancel;
SQL> alter database open read only;

Geri dönmek içinse;

SQL> alter database recover managed standby database disconnect from session;
SQL> select open_mode from v$database;

11g'deki en büyük özellik ise fiziksel veritabanını yine read only olarak açabilir ve açtıktan sonra media recovery işlemini başlatarak, ana makine ile senkronizasyonu sağlayabilirsiniz.

İlk önce media recovery'i kapatıyoruz;

SQL> alter database recover managed standby database cancel;

Database altered.

Ardından veritabanını read only olarak açıyoruz;
SQL> alter database open read only;

Database altered.

Buraya kadar herşey normal ve herhangi bir 11g özelliği görmediniz. Az önce gösterdiğim komutu çalıştırdığınız zaman 11g'nin özelliği devreye girecektir;

SQL> alter database recover managed standby database disconnect;

Database altered.

Veritabanlarındaki anlık değişimleri gözlemleyelim;
SQL> alter system switch logfile;

System altered.

SQL> select max(Sequence#) from v$log;
MAX(SEQUENCE#)
--------------
79

Şimdi de yedek veritabanına bakalım;
SQL> select max(Sequence#) from v$log;
MAX(SEQUENCE#)
--------------
79

Aynı sayıyı görmemiz, veritabanlarındaki log işleminin devam ettiğiniz göstermektedir.

Ana sunucuda bir tablo yaratlım;

SQL> create table deneme (sutun1 number);

Table created.

Birkaç log geçişi yapın ve bir süre bekledikten sonra yedek veritabanını inceleyin;

SQL> desc deneme

Name Null? Type
----------------------------------------- -------- ---------------------------
sutun1

Gördüğünüz üzere yarattığımız tablo, fiziksel yedek veritabanı read only olarak açıkken, işlenen log dosyaları ile yaratıldı.

Veritabanı Yükseltme

Veritabanının yükseltme işlemlerini yapmak için veritabanını uzun bir süre kapatmak zorunda kalabilirsiniz. Bu konu başlı başına bir büyük dokuman olduğu için ilgili link'i gönderiyorum ve bir sorunuz olursa bu doküman üzerinden takip edebiliriz. Doküman İngilizce olduğu için takıldığınız yer olursa lütfen oganozdogan@gmail.com adresine sorularınızı gönderiniz.

http://download.oracle.com/docs/cd/B28359_01/server.111/b28294/rollup.htm#BABGHIGF

Redo Sıkıştırması

Data Guard'ın çalışma mantığı, ana sunucuda oluşan archivelog'ların, yedek sunucuya aktarılarak, işlenmesi ve replikasyonun sağlanmasıdır. Buradaki en büyük sorunlardan biri iki sunucu arasındaki archivelog taşınmasının yavaşlaması ve lag'lar (gecikmeler) oluşması. Redo'ların sıkıştırılması, bu sorunu çözebilir.

11g veritabanında oluşan redo'lar sıkıştırılabilir ve bu şekilde karşı tarafa aktarılabilir, yani redo akışına dahil edilirler. Aşağıdaki komutu koşarak sıkıştırılmış redo aktarımını aktif hale getirebilirsiniz. Yalnız önemli bir ayrıntı, redo'lar sadece bir gap (boşluk) kapatılırken sıkıştırılarak gönderilecek ve aradaki açık mümkün olduğunca hızlı kapatılmaya çalışılacaktır;

SQL> alter system set log_archive_dest_2 = 'service=pro11sb LGWR ASYNC
valid_for=(ONLINE_LOGFILES,PRIMARY_ROLE) db_unique_name=pro11sb compression=enable'

Sonuç

11g ile birlikte gelen en büyük özellik kesinlike Active Data Guard'dır. Fiziksel veritabanı read only olarak açıkken, archivelog'ların işlenebilmesi kesinlikle devrim niteliğinde bir Data Guard özelliğidir. Ben bu zamana kadar 10g üzerinde birçok defa Data Guard kurdum ve Active Data Guard, Redo Sıkıştırması ve hızlı replikasyon özellikleri olmadığı için ciddi vakit ve emek harcadım dersem yanlış olmaz.

Bu makalenin İngilizce ve Arup Nanda tarafından yazılmış verisyonunu görüntülemek için lütfen tıklayınız

İyi çalışmalar.

Ogan

2 Ağustos 2010 Pazartesi

sqlplus / as sysdba = Insufficient Privileges

Merhabalar,

Bir veritabanına sqlplus komutu ile sysdba olarak bağlanmaya çalışmaktasınız fakat bunu başaramıyorsunuz. Bir veritabanına bağlanmanın (sqlplus ile) birkaç yolu bulunuyor. Bunları kısaca listelersem;

sqlplus / as sysdba --> Komutun koştuğu makine üzerindeki Oracle veritabanına bağlanır. Bağlanılacak veritabanı ya da ASM instance'ını ORACLE_SID parametresi belirler. Onun için öncelikle ORACLE_HOME ve ORACLE_SID gibi parametrelere bakılmalıdır.

sqlplus sys/password@ORCL as sysdba -->TNSNAMES.ora dosyası kontrol edilir ve ORCL tanımlı ise ilgili veritabanına giriş denenir.

Bu iki komutu koştuğunuz zaman alabileceğiniz potansiyel hatanın adı "Insufficient Privileges" olacaktır, yani yetersiz yetkiler. İki komuttan aynı hatayı alabilmenize rağmen bakmanız gereken yerler başkadır. Komutların amacı ve çıkan hata aynı olsa da bakacağınız yer farklı olacaktır. Bu, gündelik hayatta oldukça sık rastlanan bir hatadır.

1) SQLPLUS / AS SYSDBA: Bu komutu girerek ilgili hatayı almışsanız eğer bakmanız gereken iki nokta bulunuyor. Bunlardan ilki oracle kullanıcınızın bağlı olduğu grup, diğer de SQLNET.AUTHENTICATION_SERVICES. Bu parametreyi bulacağınız yer sqlnet.ora dosyasıdır ve bu dosya da $ORACLE_HOME/network/admin/ dizini altında yer almaktadır. Bu parametrenin varsayılan değeri "none" fakat all ya da NTS olarak ayarlanabilmektedir.
SQLNET.AUTHENTICATION_SERVICES(NONE) ise / as sysdba ile bağlanamayabilirsiniz. Bu parametreyi ya NTS olarak ayarlayabilir ya da başına bir "#" koyarak devre dışı bırakabilirsiniz.
Oracle kullanıcısının bağlı olduğu grup eğer DBA grubu değilse ve SQLNET.AUTHENTICATION_SERVICES parametresi de kapalı durumda bekliyorsa, buradaki sorun da Oracle kullanıcısının dba olmamasından kaynaklanıyor demektir.

USERADD -G dba oracle

Yukarıdaki komutu gönderdiğiniz zaman Oracle kullanıcısı artık DBA grubunun altında yer alacaktır ve probleminiz çözülecektir.

2) SQLPLUS SYS/PASSWORD@ORCL AS SYSDBA: Bu komutu gönderdiniz ve ilgili hatayı aldınız. Bu durumda ise bakılması gereken yer password file olacaktır. Password file'ın bulunduğu yer $ORACLE_HOME/dbs/ ya da windows'lar için /database/ dizinidir. Bir password dosyanız olmayabilir ya da yanlış şifre ile kaydedilmiş olabilir. Yeniden yaratmak ya da var olanı düzelmek için;

CD $ORACLE_HOME/dbs/
ORAPWD FILE=orapworcl password=password force=y

Bu dosyayı yeniden yarattığınız zamansa sqlplus sys/password@orcl as sysdba komutunu göndererek veritabanına bağlanabiliyor olacaksınız.

Hatanın çözümü basit ancak keşfetmesi zordur. Özellikle yeni kurulum yapmış ve Oracle'a yeni adım atmış arkadaşların sıklıkla karşılaşabileceği türden bir hatadır.

İyi çalışmalar.

Ogan
Takip et: @oganozdogan