23 Aralık 2008 Salı

Oracle'ın Geçmişine Küçük Bir Yolculuk

Merhaba,

Oracle ile uğraşan herkes az çok Oracle'ın nasıl bir geçmişi olduğunu bilir. Bugün anlatmak istediğim aslında perdenin arkasında gerçekleşmiş olaylar.

Oracle'ın geçmişi tam olarak 30 yıllık bir geçmiş. Kurucularından olan Larry Ellison ve Bob Miner'ın başlangıçta sadece 2000 Doları varmış. Veritabanlarının adı da "Oracle"mış. Tabii o zamanlar ilişkisel veritabanı değil, "veritabanı programı" olarak biliniyormuş. Bahsettiğim yıl, 1977. Bruce Scott ve Ed Oates isimli yazılım mühendisleri ise Oracle'ın ilk tam zamanlı çalışan personelleri.

Oracle başlangıçta sadece ürünün adı olacaktı ancak ilerleyen zamanlarda şirketin adı olarak anılmaya başlandı. O zamanlarda da SQL (Structured Query Language) vardı fakat kullanan şirket IBM'di. ANSII gibi bir standart olmadığı için de ilk kullanılan sorgulama dili olmasının avantajı ile bütün veritabanları da peşinden SQL'e geçti ve bugün standart olan halini aldı.

IBM'in araştırma dosyalarından yararlanarak -o zamanların meşhur mühendisi Edgar Codd ile birlikte- ilk ilişkisel veritabanın temellerini 1978 yılında attılar. Projeye IBM destek vermemiş ve Edgar Codd görevinden istifa ederek Oracle'a geçmiştir.

1979'un Temmuz ayında Oracle, raflardaki yerini almaya başladı. Bu sayede Oracle ilk RDBMS olarak tarihteki yerini aldı. Oracle ilk olarak PDP-11 Assembler Language ile yazıldı ve 2nci versiyon olarak piyasaya sürüldü.

1980'li yıllarda Oracle veritabanı o zamanların en popüler programlama dili olan C ile yazılmaya başlandı. Bu yıllarda Oracle'ı diğer bütün yazılımlardan farklı kılan bir özellik vardı. O da işletim sistemi ne olursa olsun çalışması! İnsanlar 80'li yıllarda önce ilk olarak donanım alırlardı sonra yazılım alırlardı. Sonra da kara kara hangi yazılım bizim donanımlarımızda ve işletim sistemlerimizde çalışıyor diye düşünüyorlardı.

1982 yılı geldiğinde Oracle 16 ve 32 bit işletim sistemlerinde de çalışır hale geldi. Bu versiyon 2.3'tü. 2.3'te ise Oracle yepyeni bir son kullanıcı arayüzü ile piyasaya sürüldü. Yeni geliştirmeler içinse yazılım ekibi gece gündüz çalışmaya devam ediyordu.

1984 yılında, Oracle ilk kez "okuma tutarlılığı" konusunu gündeme getirdi ve Oracle versiyon 4 ile birlikte piyasaya sürdü. Bu şekilde Oracle bir sorgunun çalıştırıldığı zamandaki verilerin tutarlı olacağını garantilemiş oldu. Bankalar ve büyük şirketlerin bütün elektriğini üstüne çekmişti Oracle. Bu büyük innovasyon ile pazardaki yeri de gittikçe sağlamlaşıyordu. Informix ile savaşan Oracle'ın vurduğu en büyük darbelerden birisi de fiyatında uygunluk ve 2 ila 15 kat daha fazla arttırdığı performansı oldu. Yine bu yılın en büyük gelişmelerinden birisi de "Export/Import" aracının geliştirilmesi oldu. Günümüzde kullandığımız ve veritabanındaki verileri ve bütün objeleri başka bir veritabanına taşınması 1984 yılında Oracle'ın 4ncü versiyonu ile birlikte yapılır hale geldi.

1985'li yıllarda çok popüler olan Client/Server ilişkisini Oracle 5nci versiyonu ile birlikte hayata geçirdi. Oracle versiyon 9i'deki Real Application Clusters'ın temelleri de bu yıllarda clustering'in gelişmesi ile atılmış oldu.

1988'in en büyük dönüm noktası ise PL/SQL olarak tarihe yazıldı. Oracle 6ncı versiyonunda PL/SQL'i hayata geçirerek procedure'ler oluşturmaya başladı. Satır bazında tablolara kilit koyulması da yine bu versiyon ile gündeme geldi. Yine aynı yıl "Hot Backup" olarak bilinen ve veritabanı açık(online) iken yedekleme alınmasına yarayan sistem geliştirildi. Bundan önceki bütün versiyonlarda veritabanı yöneticileri veritabanını kapatıp sonra yedek alıyorlardı.

Oracle 1989 yılında OLTP sistemler için destek vermeye başladı (OLTP - OnLine Transaction Processing). Bu sistem genelde işlemlerin çok olduğu ve sorguların çok yoğun çalıştığı sistemlerde kullanılıyor. Bu sebepten, Oracle sektördeki birçok potansiyel müşteriyi de etkilemeyi başardı.

90'lı yıllarda teknolojik herşeyin gelişmesi son derece büyük bir ivme ile hızlanmaya başlamıştı. Oracle'ın artık yeni rakipleri, yüzleşmesi gereken bir innovasyon maliyeti ile birlikte gündeme gelmişti. Güncel gereksimler, müşteri ihtiyaçları ve rekabetin daha da kızışması ile birlikte 1990-2000 yılları arasında Oracle'da müthiş gelişmeler kaydedildi.

Oracle artık kat kat daha hızlı, güvenli, tutarlı ve sağlamdı. Oracle geliştirdiği 6.2 versiyonu ile cluster'lı yapısı ve PL/SQL'i ile müşterilerine birçok fırsat sunabiliyordu. Bu yıllarda Oracle daha çok son kullanıcıların arayüzlerinin iyileştirilmesi ile uğraşıyordu. Aslında son derece olumlu sonuçlar da alıyordu. Artık kullanıcılar daha kolay ve hızlı SQL kullanıyorlardı.

Seneler 1992'yi gösterdiğinde Oracle versiyon 7'yi piyasaya sürmeye hazırlanıyordu. Bu versiyonda PL/SQL'de trigger yazılmaya başlandı. Bu şekilde veritabanının işleyişi ve kontrol'ü biraz daha kolaylaşmış oldu. Veritabanı, artık yöneticisi tarafından tam olarak izlenebiliyordu (audit). Bu sayede yönetici, kullanıcılarının girdiği bütün sorguları kontrol edebiliyordu.

Client/Server uygulamaları hız kesmeden devam ediyordu. Bir yandan da 64 bit sistemler için entegrasyon işlemlerini yürütüyorlardı. Internet bazlı ve uygulama tabanlı entegrasyonları da son hız devam etmekteydi.

Oracle veritabanı, 1997 yılında Java ile daha da güçlü hale geldi ve veritabanının içinde Java uygulamaları geliştirebilir hale geldi. Veritabanının içine Java kodu gömülebiliyordu ve son derece hızlı bir şekilde çalıştırılabiliyordu. XML desteğini de vermeye başlayan veritabanının bu yıllardaki versiyonu 7 idi.

1998 yılında Linux tabanlı sistemi ile Oracle, internet ortamında çok daha sağlam bir duruş sergilemeye başladı. Versiyon ise 8i.

2000'li yıllarında başında Oracle "Unbreakable" olarak tanımlamaya başlamıştı kendini. Solaris'in 64 bit işletim sisteminin desteğini arkasına alan Oracle Linux Cluster'ları ile birlikte çok kuvvetli sistemin altına imzasını altın harflerle attı. Oracle veritabanı bu yıllardan sonra hep sağlam bir veritabanı olarak anıldı.

2001 yılında, Oracle'ın belkide en çok kullanılan, hala da uzun zaman önce sistemlerde entegre edilmiş ve sürüm güncellemesi yapılmamış veritabanı olan 9i piyasaya sürüldü. Oracle, Microsoft ve IBM'in veritabanlarına inanılmaz fark atmış, pazardaki payını dramatik bir şekilde arttırma yollarını genişletirken, yeniliklerin de ardı arkası kesilmiyordu. Tam cluster desteğine de geçiş sağlandı. Real Application Clustering ve kırılamayan Oracle 9i'nin lansmanları ve ardından gelen entegrasyonları ile veritabanı yöneticileri de sistemleri daha rahat ve kolay kullanmaya başladılar. Tabii aynı zamanda daha faydalı. Oracle veritabanı ile yapılan testlere göre, 100 TB'lık bir veritabanı, hala tutarlı ve sağlam bir şekilde durabiliyordu. Bu kadar gelişimden sonra da Oracle'ın aldığı ödüllerde artıyordu.

Oracle güvenli backup'ın geliştirilmesini 2006 yılında tamamladı ve sundu. Oracle'da veriler yedeklenirken artık encyrpt edilerek yedeklenebiliyor ve olası bir hırsızlık ve kaybolması durumunda korunabiliyordu. Oracle'ın versiyonu ise 10g oldu.

2007 yılında Oracle 11g versiyonunu tanıttı ve şu andaki sürümü ise 1 (release 1). 11g ile geliştirilen birkaç başlık ise; "Oracle Database Vault, Oracle Partitioning, Oracle Real Application Clusters and Oracle Audit Vault".

30 yılda Oracle'daki gelişmeleri bu şekilde özetleyebiliriz. Evet, sadece bir özet olarak kaydedilebilir yazdıklarım. Bunların arkasında ise inanılmaz bir yazılım geliştirme ekibi ve hırs var. Daha da ilerisinde ise, öğrenilecek çok şey :) Çünkü Oracle'da yeni bir innovasyon, siz eskisini tam olarak anlayana kadar geliştiriliyor ve Oracle durmuyor, yoluna devam ediyor. Bize de buradan şimdiye kadar bu yazılımın geliştirilmesinde katkısı bulunan bütün mühendislere teşekkür ediyoruz, ellerine sağlık.

İyi akşamlar,

Ogan


4 Aralık 2008 Perşembe

Reverse Key Indexes

Merhaba,

Bir index yarattığımız zaman (create index komutu kullanarak) sıradan bir b-tree index yaratmış oluyoruz. Bu yazımda bahsedeceğim konu ise Index'lerin Reverse Key ve Bitmap olanları.

Reverse Key Indexes: Bu index'in, standart bir b-tree index'ten en büyük farkı; kolonları değiştirmeden sadece indexlenen her kolonun byte'ını ters çevirmesidir. Bu durumda index'in okuduğu byte'ların yerleri tamamen değişecek ve bir takım performans problemlerine yol açacaktır. Yani, heap organized bir tablo'da yaratılan ve paşa paşa kullanılan bir b-tree index'i reverse ederseniz, bu büyük bir yanlışlık olacaktır. Reverse işlemi genelde RAC (Real Application Cluster)'lardaki performans problemlerini çözmek için kullanılır. Ayrıca, düzgün bir yapıya sahip index eğer reverse edilirse index range scan yapabilmekte bir hayal olarak kalacaktır. Çünkü index'in point ettiği alanların yerleri altüst olacak ve range ile bakabilmesi imkansız olacağından index yerine histogramlar vasıtasıyla ya full table scan'e bırakacaktır ya da düzensiz olarak reverse key index ile çalışıp, performansı son derece düşürecektir.
Reverse Key Index'leri genelde OLTP RAC (Online Transaction Processing Real Application Clusters) ortamlarında performansı arttırmak için kullanıyoruz.

Bir örnek vermek gerekirse;

SQL > CREATE INDEX index_deneme ON ogan_deneme (kullanici_adi) REVERSE;

Yukarıdaki örnekte, index_deneme diye bir reverse key index'i ogan_deneme tablosunun kullanici_adi kolonunda yarattık.

Reverse Key bir index'i eski haline döndürebilmek içinse;

SQL> ALTER INDEX index_deneme REBUILD NOREVERSE;

diyoruz... Ayrıca noverse demezsek, index_deneme reverse haliyle rebuild edilecektir.

Index'lerin genelde hızlı olmasının sebebi rowid'lerden, belirli bir düzen ile gitmesidir. Oracle veritabanın'da veriye en hızlı ulaşma yolu ise rowid'dir. Bu sebepten dolayıdır ki b-tree index'ler rowid'leri takip ederek sonuca ulaşırlar.

İyi çalışmalar,

Ogan

27 Kasım 2008 Perşembe

Data Concurrency and Consistency - Veri Uyumluluğu ve Tutarlılığı

Merhaba,



Oracle veritabanı bir ilişkisel veritabanı olduğundan tablolar arasındaki verilerin ilişkisi üzerine kurulmuştur. Bu ilişki bildiğimiz gibi primary ve foreign key başta olmak üzere index, synonym, pl/sql gibi destek üniteleri ile desteklenir. İlişkisel veritabanları birden çok kullanıcının aynı anda bağlı olacağı şekilde tasarlanmıştır. Bu da, yine birden çok kullanıcının aynı anda veritabanı içinde verilerin tutulduğu tablolara erişebileceği anlamına gelmektedir. Bugün anlatacağım konuda, birden çok kullanıcının aynı tablo üzerinde aynı anda aynı kolonu aynı değerlerle değiştirmesine kadar açıklamaya çalışacağım.

Veri uyumluluğu ve tutarlılığı birden çok kullanıcısı olmayan, yani sadece tekil kullanıcının bağlandığı -çoğu zaman test veya kişisel, bireysel sunucu diyebiliriz- durumlarda geçerliliğini yitirir. Çünkü tek kullanıcı istediği tabloyu değiştirebildiği için ve o anda bir başkasının da o tablodaki değişikliklerin üzerine yazamayacağı için veri tutarlılığından bahsedilemez. O veri, zaten tutarlı ve uyumlu olacaktır. Elektriklerin gitmesi, long operation dediğimiz işlemlerler sürerken veya ciddi bir pl/sql sorgusu çalıştırılırken ya da shutdown abort yazılmışken, veri uyumluluğu ve tutarlılığını sağlayabilen background processlerimiz de vardır. Bu tarz bir durumda bile Oracle, verilerin sağlığı için herşeyi yapmaktadır. SMON(System monitor) ve PMON(Process monitor) diye adlandırılan ve arkaplanda devamlı çalışan işlemler, Oracle'ın düzgün kapatılamadığı durumlarda devreye girer ve gerektiğinde "rollback" gerektiğinde "rollforward" yaparlar.


Tam olarak "Data Concurrency, Data Consistency" ne demek, şu şekilde açıklayabiliriz:

DATA CONCURRENCY: Birden çok kullanıcının aynı anda verilere erişmesine denir.

DATA CONSISTENCY: Her kullanıcı verilerin tutarlı halini görürler. Buna kullanıcının kendi yaptığı değişiklikler ve diğer kullanıcıların yaptığı değişiklikler de dahildir.

Oracle veritabanında, bir kullanıcı bağlı olduğu schemada, bir tablodaki veriye eriştiği zaman ve o veriyi "update" ederken, diğer hiçbir kullanıcı o veriyi update veya delete edemez. Çünkü ilk kullanıcı tablonun update etmeye çalıştığı kolonu üzerine kilit almıştır. Onun işlemi bittikten sonrada yani kolonu update ettikten sonrada kilit devam eder. Bu esnada buffer cache'de veri, dirty buffer olarak bekler. İlk kullanıcı henüz commit etmediği için aynı sessiondaki bütün kullanıcılar o verinin eski halini, yani update edilmemiş halini görürler. Update edilmiş halini tek gören ilk kullanıcımızdır. Bunun Oracle'da bu şekilde olmasının sebebi ise, kullanıcı yaptığı değişiklik veya değişikliklerden vazgeçebilir, rollback yapabilir. Ne zaman ki ilk kullanıcı commit eder, o zaman bütün kilitleri kaldırır ve diğer kullanıcılar da update edilmiş hallerini görmeye başlarlar. Yalnız, bu demek değildir ki, buffer cache'deki dirty buffer'lar commit ile yazılırlar. HAYIR, update, delete veya insert yani bir DML komutundan sonra gelen commit ile dirty buffer'ları dbf'lere (database file) yazmıyoruz. Bunun sebebi ise, redo logların dbf'lere yazılma işleminin son derece zor olduğudur. Veritabanının performansını çökermemek için verilerin dbf'lere yazıldığı belirli araklıklar vardır.

1) Buffer cache'deki dirty buffer miktarı 1/3'e ulaşırsa,
2) alter system switch logfile; yazılırsa,
3) Redo log'ların boyutu dolar ve diğer gruba geçerse,


VERILER REDO LOG'LARDAN DATABASE FILE'LARA YAZILIRLAR...


ANSI'nin belirlediği SQL standartlarına göre 3 çeşit "Preventable Phenomena" vardır. Yani 3 çeşit Önlenebilir fenomen vardır. Peki ne demek bu? Hemen açıklayalım.

Dirty Read: Bir başkası tarafından (bir başkasının transaction'ı tarafından) henüz commit edilmemiş verinin, diğer kullanıcının transaction'ı tarafından okunmasına denir.

Fuzzy Read: Bir transaction eğer daha önceden okuduğu veriyi tekrar okuduğunda, bir başka transaction'ın, ilk okuduğu veriyi commit etmesiyle, okuyacağı veri değişir ve buna da fuzzy read denir.

Phantom Read: Belirli bir arama koşulunu sağlayan ve belirli bir satır döndüren bir transaction yeniden aynı sorguyu sorguladığı zaman, bir diğer transaction'ın, aynı arama koşullarını sağlayan veriyi commit etmesiyle ortaya çıkan ortak sonuç kümesinden okuma işlemine denir.


Commit edilmemiş veri; dirty, fuzzy ve phantom olarak okunabilir, Commit edilmiş veri; fuzzy ve phantom olarak okunabilir, Tekrar tekrar okunan veri; sadece phantom olarak okunabilir. Bu şekilde sınırlanan okuma durumlarına ve oluşan katmana, Isolation Level (İzolasyon seviyesi) denir.

Oracle'ın garanti ettiği 2 tane uyumluluk kontrolü vardır. Bunlar, Statement level read consistency ve Transaction level read consistency dir. Bunlar, Oracle'ın her zaman bir sorgunun veri ile döneceğini ve her sorgunun veriye ulaşacağını garanti eden koşullardır.

Az önce bahsettiğim row locking yani satır bazında kilitleme duruma geri dönersek, satır kilitleme işlemi; bir kullanıcı o satırdaki veriyi update delete veya insert ederken satır bazında kilitleme gerçekleşir ve kilidi bulunduğu transaction ve kendisinin üzerine alır. Üzerineki kilit, commit veya rollback diyene kadar ya da ikisini de demeden veritabanından çıkana kadar (rollback yapar fakat autocommit on ise commit yaparak çıkar) geçerlidir. Bu kilit olduğu sürece aynı satıra erişmeye çalışan ve update etmeye kalkışan bütün transactionlar askıda kalırlar.

Bunu bir örnek ile göstermem gerekise;

İlk session'ımızı açtık ve ogan kullanıcısı ile bağlandık ...


C:\> sqlplus
ogan/deneme@orcl

SQL*Plus: Release 10.2.0.3.0 - Production on Thu Nov 27 19:13:04 2008

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

Connected to:Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production With the Partitioning, OLAP and Data Mining options

SQL> set timing on

SQL> drop table ogan_deneme purge;

Table dropped.

Elapsed: 00:00:04.38
SQL> create table ogan_deneme
2 (
3 kullanici_adi varchar2(40),
4 kullanici_soyadi varchar2(50)
5 );

Table created.

Elapsed: 00:00:00.09
SQL> insert into ogan_deneme

2 values ('ogan','ozdogan');

1 row created.

Elapsed: 00:00:00.01
SQL> / 1 row created.

Elapsed: 00:00:00.00
SQL> / 1 row created.

Elapsed: 00:00:00.00
SQL> select * from ogan_deneme;

KULLANICI_ADI KULLANICI_SOYADI

----------------------------------------

ogan ozdogan
ogan ozdogan
ogan ozdogan

Elapsed: 00:00:00.04

ogan_deneme tablomuza 3 tane duplicate veri aktardık ve şimdi bunları update ediyoruz ve row lock'ı üzerimize alıyoruz ...

SQL> update ogan_deneme
2 set kullanici_adi = 'ahmet';

3 rows updated.


Elapsed: 00:00:00.01
SQL> select * from ogan_deneme;

KULLANICI_ADI KULLANICI_SOYADI
-------------------------------------------

ahmet ozdogan
ahmet ozdogan
ahmet ozdogan

Elapsed: 00:00:00.03

Kullanici_adi satırı üzerinde henüz bir DDL çalıştırmadığımız veya commit ya da rollback yazmadığımız için row lock duruyor. Şimdi bunu aynı user ile bağlanan fakat farklı transaction'dan update etmeye çalışan kullanıcı ile nasıl olacağına bakalım ...

C:\> sqlplus
ogan/deneme@orcl

SQL*Plus: Release 10.2.0.3.0 - Production on Thu Nov 27 19:23:19 2008

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

Connected to:Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production With the Partitioning, OLAP and Data Mining options

SQL> select * from ogan_deneme;

no rows selected

Peki şimdi ne oldu? Hazır yeri gelmişken, veriler, diğer transaction tarafından commit edilmediği için görülemiyor ... Diğer transaction'a geçelim ve commit edelim ...

SQL> commit;

İlk ve ikinci transactionların ogan_deneme tablosunu nasıl gördüklerini görelim ...

SQL> select * from ogan_deneme;

KULLANICI_ADI KULLANICI_SOYADI

--------------------------

ahmet ozdogan
ahmet ozdogan
ahmet ozdogan

Elapsed: 00:00:00.04

Şimdi en kritik noktaya geldik. İlk transaction kullanici_adi'nı update etmeye çalışacak ve commit etmeyecek. Bu sırada ikinci transaction da aynı satırı update etmeye çalışacak ...

İlk oturum


SQL> update ogan_deneme
2 set kullanici_adi=
3 'ogan'
4 where kullanici_adi='ahmet';

3 rows updated.

Elapsed: 00:00:00.01

İkinci oturum

SQL> update ogan_deneme
2 set kullanici_adi='mehmet'
3 where kullanici_adi='ahmet';
...
...
...
...

* * * İkinci oturum aynı satırı update etmeye çalışırken askıda kaldı. Çünkü o satırın şu anki sahibi, kilidi koyan transaction ilk transactiondır. Kilitlenen transaction ve kilitleyen transaction'a bakalım ...

C:\> sqlplus / as sysdba

SQL*Plus: Release 10.2.0.3.0 - Production on Thu Nov 27 19:44:10 2008

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

Connected to:Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production With the Partitioning, OLAP and Data Mining options


SQL> select * from dba_waiters;

WAITING_SESSION HOLDING_SESSION LOCK_TYPE
--------------- --------------- --------------------------
MODE_HELD

----------------------------------------
MODE_REQUESTED LOCK_ID1 LOCK_ID2
---------------------------------------- ---------- ----------
159 153 Transaction Exclusive Exclusive 589831 1127


159 numaralı session (ikinci) bekliyor, 153 numaralı session (ilk) onu
tutuyor.

SQL> select * from dba_blockers;

HOLDING_SESSION
---------------
153

SQL> select * from v$lock order by SID;

ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ---------
331C4324 331C433C 153 TM 54936 0 3 0 611 0
3323CD88 3323CDAC 153 TX 589831 1127 6 0 611 1
33C34398 33C343AC 159 TX 589831 1127 0 6 506 0
331C43E8 331C4400 159 TM 54936 0 3 0 1092 0

TX: Satır tipi kilitlemelere verilen isim TX'tir. Genelde DML omutları kullanılırken satırlara TX kiliti konulur

TM: Tablo tipi kilitlemelere verilen isim TM'dir. Tablolar DDL komutlarına karşı kilitlenirler.

SQL> select * from dba_locks order by session_id;

SESSION_ID LOCK_TYPE MODE_HELD MODE_REQUESTED

---------- -------------------------- ---------------------------------------- ------

153 DML Row-X (SX) None
153 Transaction Exclusive None
159 Transaction None Exclusive
159 DML Row-X (SX) None
164 Temp Segment Row-X (SX) None
165 RS Row-S (SS) None
165 XR Null None
165 Control File Row-S (SS) None
166 Redo Thread Exclusive None
167 Media Recovery Share None
167 Media Recovery Share None
167 Media Recovery Share None
167 Media Recovery Share None
167 PW Row-X (SX) None
167 Media Recovery Share None

15 rows selected.

Satır bazında exclusive kilitleri 153 ve 159 için görüyoruz ...

Bu aşamadayken bahsetmek istediğim bir durum var. "Deadlock" dediğimiz kilit çeşidir vardır. Eğer ilk transaction A tablosunu update ediyorsa, aynı anda diğer bir transaction B'yi update ediyorsa ve ikisi de commit etmediyse, tam bu esnada ilk transaction B'yi, ikinci transaction'da A'yı update etmeye çalışırsa (update edilmeye çalışılan satırların aynı olduğunu düşünelim) o zaman ikisi birden kilitlenir ve deadlock oluşur.


Bir başka deadlock oluşma yolunu aşağıdaki (tahiti.oracle.com'dan alınan bir örnektir) tabloda görebiliriz. Kurtulmanın yolu, dba olarak bağlanıp ikisinden birinin session'ını kill etmemiz gerekir. Kill edilen session, kendisini rollback edeceğinden, diğeri update'ine devam edebilecektir.

DEADLOCK





İkinci transaction kilitli durumda bekliyor. Onu kurtaralım :) İlk session'da commit ya da rollback diyelim. Fakat bunu derken diğer komut satırıda ekranın yanında dursun. İlk transaction commit edildiğinde ikinci transaction'ın nasıl davrandığına ve ilk ve ikinci session'ın ogan_deneme tablosunu nasıl gördüğüne bakın ...

Şimdi de "flashback query" özelliğinden bahsetmek istiyordum ancak ya vista'dan dolayı ya da blogger'dan dolayı explorer çok yavaşlamış durumda :) Bundan sonraki yazı için flashback query diyelim ve oradan devam edelim. Konu ile ilgili daha detaylı yazmak isterdim fakat yazabilmek için ter döküyorum olmuyor :) Okuduğunuz zaman aklınıza takılan birşey olursa lütfen mail atmaktan çekinmeyin.


İyi akşamlar,


Ogan

26 Kasım 2008 Çarşamba

"Index Organized Table" nedir?

Oracle'da birden fazla tablo yaratım seçeneği vardır. "create table" ile yarattığımız zaman "heap organized table" yaratmış oluruz. Heap, yani yığın, küme demektir. Bir diğer seçenek olarak Index Organized Table, Partitioned Table gibi seçenekler de mevcuttur. Bu tamamen o anki ihtiyaca ve kullanılması gereken tablo yapısına göre belirlenir.

Heap organized tablolar database file(.dbf) uzantılı dosyalarda ve extent-->block-->segment yapısı ile tutulur.

Neden "Index organized table"? Bir tablonun neden index ile yönetilmesini, organized edilmesini isteriz? Index Organized Table ne demek?

Index Organized Table bir B-tree index depolama çeşidir. Heap Organized Table'da olduğu gibi dağınık, sıralanmamış ve farklı yerde değildir. Index Organized tabloların verileri b-tree index yapısında tutulur ve primary key tarafından sort edilir.

Peki ne gibi faydaları var?

1) Primary Key kolonuna hızlı ve rastgele erişim sağlanır. Zaten index range scan yapıldığı için heap organized bir tabloya göre daha performanslıdır.
2) Çok daha düşük alan kaplar ve primary key orderında olduğu için range scan'de random scan'de bir heap tablo'ya göre daha hızlı gerçekleşir.

Bir Index Organized tablo, sanki bir heap tabloymuş gibi kullanılabilir. Yani, triggerlar yaratılabilir, partitioned olarak kullanılabilir. Ayrıca tablo üzerinde ikincil index yaratılmasına izin verir. Buna bitmap index de dahildir.

Bir heap tablo nasıl yaratılıyorsa, index organized tablo'da aşağı yukarı aynı şekilde yaratılır.

Örnek vermek gerekirse;

SQL> CREATE TABLE ogan_deneme(
2 kullanici_adi varchar2(40),
3 kullanici_numarasi number(20),
4 gorevi varchar2(50),
5 CONSTRAINT pk_ogan_deneme primary key (kullanici_adi))
6 ORGANIZATION INDEX
7 TABLESPACE users;

Table created.

Bir index organized tablo yaratmamız için primary key kullanmalıyız. Bu primary key üzerinden tablo organizasyonu kuruluyor ve primary key'in barındırdığı unique index ve not null özelliği ile korelasyon gerçekleşiyor.



İyi akşamlar,



Ogan

Response File kullanarak Non-Interactive Oracle Kurulumu

Merhaba,


Birçoğumuz Oracle'ı Windows tabanlı işletim sistemlerinde öğrendik ve öğrenmeye devam ediyoruz. Nedeni kurulumun, kullanımın ve çalıştırılmasının kolay oluşudur. Aslında teorik olarak doğru bir yaklaşım fakat bana göre bu kendimize yaptığımız bir kötülük. Nedeni ise gerçek hayatta bir production sistemin başına geçtiğimiz zaman önümüzde çoğu zaman ya bir terminal ekranı -ki bu bir linux ya da unix işletim sistemi olduğu anlamına gelir- ya da windows haricinde bir işletim sistemi gelir. Dolayısıyla windows'a kurulumla uzak yakın pek bir ilgisi yoktur.

Windows'da kernel ayarları yoktur, terminal denen shell'e komut gönderip onun da kernel ile konuşmasını sağlayan arayüz yoktur, uninstall ederken registry ile uğraşmak zorunda kalmayız gibi birçok faktör sayabiliriz.

Sistemimizin sağlıklı bir biçimde çalışmasını hedefliyorsak, bu işin %50'lik kısmı kurulum esnasında tamamlanır. Düzgün kurulmamış bir veritabanı ileride ciddi sorunlara dönüşebilmektedir.

Gelelim konumuza. Response file nedir? Öncelikle bir linux, unix, solaris, aix vb unix tabanlı sistemlere kurulum yaparken her zaman önümüzde grafiksel bir arayüz bulunmuyor. İş gereği uzaktan bağlanıyoruz ve çoğu zaman makinenin bile başında olamıyoruz. Elbetti ki makinenin başında olmayışımız, grafiksel bir takım arayüzlere ulaşamayacağımız anlamına gelmez. Çalıştığınız makine üzerinde grafik kartı dahi olmayabilir. Ben öncelikle grafik kartı olmayan bir makine üzerinde neler yapılabilir ondan bahsedeyim.

Unix işletim sistemlerinde X11 dediğimiz paketler vardır. X11 windows tabanlı olup genelde unix'ler için kullanılır ve unix sistemlerden grafiksel arayüzlerin çekilebilmesine yarar. Bu paketlerin gönderilmesi ve unix'ten cevap alınması ile windows'dan putty gibi ssh client'ı veya telnet ile bağlandığımız bir unix işletim sistemindeki grafiksel arayüzlerin çalıştırılmasını kendi işletim sistemimiz olan windows'a aktarabiliriz. Bu aktarım içinse Humming Bird "Exceed" veya XManager gibi özel yazılımlar kullanılır. Putty ile de X11 forwarding paketlerini işaretleyerek sonuç üretmek mümkün ancak unix tarafında DISPLAY parametresini şu şekilde set etmek gerekebilir:

# DISPLAY=:0.0 --> (Putty'de geçerli, xmanager ve exceed'de genelde 0.0 olur ancak kontrol edilmesi lazım)
# export $DISPLAY

Bu şekilde runInstaller executable dosyasını grafiksel olarak windows işletim sistemimizde çalıştırabiliriz. Sadece runInstaller değil, dbca, netca, patchset upgrade runInstaller gibi configuration assistantları da grafiksel arayüzlerle çalıştırmak mümkün.

Evet, bu kadar ön bilgi yeterli olacaktır sanırım. Şimdi, responsefile dediğimiz dosya, adı üzerinde bir cevap dosyasıdır. Peki neye cevap verir? Oracle responsefile'dan bir instance, client, database, net gibi configuration assistanları çalıştırırken hesap sorar. Grafiksel arayüzde sizden istediği bütün cevapları, bu yardımcı yazılımları çalıştırırken responsefile'dan okuyacaktır.

Responsefile ile gerçekleştirilen bütün kurulumlara "Silent ya da Non-interactive" kurulum denir. Az önce de dediğim gibi, son derece zor bir kurulum çeşidi olarak algılayabilirsiniz. "E grafik yoksa nasıl kuracağız?" gibi sorular kafınıza takılabilir. Bütün bunların cevabını işteyken acı çekerek öğrenmek yerine, yazının devamını takip ederek öğrenebilirsiniz.

otn.oracle.com'dan indirdiğimiz bir install dosyamız var diyelim. Örneğim kurmak istediğimiz işletim sistemi RHEL 4 (Red Hat Enterprise Linux 4) olsun. Önceki bütün aşamaları (preinstallation, kernel parametrelerinin ayarlanması, oracle kullanıcısı ve dba grubunun yaratılması vs) atlıyorum. Bu aşamada kafanıza takılan soruların bütün cevaplarını tahiti.oracle.com dan öğrenebilirsiniz.

Gunzip veya untar ettiğimiz Oracle kurulum dosyasının içinde -genelde runInstaller executable'ının olduğu yerde- response diye bir dosya göreceksiniz. İçerisinde ise her configuration assistant'a özel response file'larını göreceksiniz. DBCA çalıştırırken farklı, NETCA çalıştırırken farklı, runInstaller çalıştırırken farklı. Sadece Patchset'inkini göremezsiniz o da zaten patchset ile birlikte geliyor. Bu response file'lar bir şablon şeklindedir ve her parametreden önce o parametrenin ne olduğunu, örnek olarak ne yazılabileceğini anlatır. Bu parametreleri ilk başta tek tek geçerek ne olduğunu anlamanızda fayda var. İlk seferinde bunların hepsini düzenleyin ve sonraki kurulumlar için saklayın. İkinci seferinde size inanılmaz kolay gelecektir ve her kurulumunuzu response file ile yapmak isteyeceksiniz. Hem daha gelişmiş bir kurulum olur hem de sizin için artı bir bilgi kümesi haline gelir.

Response file'ın içeriğini ayarladığınız zaman artık Silent ya da non-interactive kuruluma geçebilirsiniz.

# ./runInstaller [-silent] [-nowelcome] [-nowait] -responsefile

Silent: Oracle kurulumunu silent modda çalıştırır ve kurulum penceresini açık tutar. Eğer bu modda çalışıyorsak, nowelcome opsiyonuna gerek yok.
Nowelcome: Kurulum penceresini açık tutar.
Nowait: Silent kurulum tamamlandığı zaman kurulum ekranını kapatır.
Responsefile: Kurulumun response file'ını belirtmek için kullanılır.
Response_file_name: Response file'ın adı ve önünde -eğere gerekiyorsa- absolute path'i.

Silent opsiyonuyla bu kurulumun bir non-interactive kurulum olduğunu ve bu non-interactive kurulumun bir response file'a bağlı olacağını, cevapların oradan alınacağını söylüyoruz. Ardından runInstaller da bu duruma göre kuruluma devam ediyor.

Bahsettiğim gibi, çoğu zaman önünüzde sadece bir terminal ekranı olacak. Onun için, en kritik komutları, en önemli adımları iyi bilmek, nasıl olsa ToAD gibi yazılımlar var oradan hallederim gibi düşüncelere kapılmamak lazım. Bu işin en önemli yolu sadece bir terminal ekranından müdahale edebilmektir. Bunu başarıp, bir Oracle kurabiliyorsanız, Oracle'ı upgrade edebiliyorsanız, çökmüş bir veritabanını ayağa kaldırabiliyorsanız işte o zaman oyun şimdi yeniden başlıyor demektir...

İyi akşamlar,

Ogan

25 Kasım 2008 Salı

Küçük bir Index Örneği

Merhaba,

Bu yazımda indexlerin kullanımı ile ilgili çok ufak ama son derece önemli olduğunu düşündüğüm birkaç örnek göstereceğim.

Index, bir kitabın sayfalarının tutulması, word dökümanında giriş sayfasından sonra gelen içindekiler bölümü veya süper marketlerdeki yiyecek bölümlerinin ayrılması gibidir. Bunların temel amacı aslında istenilen noktaya en hızlı şekilde ulaşmaktır. Peki neden en hızlı şekilde ulaşmak isteyelim? Cevap basit, "vakit, nakittir". Dolayısıyla veritabanının performansı için çoğu zaman index kullanmak isteyebiliriz. Tabii ki yeri geliyor ki index kullanmanın da full table scan yapmaktan daha berbar bir çözüm olduğunu görüyoruz.

Indexlerinde kendi içinde farklı farklı tipleri vardır. Bu index tiplerinin belirlenmesi veritabanındaki genel yapı ve tablonun içeriğine göre değişkenlik gösterebilir. B-tree indexlerin kullanılacağı bir tablodaki performans düşükken bu indexi reverse etmenin ya da bitmap index'e çevirmenin performans üzerindeki etkileri inanılmaz boyutlarda olabilir.

Ufak örneklerle başlayalım. (sys ile bağlıyız)

SQL> create user ogan identified by deneme;
User created.

SQL> grant connect,resource to ogan;

Grant succeeded.

SQL> conn ogan/deneme
Connected.
SQL> set linesize 600
SQL> set pagesize 150
SQL> create table ogan_deneme
2 (
3 username varchar2(40),
4 userid number (10)
5 );

Table created.

SQL> select * from user_indexes;

no rows selected

SQL> select * from user_constraints;

no rows selected

Bu aşamada birkaç veri girişi yapalım...

SQL> insert into ogan_deneme
2 values ('ogan',12345);

1 row created.

SQL> insert into ogan_deneme select * from ogan_deneme;

1 row created.

SQL> /

2 rows created.

SQL> /

4 rows created.

SQL> /

8 rows created.

SQL> /

16 rows created.

SQL> /

32 rows created.

SQL> /

64 rows created.

SQL> /

128 rows created.

SQL> select count(*) from ogan_deneme;

COUNT(*)
--------------
256

SQL> select * from ogan_deneme where userid=12345;

256 rows selected.

Elapsed: 00:00:01.88

Execution Plan----------------------------------------------------------
Plan hash value: 1896958321
---------------------------------------------------------------------------------
Id Operation Name Rows Bytes Cost (%CPU) Time
---------------------------------------------------------------------------------
0 SELECT STATEMENT 256 8960 3 (0) 00:00:01
* 1 TABLE ACCESS FULL OGAN_DENEME 256 8960 3 (0) 00:00:01
--------------------------------------------------------------------------------

Statistics----------------------------------------------------------
5 recursive calls
0 db block gets
32 consistent gets
0 physical reads
0 redo size
3908 bytes sent via SQL*Net to client
587 bytes received via SQL*Net from client
19 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
256 rows processed

Bu aşamadan sonra index yaratalım ve neler olduğunu görelim. Yaratacağımız index bir b-tree index olacaktır.

SQL> create index index_deneme on ogan_deneme(userid);

Index created.

SQL> select index_name, table_name from user_indexes;

INDEX_NAME TABLE_NAME
------------------------------ ------------------------------
INDEX_DENEME OGAN_DENEME

SQL> select * from ogan_deneme where userid=12345;

256 rows selected.

Elapsed: 00:00:00.53

Execution Plan----------------------------------------------------------
Plan hash value: 4118286141
--------------------------------------------------------------------------------------------
Id Operation Name Rows Bytes Cost (%CPU) Time
--------------------------------------------------------------------------------------------
0 SELECT STATEMENT 256 8960 2 (0) 00:00:01
1 TABLE ACCESS BY INDEX ROWID OGAN_DENEME 256 8960 2 (0) 00:00:01
* 2 INDEX RANGE SCAN INDEX_DENEME 256 1 (0) 00:00:01
--------------------------------------------------------------------------------------------

Statistics----------------------------------------------------------
13 recursive calls
0 db block gets
46 consistent gets
0 physical reads
0 redo size
3908 bytes sent via SQL*Net to client
587 bytes received via SQL*Net from client
19 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
256 rows processed

Daha önce çalıştırdığımız full table scan, içerik duplicate olduğu için 32 consistent gets çıktısı verdi. Ancak Index range scan ile arattığımız zaman bu rakam 46'ya ulaştı. Yani, veritabanının okuduğu alan sayısı arttı ve biz bunun düşük olmasını bekliyorduk. Dolayısıyla performans adına pek iç açıcı bir sonuç olmadığını görüyoruz.

SQL> drop index index_deneme;

Index dropped.

SQL> drop table ogan_deneme purge;

Table dropped.

SQL> create table ogan_deneme
2
(
3
username varchar2(40),
4 userid number(10)
5 );

Table created.

SQL> create index index_deneme on ogan_deneme(userid);

Index created.

SQL> insert into ogan_deneme 2 values('ogan',12345);
1 row created.

SQL> insert into ogan_deneme 2 values('ahmet',54321);
1 row created.

SQL> insert into ogan_deneme 2 values('mehmet',32145);
1 row created.

SQL> insert into ogan_deneme 2 values('ali',54123);
1 row created.

SQL> insert into ogan_deneme select * from ogan_deneme;
4 rows created.
SQL> /
8 rows created.
SQL> /
16 rows created.
SQL> /
32 rows created.
SQL> /
64 rows created.
SQL> /
128 rows created.
SQL> /
256 rows created.
SQL> /
512 rows created.
SQL> /
1024 rows created.

SQL> select * from ogan_deneme;

2048 rows selected.
Elapsed: 00:00:03.18
Execution Plan----------------------------------------------------------

Plan hash value: 1896958321
---------------------------------------------------------------------------------

Id Operation Name Rows Bytes Cost (%CPU) Time --------------------------------------------------------------------------------- 0 SELECT STATEMENT 2048 71680 3 (0) 00:00:01 1 TABLE ACCESS FULL OGAN_DENEME 2048 71680 3 (0) 00:00:01 ---------------------------------------------------------------------------------

Statistics----------------------------------------------------------

152 consistent gets

2048 rows processed

Şimdi bir de index range scan ile bakalım duruma...

SQL> select * from ogan_deneme where userid=12345 or userid=54321;

1024 rows selected.
Execution Plan----------------------------------------------------------

Plan hash value: 1212428791
--------------------------------------------------------------------------------------------- Id Operation Name Rows Bytes Cost (%CPU) Time --------------------------------------------------------------------------------------------- 0 SELECT STATEMENT 1024 35840 2 (0) 00:00:01 1 INLIST ITERATOR 2 TABLE ACCESS BY INDEX ROWID OGAN_DENEME 1024 35840 2 (0) 00:00:01 * 3 INDEX RANGE SCAN INDEX_DENEME 8 2 (0) 00:00:01 ---------------------------------------------------------------------------------------------
Statistics----------------------------------------------------------

154 consistent gets

1024 rows processed

Consistent gets 2 arttı. Şu aşamada sonuç olarak yine amaçsız bir index olarak karşımızda duruyor olabilir. Şimdi bu indeximizi işe yarar hale getirebilmek için tabloda birkaç değişiklik gerçekleştirelim.

SQL> drop index index_deneme;

Index dropped.

SQL> truncate table ogan_deneme;

Table truncated.

SQL> insert into ogan_deneme

2 values('ogan',12345);
1 row created.


SQL> insert into ogan_deneme

2 values ('ahmet',99999);
1 row created.


SQL> insert into ogan_deneme

2 values ('mehmet',88881);
1 row created.


SQL> insert into ogan_deneme

2 values ('ali',12333);
1 row created.


SQL> insert into ogan_deneme

2 values ('veli',24144);
1 row created.

SQL> select * from ogan.ogan_deneme;

Execution Plan----------------------------------------------------------Plan hash value: 1896958321
--------------------------------------------------------------------------------- Id Operation Name Rows Bytes Cost (%CPU) Time --------------------------------------------------------------------------------- 0 SELECT STATEMENT 5 175 3 (0) 00:00:01 1 TABLE ACCESS FULL OGAN_DENEME 5 175 3 (0) 00:00:01 ---------------------------------------------------------------------------------
Statistics----------------------------------------------------------

16 consistent gets

5 rows processed

Şimdi index yaratalım...

SQL> create index index_deneme on ogan_deneme(userid);

Index created.

SQL> select * from ogan_deneme where userid=12345;

Execution Plan----------------------------------------------------------

Plan hash value: 4118286141
-------------------------------------------------------------------------------------------- Id Operation Name Rows Bytes Cost (%CPU) Time -------------------------------------------------------------------------------------------- 0 SELECT STATEMENT 1 35 2 (0) 00:00:01 1 TABLE ACCESS BY INDEX ROWID OGAN_DENEME 1 35 2 (0) 00:00:01 * 2 INDEX RANGE SCAN INDEX_DENEME 1 1 (0) 00:00:01 --------------------------------------------------------------------------------------------
Statistics----------------------------------------------------------

3 consistent gets

1 rows processed

Çok az sayıda ama birbirinden farklı verileri barındıran bir tabloda index yaratılır mı? sorusunun en güzel cevabı. Tam 13 consistent gets daha düşük çıktı aldık. Sadece bir index yaratarak. Dolayısıyla 3-5 verili bir tabloda da index yaratmanın önemi çok açık olarak ortada. Bu tabloya, özellikle OLTP sistemlerde günde milyonlarca defa giriş olabileceğini düşünürseniz inanılmaz bir zaman kazancı olacaktır.

Indexler durduğu yerde disable / unusable olmazlar. Tablo'da bir movement olduğu zaman (alter table deneme move; , alter table deneme shrink space; gibi)

SQL> select * from ogan_deneme where userid=12345;

Execution Plan----------------------------------------------------------

Plan hash value: 1896958321
--------------------------------------------------------------------------------- Id Operation Name Rows Bytes Cost (%CPU) Time --------------------------------------------------------------------------------- 0 SELECT STATEMENT 1 35 3 (0) 00:00:01 * 1 TABLE ACCESS FULL OGAN_DENEME 1 35 3 (0) 00:00:01 ---------------------------------------------------------------------------------

Tablo'yu move ettik ve blockların bulunduğu yerleri değiştirdik. Dolayısıyla index disable duruma düştü.

SQL> alter index index_deneme rebuild online;

Bu noktada unutmamak gereken durum şudur. Index rebuild edilirken, table'da exclusive lock meydana gelir ve kimse tabloya erişemez. Yani, büyük çapta bir indexin çok uzun sürebileceğini düşünürsek sıkıntı olabilir.

SQL> select * from ogan_deneme where userid=12345;

Execution Plan----------------------------------------------------------

Plan hash value: 4118286141
-------------------------------------------------------------------------------------------- Id Operation Name Rows Bytes Cost (%CPU) Time -------------------------------------------------------------------------------------------- 0 SELECT STATEMENT 1 35 2 (0) 00:00:01 1 TABLE ACCESS BY INDEX ROWID OGAN_DENEME 1 35 2 (0) 00:00:01 * 2 INDEX RANGE SCAN INDEX_DENEME 1 1 (0) 00:00:01 --------------------------------------------------------------------------------------------

Index'i rebuild ettiğimiz zaman tekrar kullanılır duruma kavuştu. Az önceki gibi düşük sayıda farklı veriler içeren bir tablo'da bu sıkıntı olsaydı rebuild sırasında da sıkıntı yaşamazdık. Yalnız rebuild ederken index'in size'ı son derece dikkatle izlenmelidir.

Index'ler üzerine konuşmakla bitiremeyiz. Yukarıdaki örnekler sadece b-tree indexlerin unique olanlarıdır. Bunun reverse key, bitmap, partitioned, non-partitioned vb tipleri de mevcuttur. Partitionedların içerisinde global local ve bunların dışında fake indexler gibi index tiplerini de eklersek herbiri ayrı ayrı bir konu olarak saatlerce anlatılabilir. Best Practicelerini de eklersek Oracle içinde apayrı bir uzmanlık alanı bile oluşturabilecek kadar geniş bir konudur.

Bir veritabanının performansının önemli ölçüde değişmesini (iyileşmesini) istiyorsak, index yaratmalıyız demek zor ancak sağlıklı indexler ve doğru tercihler ile son derece faydalı olacaktır.

İyi geceler,

Ogan

15 Ekim 2008 Çarşamba

*.csv Dosyalarının Oracle Veritabanına Yüklenmesi (SQLLDR)

Merhaba,

Takip etmek istediğim konu ile biraz alakasız olacak fakat önemli bir konu ve hiç bahsetmediğim için yazacağım.

Belirli durumlarda Oracle veritabanına external verileri yüklememiz gerekebilir. Yani, bu veriler çoğu zaman bir Java veya C# arayüzünden gelmeyebilir. Bu veriler herhangi bir programlama dilinin arayüzünden gelmediği gibi, uzantıları da farklı olabilir. Bu durumda kullanabileceğimiz Oracle aracına SQL-LOADER diyoruz (komut olarak kullanım şekli ise SQLLDR).

Bir excel dosyasındaki bütün verileri .csv (comma seperated value) olarak değiştirebiliriz. Bu değişikliği yaptıktan sonra kısa bir örnek ile devam edelim. Bu arada sqlldr'ın çalışabilmesi için öncelikle bir control dosyası (.ctl) yaratmamız gerekiyor.

CONTROL FILE:

Bir text dosyası ve c'nin altında trial isimli bir folder açalım ve içine;

load data
infile 'c:\trial\veri.csv'
into table deneme
fields terminated by ","
optionally enclosed by '"'
(deneme_sayi,deneme_karakter)

Kaydedelim ve kapatalım. Uzantısını da .ctl olarak değiştirelim ve adını kontrol koyalım. Ardından yüklenmesini dilediğiniz schema'ya bağlanıp yukarıdaki deneme tablosunu yaratalım;

ORACLE TABLE:

C:\> sqlplus deneme/password@oracle_sid
SQL> drop table deneme purge;
SQL> create table deneme
SQL> (
SQL> deneme_sayi number(10), deneme_karakter varchar2(45)
SQL> );
Table created.

Tablomuzu da yarattıktan sonra control dosyasında belirttiğimiz veri.csv'ye bakalım. Önce bir excel dosyası yaratalım ve adını veri.xls koyalım. Ardından örneğimiz için içine şu verileri dolduralım;

EXCEL FILE:

987 Bu bir denemedir
654 Bu da bir denemedir
321 Bu da bir baska denemedir

Kaydedelim ve uzantısını da .csv olarak değiştirelim.

Bir komut satırı açarak şu şekilde deneyebiliriz;

SQLLDR INVOKE:

C:\trial> sqlldr deneme/password@oracle_sid control=kontrol.ctl log=logfile.log

Bu komutun ardından trial folderının altında logfile oluşacak ve buradan durumu gözleyebilirsiniz. Eğer herhangi bir problemle karşılaşacak olursanız da, .bad uzantılı bir dosya göreceksiniz.

Şimdi tablomuzu kontrol edelim ve verilerin yüklenip yüklenmediğini görelim,

C:\> sqlplus deneme/password@oracle_sid
SQL> select * from deneme;

Eğer verileri görebildiyseniz bu aşamada şunu yapabilmiş oldunuz. SQLLDR tool'u ile .csv uzantılı bir dosyanın içindeki verileri sağlıklı bir biçimde Oracle'da daha önceden yarattığınız tabloya atabildiniz.

Unutmadan, unix tabanlı işletim sistemi kullanan arkadaşlarda sqlldr'ı şu şekilde çalıştırabilir;

SQLLDR INVOKE:

% sqlload userid=deneme/password control=kontrol.ctl log=logfile.log

Tekrar görüşmek dileğiyle,

Ogan

10 Ekim 2008 Cuma

Veri Tipleri ve Temel SQL Queryleri

ORACLE VERİ TİPLERİ

Kullandığımız veritabanında, verileri saklayabilmemiz için tablolar yaratmamız gerekmektedir. Bu tablolarında bünyesinde de birtakım veri tipleri mevcuttur. Bu veri tipleri, saklanabilecek verinin bir anlamda kimliğini açığa çıkartmaktadır.

Veri tipleri arasında;

- CHAR(X): Büyüklüğü 1 byte ile 2000 byte arasındadır ve bu aralıktaki karakter değerlerini saklayabilmek için kullanılır. CHAR'ın özelliği, tablo yaratılırken eğer CHAR(5) olarak bir değişken yarattıysak, verilen değelerin tamamı doldurulacak demektir. Eğer 5'ten büyük bir karakter girmeye çalışırsanız hata alırsınız fakat düzeltemenin yoluda modify etmektir.

- VARCHAR2(X): Büyüklüğü 1 byte ile 4000 byte arasındadır. CHAR'dan en büyük farkı ve en büyük kullanılma sebeplerinden biri ise, VARCHAR(200) ile VARCHAR(2)'nin yaratıldıkları zaman aynı yeri kaplıyor olmasıdır. Yani, bir değer girilene kadar veritabanında aynı miktarda yeri işgal ediyorlar. Burada gelebilecek soru; neden varchar değilde varchar2 olabilir. varchar reserved keyworddür ve ileriki bir zamanda kullanılmak üzere saklanmıştır.

NUMBER(X,Y): X tam kısmı, Y ise ondalıklı kısmı temsil eder. Örneğin; number(4,1) yazarsak 3 tam sayılı ve bir ondalıklı sayı olacak demektir. Belirtilen ondalıklı sayıdan daha büyük ondalıklar girildiğinde, Oracle bu ondalığı, belirtilen ondalığa kadar rounded-up olarak yuvarlar. Ondalık belirtmeden de bir değişken tanımlanabilir. Bu bir tam sayı olacağını ifade edecektir.

DATE: Bu veri tipi, tarih ve zaman bilgilerini barındırır. Toplam 7 byte büyüklüğündedir ve en küçük birimi saniyedir.

LONG, RAW, TIMESTAMP, CLOB, ROWID gibi diğer veri tipleri de mevcuttur.

SQL QUERYLERİ
Veritabanına kaydettiğimiz verileri alma, görünteleme, raporlama vb işleri yerine getirmemize yarayan, Oracle veritabanının olduğu gibi diğer bütün veritabanlarının en temel yapıtaşı, atomu olan sorgulama sistemine SQL Queryleri denir(QUERY-Cümle). SQL Queryleri ile, ilişkisel veritabanı özellikleri, tablo birleştirme, yaratma, düşürme, boşaltma, pl/sql içinde dinamik olarak gömebilme, yönetim komutlarını yerine getirebilme, kullanıcılar yaratabilme, yaratılanlara haklar tanıyabilme ve düşürebilme, system kullanıcısının segmentlerindeki bilgileri toplama, görüntüleme gibi nice komutu yerine getirebiliriz.
Basit bir SQL yapısı ve sorgu örneği ise şu şekilde verilebilir:
SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
Yukarıdaki yapı, bir sql sorgusunda sırayla takip edilmesi gereken yapıdır. Bu yapıda select'in ardından gelecek bir group by veya havingden önce gelebilecek bir order by sorgunun hata vermesine ve çalışmamasına sebep olacaktır.
SELECT *
FROM DENEME;
Yukarıdaki sorguda istenilen şey, DENEME tablosundaki bütün kolonlardaki verilerin çekilmesi. Buradaki "*" bütün kolonları simgelemektedir. Yani, yukarıda belirttiğim veri tiplerinden tabloya işlenmiş olanları ve içlerinde barındırdığı verilerin tamamı demektir.
Eğer DENEME tablosunda 2 veri tipi kayıtlı ise örneğin, kullanici_adi varchar2(40) ve kullanici_soyadi varchar2(45), yukarıdaki sorguyu şu şekilde de yazabiliriz:
SELECT KULLANICI_ADI, KULLANICI_SOYADI
FROM DENEME;
Ya da,
SELECT D.*
FROM DENEME D;
Bu da, DENEME tablosuna D tagı ekliyoruz ve D'nin bütün verilerini çekmek istiyoruz demektir.
Sütünların hepsini çekebilidiğimiz gibi bir kısmınıda, belirtli koşullarla ve taglarla çekebiliriz. Örneğin;
SELECT KULLANICI_ADI AS AD, KULLANICI_SOYADI AS SOYAD
FROM DENEME;
Unutmayalım ki yukarıda kullandığım "AS" keyword'ü Oracle 9i ile birlikte depracate edilmiştir ve kullanılmamaktadır. Bunun yerine;
SELECT KULLANICI_ADI AD, KULLANICI_SOYADI SOYAD
FROM DENEME;
diyebiliyoruz. Bu şekilde yazılan bir sorgunun ekrana yansıması ise sütün adı olarak KULLANICI_ADI değilde, AD olması olacaktır.
SQL QUERYLERİ İLE VERİLERİN SINIRLANMASI
Bir select cümlesi ile bütün verileri almak istemiyorsak ve birtakım veriler arasından da bir gruplarını seçmek istiyorsak kullandığımız çok nitelikli ve bol miktarda fonksiyon ve grup fonksiyonları vardır.
Örneğin;
Bir tabloda eğer birden fazla grup_id'si bulunuyorsa ve biz sadece tekil olarak grup_idleri görmek istiyorsak DISTINCT kullanmalıyız.
SELECT DISTINCT GRUP_ID
FROM DENEME;
Distinct için unutulmaması gereken en önemli nokta ise, ardından gelen bütün sütünlar da distinct, yani tekil olacaktır. Yukarıdaki örnekte grup_id'nin yanına user_id'de ekleseydik, ikisinin birden tekil olacağı anlaşılacaktı.
Bir diğer veri sınırlandırma yöntemi ise WHERE koşuludur. Bu koşul ile tabloda bulunan verilerin içeriğine göre sorgular yazabilir ve görmek istediğimiz kadarını görmeyi başarabiliriz.
Örneğin;
SELECT KULLANICI_ADI AD, GRUP_ID ID
FROM DENEME
WHERE GRUP_ID IS NULL;
Deneme tablosundan kullanici_adini AD olarak ve grup_id'yi ID olarak çektiğimiz ancak grup_idlerinin NULL değer, yani değersiz, boş olduğu verileri bu şekilde alabiliriz. NULL demek sıfır demek değildir!..
Bundan sonraki konumuzda, Mantıksal operatörler olan AND, FALSE, NULL gibi konularla diğer sınırlandırma operatörlerini inceleyeceğiz.
İyi günler,
Ogan

1 Eylül 2008 Pazartesi

İlişkisel Veritabanı, Oracle ve SQL

ORACLE KURULUMU
Oracle veritabanının kurulumu ile yazılarımıza başlıyoruz. Yapılacak örnekler Oracle 10g üzerinde olacaktır ve Windows XP (32 bit) kullanılacaktır.

OTN (Oracle Technology Network) adresinden Win32 Database'i indirelim. Java tabanlı olan Oracle Universal Installer (OUI) başlatılmadan önce, bölgesel dil ayarlarımızın İngilizce'de olduğundan emin olalım. Türkçe olarak ayarlı ise kurulum sırasında problem yaşayabilirsiniz.

OUI çalıştırdıktan sonra Oracle kurulum dizinini seçiniz. Veritabanınız buraya kurulacaktır. Kurulum tipleri arasında Enterprise (bütün özellikleri), Standard (belirli bir kısmı kurulmaz) ve Personal (tek kullanıcı) vardır.

Install dedikten sonra ilk önce yazılımı, ardından veritabanını kuracaktır. Yükleme tamamlandıktan sonra Exit diyerek OUI'dan çıkıyoruz.

Oracle veritabanı 3 aşamada açılmaktadır. Bunlardan ilki "nomount" aşamasıdır. Bu aşamada veritabanı açılmaz, sadece init.ora dediğimiz Oracle'ın parametrelerinin bulunduğu dosya okunur. Startup nomount diyerek bu aşamaya geçebiliriz. Bir sonraki aşama olan "mount" aşamasına ise, alter database mount diyerek geçebiliriz. Eğer veritabanı kapalıyken "mount" aşamasına geçmek istersek, startup mount yazmamız gerekmektedir. Bütün startup komutlarının sonuna "quiet" yazarsak bize ilk açılıştaki SGA ve diğer birimlerin toplam boyutlarını göstermez. Sadece startup yazılırsa, veritabanı önce nomount aşamasına, ardından mount aşamasına ve son olarak open aşamasına geçecektir. Startup force yazılırsa, veritabanı açıksa shutdown abort ile kapatılır ve startup komutu verilir. Bu komutu veritabanını normal şekilde kapatamıyorsak kullanabiliriz.

Veritabanımızı açtık, şimdide kapatalım. Veritabanını kapatmak için uygulanan bir kaç değişik komut vardır. Bunlardan ilki shutdown ya da shutdown normal'dır. Bu kapatma yönetimde, bütün bağlı kullanıcıların sistemden çıkmaları beklenir. Bu işlem sürerken Oracle yeni kullanıcı kabul etmez. Shutdown immediate diyerek kapattıysak, Tüm kullanıcıların bağlantıları kesilir ve işlemi süren kullanıcılara rollback yapılır yani, commit işlemi yapılmamış bütün kayıtlar rollback edilir. Bu esnada yeni kullanıcı kabul edilmez ve veritabanı kapatılır. Shutdown transactional komutu işlenirse, kullanıcılardan commit (işlemlerini onaylamak için) ya da rollback (işlemlerini onaylamamak için) yazmaları beklenir. Bu sırada yine yeni kullanıcılara ve yeni işlemlere izin verilmez. Kullanıcılardan commit veya rollback komutu geldiğinde kullanıcılar atılır ve veritabanı kapanır. Shutdown abort ile ise, tüm tamamlanmamış işlemler geri alınır, yeni kullanıcılara izin verilmez ve bağlı olan bütün kullanıcılar derhal atılır. Ardından veritabanı direk kapatılır. Bu kapatılma tarzı çok önemli durumlar haricinde kullanılmamalıdır ve Oracle tekrar açıldığında SMON ve PMON gibi bir takım Oracle veritabanını ait background process'lerin recovery işlemini gerçekleştirmesi gerekir.

SQL (STRUCTURED QUERY LANGUAGE)
Bir veritabanına ait ve depolanmış olan verileri sorgulamamıza yarayan gerece SQL denir. SQL sorguları (query) ile veritabanımızdan istenilen düzeyde ve şekilde verileri ekranımıza getirebiliriz. SQL sorgularının içinde bir takım kategoriler bulunmaktadır. DDL (Data Definition Language) ve DML (Data Manipulation Language) dediğimiz kategorilere göre ayrılabilirler.
DDL: Create, Drop, Alter, Truncate, Grant, Revoke, Audit vs.
DML: Select, Update, Insert, Delete, Merge vs.
DDL komutları veritabanının şeklini ve genel yapısını değiştirdikleri için kullanıldıkları anda commit edilirler ve schemaya bağlı her kullanıcı (session) için geçerli kılınır. Ancak DML komutları sadece veri ile ilgili olduğu için kullanıldıkları anda commit edilmezler.
SQL sorgusuna bir örnek vermek gerekirse;
SQL> select * from employees; --> Employees tablosundaki bütün sütünlara ait verileri ekranımıza getirir. Buradaki "*" bütün anlamına gelmektedir ve bütün sütünları temsil etmektedir. Kaç tane olursa olsun. Bir başka şekilde yazma yöntemi ise;
SQL> select e.* from employees e; --> Employees tablosuna "e" ismini taktık ve e'nin bütün sütünları getirmesi için yine "*" işaretini kullandık.
Select sorguları ile verileri görebilir ve sınırlandırmalarını yardımcı komutları ile gerçekleştirebiliriz. Ancak şu aşamada sadece verilerinin tümünü çekebilmeyi gösteriyor olacağım.
SQL> desc employees; --> Employees tablosunu desc eder yani açıklar.
Bugünkü konularımız bu kadardır. Bir sonraki yazıda Oracle veri tiplerini ve aritmetik operatörleri işleyeceğiz. Buraya kadar biraz hızlandırılmış geçtim, kafanıza takılan sorular olursa lütfen e-posta gönderiniz.

İyi akşamlar ve Ramazan ayınız mübarek olsun.

22 Temmuz 2008 Salı

Oracle versiyon yükseltilmesi hakkında...

Merhaba,

Oracle versiyonunu yükseltirken en kritik noktalardan birisi belkide her sistemin en kritik varlığı olan "veri"nin taşınmasıdır. Gelin, en baştan başlayalım...

Diyelim veritabanınızın versiyonu 9i ve siz bu versiyonu 10g'ye yükseltmek istiyorsunuz. Peki ilk adım ne olmalı? İlk adım, sahip olduğunuz bütün verinin sağlam bir şekilde yedeğinin alınmasıdır. Bu verinin yediğini RMAN (Recovery Manager) ile almak istemek en doğal hakkınız. Zira incomplete recovery yapabilmeniz için de control file ve spfile yedeği RMAN ile alınabilmektedir. Ancak, burada çok kritik bir nokta vardır. O da RMAN'in sadece aynı Oracle versiyonlarında ve sadece aynı işletim sistemlerinde çalışabilmesi. RMAN'dan alınan yedek, ancak ve ancak belirttiğim sistemi sağlayabilirseniz ayağa kalkacaktır. Onun için de RMAN kullanımını gözden çıkarmalısınız.

Tabii Oracle'da çareler tükenmez. Elimizdeki bir diğer koz ise, "export/import" özelliğidir. Veritabanının "exp" ile komut satırındayken tam yedeğini alalım. Mutlaka hata oluşmadan aldığından emin olalım. Bu aşamada "yaşasın export aldım, hadi 10g'yi kuralım" deyip, hızlı bir adım atmayalım. Çünkü bu aşamadan sonra password file ile spfile'ı da mutlaka export ile birlikte bir yere kopyalayalım. Netice itibariyle, ayağa kalkacak olan veritabanı, halihazırda passwordfile ve spfile'ı aynı olacak bir veritabanı olacaktır.

Bu işlemleri de başarıyla tamamladıktan sonra, eğer aynı sunucuya Oracle kurulacaksa, temiz bir uninstallment aşaması bizi beklemektedir. İşletim sisteminiz Linux/Unix/Aix/Solaris vb. ise sıkıntı yaşamayacaksınız. Deinstall diyerek uninstall işlemini başarılı bir şekilde tamamlayabilirsiniz. Eğer işletim sisteminiz Windows ise -ki production serverlarda windows işletim sistemi kullanan varsa büyük bir alkış- işiniz birazcık daha zor. Deinstalldan sonra bir takım Oracle folderları kalmakta. Aynı zaman bir grup registry uzantıları da mevcut kalmaktadır. Onları tamamen silmezsek de bir sonraki sürüm yüklendiği zaman çakışmalar, çalışmamalar, install aşamasında hatalar, donmalar gibi bir takım acaip hata ile karşılaşabilirsiniz. Onun için nasıl verinin yedeğini alırken dikkatli davrandıysanız, deinstall aşamasında da son derece dikkatli olmalısınız. Zira, Oracle'da bir arıza oluştuğu zaman "Çözmek zor, format atın" şeklinde cevapları da veren Oracle yetkililerini, hocalarımızdan duyuyoruz. Deinstall gözünüzde büyümesin, başarmayı istemek, başarmanın yarısıdır ve kalan yarısıda bunu deneyebilmektir.

10g kurulumuna geçebiliriz. Bu noktadan sonra önümüzde temiz bir 10g kurulumu var. Bu konuda çok ciddi dökümanlara google'dan ulaşabilmek mümkün. Zira yine Linux türevi işletim sistemlerinde son derece kolay fakat belli trickleri olan bir kurulum ve Windows'da garip aşamalardan oluşan bir kurulum sizi beklemekte. Bu konuda çok fazla detaya girmek istemiyorum çünkü google sizi son derece iyi bir şekilde yönlendirecektir.

En önemli noktadayız. Verinin, taze yüklenmiş olan 10g sürümüne yüklenmesi. Export ile aldığımız backup'ı, import ile veritabanına geçirmeden önce, 9i'deki passwordfile ve spfile'ı veritabanı tamamen kapalı iken yapıştıralım. Ardından veritabanımızı yine açmadan önce import işlemini komut satırından "imp" komutu ile gerçekleştirelim. Yalnız passwordfile geçerli olduktan sonra export'u hangi yetkili user ile aldıysak, aynı user ile import edelim. Yoksa bir Oracle hatası alırsınız.

Bu işlemin arkasında yatan en büyük temel mantık, export ile import işlemidir. Bu işlemlerin düzgün yapıldığı takdirde sürüm yükseltilmesinin hiçbir zor tarafı mevcut değildir. Yalnız dikkatli adım atılmalı ve temel noktalar gözden kaçmamalıdır. Unutmadan, 10g'de sağlıklı bir veritabanı kurduğunuzu gördüğünüz anda, mutlaka RMAN ile hot backup alın ve RMAN ayarlarına mutlaka dikkat ederek yapın, bu işlemi (Controlfile ve spfile ayarları).

İyi çalışmalar.


Ogan

3 Temmuz 2008 Perşembe

Oracle Profiles

Uzun bir aradan sonra tekrar merhaba,


Bugün, aslında hepimizin çok detaylı bilmesi gerektiği bir konuyu ele almak istedim. Oracle Profilleri. Peki Profil nedir?
Bağlı bütün kullanıcıları yaratırken, öncelikle bir profile belirleriz. Eğer, kullanıcı yaratırken belirtmezsek default profile ile yaratılacaktır. Tabii ki bu şekilde bir sistem oluşturmak son derece sakıncalı olabilmektedir. Profillerin içinde barındırdığı özellikleri sayesinde çoğu zaman oluşabilecek güvenlik açıklarından kurtulabilmekteyiz.
En çok kullanılan kaynakları ise;
CONNECT_TIME : Dakika bazında, sessionlar için kabul edilen bağlantı zamanını düzenler.
alter profile limit connect_time 300;
*** Burada belirtmeliyim ki, profile'a ait bir kaynağı değiştirirken mutlaka "limit" kullanılması gerekmektedir. Sık sık unuttuğum için belirtmem de fayda var :)
IDLE_TIME : En kritiklerinden birisi de idle_time'dır. Adından da anlaşılabileceği gibi, herhangi bir schemaya bağlı bir session'ın hiçbir DML/DDL komutu kullanmadan beklediği süreye denir. Eğer kullanıcı bu süreyi aşarsa, session'ı Oracle tarafından öldürülür. Yine dakika bazında değer verilebilmektedir.
alter profile limit idle_time 10;
SESSIONS_PER_USER : Bir kullanıcı için kabul edilebilen toplam session sayısıdır. Bir schemaya tanımladığımız kullanıcı, eğer bu değeri 2 olarak belirlersek en fazla 2 session yaratabilir. Yani 1 schema'da 1 kullanıcıya ait toplam 2 session açılabilir.
alter profile limit sessions_per_user 2; --> Default olarak unlimited seçilir.
FAILED_LOGIN_ATTEMPTS : Güvenlik açısından kritik bir kaynaktır. Bu değeri eğer belirlemezsek, bağlanmak isteyen kullanıcılar sürekli deneme yanılma yöntemi uygulayabilirler.
alter profile limit failed_login_attempts 4; --> 4 denemeden sonra kullanıcının hesabı kilitlenecektir.

Eğer yeni bir profil yaratmak istersek;
Create profile deneme LIMIT
failed_login_attempts 4
sessions_per_user 14
private_sga 400K
logical_reads_per_call 900;

Veritabanı yöneticisi olarak, default profile kullanmaktansa, her kullanıcıya ait, özel isimler altında profiller yaratmak çok daha sağlıklı olacaktır. Bu kaynakların komutlarının düzgün ayarlanması halinde, içerideki ve dışarıdaki tehlikelere karşı sistem bir nebze olsa korunacaktır.

İyi çalışmalar.

Ogan

17 Mart 2008 Pazartesi

SQL NEDİR ?

Merhaba,

RDBMS (Relational DataBase Management Systems), yani "İlişkisel veritabanı yönetim sistemleri"'nin temeli 1980'li yıllarda atılmıştır. IBM tarafından Oracle tarafında geçen ve 2003 yılında vefat eden Dr. Edgar J. Codd bu temelin atılmasında çok büyük rol oynamıştır.

İlişkisel veritabanının mantığı veriye daha hızlı ve sağlam ulaşmaktan geçer, diyebiliriz. Veri modelleri arasındaki bağlar birbirleri ile ilişkilendirildiği zaman mantıklı ve stabil sonuçlar elde edildiği anlaşılmıştır.

Bu andan itibaren SQL (Structured Query Language)'in önemi o yıllardan başlayarak hızlı bir şekilde artmıştır. Devamında gelen PL/SQL (Procedural Language) ile de günlük veritabanı yönetimi işlemlerimiz için de bir dönüm noktası olmuştur.

Aslında bu yazımda SQL'den bahsetmek istiyorum. SQL'i nerelerde, neden, ne zaman ve ne için kullanıyoruz ona bakalım.

SQL sorgularını, ilişkisel veritabanına ait tablolardaki verileri çekmek ve görüntülemek için kullanabiliriz. Bu verileri, birbirine bağlı olan tablolarla birleştirip farklı sonuçlar görmeyi sağlayabiliriz. Bu sonuçları bi view'da tutup, her seferinde uzun sorgular yazmak yerine o view'u sorgulayarak ulaşabiliriz.

Tablolar, sequenceler, synonymler, viewlar vb. objeler yaratmak için SQL kullanırız. Kullanıcı yaratmak, haklar dağıtmak, dağıtılan hakları geri almak ve kullanıcıları düşürmek için de kullanırız.

Başka veritabanlarında kendi veritabanımıza bağlı iken sorgular çalıştırabilir, gerekli yetkilerimiz varsa bu yetkiler doğrultusunda veritabanının yapısını değiştirebiliriz.

Veritabanının memory parametrelerini değiştirebilir, daha hızlı ve performanslı çalışmasını sağlayabiliriz.

Veritabanının yedeğini alabilir, aldığımız yedekten dönebilir ve veritabanını kapatıp, açabiliriz.

Oracle veritabanında kayıtlı olan paketlerden özel fonksiyonları kullarak hesaplama işlemlerimiz yapabiliriz. X$ tablolarından alınan V$ view'ları ile de veritabanının monitör edilmesinde kritik rol oynayan verileri görebilir, değiştirebiliriz.

Velhasıl, Oracle'ın kurulum anından, kaldırdığımız ana kadar SQL ile her işimizi belirli düzeylerde görebiliriz. Çok daha ileri durumlarda, mesela veritabanına giren kullanıcıların takip edilmesi gibi, PL/SQL'e başvurabiliriz. O kademede ise işlerimiz çok daha rahat olacaktır, PL/SQL ile.

ANSI standartlarının belirlediği SQL sorguları, günümüzde bütün ilişkisel veritabanlarında desteklenmektedir. Oracle'a ait bazı sorgu çeşitleri vardır ve sadece Oracle veritabanlarında kullanılabilir. Aslında ANSI standarları uyarınca bilinen SQL her veritabanında hayat kurtarabilir.

Oracle veritabanı SQL'in olduğu yerde başlar ve olmadığı yerde biter. SQL sorgularının çalıştırılmadığı bir veritabanı olamaz, düşünülemez.

İyi çalışmalar.

Ogan

ORACLE - ORA HATALARI

Merhaba,


Oracle veritabanını yönetirken, yedeğini alırken, performansını ayarlarken veya sql-pl/sql sorguları hazırlarken hepimizin, yaptığımız hatalardan dolayı aldığımız hatalar ORA- ile başlar ve hatanın algılanması için son derece kritiktir.


Destek verdiğiniz kurum, şahıs veya kuruluşta Oracle konusunda hatalar oluşuyorsa, bunu çözmenin en mantıklı yolu ORA hatasına bakmaktadır. İkinci olaraksa alert.log'a bakılabilir.


Sıklıkla karşılaştığımız ORA hatalarını kısaca şu şekilde özetleyebiliriz;


ORA-06550 : PL/SQL kodu compile edilirken oluşan hatalardır. (PL/SQL compilation error)
ORA-00936 : Sorgumuzda atlanan veya unutulan bir bölüm olduğu zaman oluşan hatalardır. (missing expression)
ORA-01034 : Oracle veritabanı açık değildir. (ORACLE not avaliable)
ORA-01033 : Oracle kapatılma sürecindeyken log on olduğumuz durumlarda oluşan hatalardır. (ORACLE initialization or shutdown in progress)
ORA-01555 : Üzerine veri kaydedilmiş rollback kayıtları olduğu zaman oluşan hatalardır. (snapshot too old)
ORA-01017 : Kullanıcı adı veya parolayı yanlış girdiğimiz durumlarda aldığımız hatalardır. (invalid username/password; logon denied)
ORA-00932 : Veri tipleri (data type) uyuşmadığında aldığımız hatalardır. (inconsistent datatypes)


Oracle'da sık sık aldığımız hataların başında gelen bu hatalar, hata kodunu bildiğimiz durumlarda aslında çok kolaylıkla kurtulabileceğimiz ve düzeltebileceğimiz hatalardır. Hata kodunu bildiğimiz durumlarda müdahale etmemiz ne kadar kolaysa, bilmediğimiz durumlarda da yorum yapıp, müdahale etmemiz o kadar zordur!


ORA-00600 hataları, Oracle Yazılımının kernel kodundan kaynaklanan hatalardır. Bu problem ile karşı karşıya kaldığımız anlarda müdahale şansımız düşüktür ve bu hataların ürettiği logları alert.log larda bulabiliriz.
Bu hatalar beraberinde bir takım argümanları da getirmektedir.
Örneğin;
ORA-00600 [400][520][11][900][][]
Bu hatalara sadece Oracle hata analizcileri müdahale edebilir. Ayrıca, bu argümanların içerisindeki değerler versiyondan versiyona değişebildiği için, son kullanıcılara veya DBA'lere ezberlemeleri tavsiye edilmez. Daha detaylı bilgi için yazdığım bir başka yazıya tıklayınız.


Oracle konusunda eğer bir hatayı çözmek istersek, o hatanın en derinine inmemiz gerekir. Asıl sebep ile gerçek sonuca ulaşabilmek şüphesiz çok hızlı gerçekleşecektir. Onun dışında deneme-yanılma yöntemleri veya içgüdüsel duygularla yapacağımız işin sonucu pek de hayırlı olmayacaktır.


İyi çalışmalar.


Ogan

12 Mart 2008 Çarşamba

BLOCK CHANGE TRACKING

Merhaba,

Bu yazımda Oracle Database 10g'ye özel bir özellik olan ve RMAN ile incremental backuplarımızı çok kritik ölçülerde hızlandırabilen "BLOCK CHANGE TRACKING"den bahsedeceğim.

Bu tarz bir hız artışına neden ve hangi durumlarda ihtiyacımız olabilir?

1) Veritabanımız ciddi boyutlarda ve adette verileri barındırıyorsa, yedekleme işlemi saatlerce sürebilir.
2) Gelişen ve hızla büyüyen ülkemizde ve dünyada artık zamanın çok kritik olduğu.
3) Incremental backup ile geliştirilmiş bir yedekleme stratejisi oluşturmuşsak.

Yeni ve sıklıkla kullanılan bir özellik olan Block Change Tracking, özel bir dosyada (bizim enable ederken belirlediğimiz), veritabanı bloklarını flag ile tutar.
Bu özelliği aktif hale getirebilmek için ise;
SQL> ALTER DATABASE ENABLE BLOCK CHANGE TRACKING USING FILE '/ORACLE/ADMIN/TRIAL/BLOCKTRACK.DBF';

Bu komutun ardından, veritabanında değişen bütün blocklar bu özel dosyada değişiklikleri ile tutulur. RMAN ile incremental backup alınırken, RMAN bu dosyayı kontrol eder ve blockların üzerindeki değişiklikleri algılar. Bu işlem, backup sırasında, ciddi boyutlarda CPU ve zaman kazançları sağlayabilir.
Block change tracking aktif iken RMAN ile herhangi bir işlem veya komut gerçekleştirmeden bu uygulamadan yararlanabiliyoruz.
Hızla büyüyen ve çok büyük boyutlarda veritabanlarında incremental backup alınırken bu komutu mutlaka aktif hale getirmeliyiz de denebilir. Bu özellik sayesinde, aynı zaman da çok ciddi zaman ve para kaybı da engellenmiş olacaktır.
V$BLOCK_CHANGE_TRACKING view'u, bizim bu özellliği en son hangi duruma ayarladığımızı ve hangi dosyaya kaydedildiğini gösterir.
SQL> ALTER DATABASE RENAME FILE '/ORACLE/ADMIN/TRIAL/BLOCKTRACK.DBF' TO '/ORACLE/ADMIN/BLOCK.DBF';
Bu komut ile özel dosyamızın adını değiştirebilir (mount modunda) ya da
SQL> ALTER DATABASE DISABLE BLOCK CHANGE TRACKING;
ile bu özellikten yararlanmaktan vazgeçebiliriz.
Bu özellik daha önce enable edilmiş ve ardından disable edilmişse, disable komutundan enable komutuna aynı özel dosya ile geçiriyorsak, bütün değişiklikler silinir ve bilgiler baştan toplanır.

İyi çalışmalar.

Ogan

21 Şubat 2008 Perşembe

STARTUP ve SHUTDOWN

Merhaba,

Bu yazımda Oracle'ın nasıl kapatılıp açılması gerektiğinden biraz bahsedeceğim. Hazır yeri gelmiş iken, ben yazılarımda Oracle'a tamamen uzak olan insanların da anlayabileceği türden yazmaya çalışıyorum. Daha da sığ olarak anlatmamı isteyenler mail atabilirler. Genelde koddan biraz uzak durmaya çalışmaktayım.

Öncelikli olarak, STARTUP ile başlayalım. Startup, Oracle'da "Instance"ı ve veritabanını açmaya yarayan komuttur. Çeşitli durumlarda ve şekillerde instance'ın öncelikli olarak açılabilmesi için sonuna ek komutlar alabilir.
Başlamadan küçük bir hatırlatma. "select open_mode from v$database" dersek veritabanının hangi aşamada açıldığını görebiliriz.

Kapalı durumda olan veritabanına bir SYSDBA kullanıcısı ile bağlanalım.
C:\> SQLPLUS / AS SYSDBA
Connected to an idle instance.
SQL> STARTUP; --> Şuan veritabanı öncelikle "NOMOUNT" moduna geçer. Ardından MOUNT ve son olarak OPEN.
STARTUP'dan sonra gelen prefixleri sonra detaylı olarak inceleyeceğiz.

NOMOUNT AŞAMASI: Oracle giriş parametre dosyasını okuyor (INITORA, SPFILE). Veritabanının hangi parametrelerle ve boyutlarla açılmasını gerektiğini algılar. Bu durumda Oracle Background Process'leri de çalıştırılır.
Bu kısmı "STARTUP QUIET" diyerek görmeden geçebiliriz.
SQL> STARTUP NOMOUNT QUIET;
ORACLE instance started.
Veritabanımız şuan da nomount modunda bekliyor. Henüz veritabanını açmadık.

MOUNT AŞAMASI: Veritabanı bu aşamada Control dosyalarını okur. Bu dosyalardan, datafile gibi kritik dosyaların yerlerini algılar fakat henüz açmaz. Bu yerlerin algılanmasıda tamamlandıktan sonra artık veritabanımız BG Process'leri ve Control dosyaları ile açılmaya hazırdır.
SQL> ALTER DATABASE MOUNT; -VEYA- STARTUP MOUNT; --> Veritabanımız nomount aşamasında ise ilkini, değilse ikincisini yazabiliriz.
Database mounted.

OPEN AŞAMASI: Şuan veritabanı datafile'lara girişini yaptı ve kullanıma hazır hale getirdi. Kullanıcılar bağlanabilir durumda.
SQL> ALTER DATABASE OPEN; -VEYA- STARTUP; --> Veritabanımız mount aşamasında ise ilkini, değilse ikincisini yazabiliriz.
Database opened.

Özetlemek gerekirse;

1) STARTUP; --> Önce nomount sonra mount ve son olarak open aşamalarını veritabanını taşır (eğer herhangi bir sorun ile karşılaşılmazsa).
2) STARTUP NOMOUNT; --> Veritabanını nomount aşamasına getirir.
MOUNT; --> Veritabanını mount aşamasına alır.
(Default)OPEN; --> 1'inci durum ile aynıdır.

Bunlara ek olarak ise;

1) STARTUP [MOUNT/NOMOUNT/OPEN] RESTRICT; --> Veritabanını restricted modda açmamıza yarar. Yetkili kullanıcılar dışında hiçbir kullanıcı bağlamaz. RESTRICTED SESSION yetkisi olanlar bağlanabilir. Açık veritabanında ise restricted session'ı şu şekilde açıp kapatabiliriz.
SQL> ALTER DATABASE ENABLE RESTRICTED SESSION;
SQL> ALTER DATABASE DISABLE RESTRICTED SESSION;
2) STARTUP [MOUNT/NOMOUNT/OPEN] FORCE; --> Veritabanını "SHUTDOWN ABORT" yaparak kapatır, istenilen şekilde açar. Bu şekilde açılan veritabanının herhangi bir başlangıç paramatresi olmasına gerek yoktur.
3) STARTUP [MOUNT/NOMOUNT/OPEN] EXCLUSIVE; --> Öncelikle belirtelim, startup mount exclusive deprecated edildi ve desteklenmiyor. Bu komut ise veritabanının sadece bu session tarafından mount veya open edilebileceğini gösterir.

Sırada SHUTDOWN komutları var. Detaylı olarak inceleyelim.

C:\> SQLPLUS / AS SYSDBA
Connected to:Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - ProductionWith the Partitioning, OLAP and Data Mining options

Şuan da bağlıyız. Yapabileceğimiz SHUTDOWN olanakları şunlardır;

1) SHUTDOWN [NORMAL]; --> Veritabanını "temiz" şekilde kapatır. Bütün kullanıcıların bağlı oldukları sessionlardan çıkmalarını bekler. Ardından instance'ı ve veritabanını güvenli bir şekilde kapatır. Bu sırada buffer_cache'de yazılmayı bekleyen dirty buffer'lar datafile'lara yazılır. Temiz olarak veritabanını kapatılır. Genelde kullanılmayan bir kapatma metodudur. Yeni kullanıcı kabul edilmez.
2) SHUTDOWN IMMEDIATE; --> Veritabanına bağlı olan bütün kullanıcıları atar ve commit edilmemiş işlemleri rollback yapar. Yeni kullanıcıların girmesini engeller. Shutdown normal'de olduğu gibi datafile'lara veriler yazılır. Veritabanı güvenle ve temiz olarak kapatılır.
3) SHUTDOWN ABORT; --> Veritabanını kapatmanın en hızlı ve aynı zamanda veritabanı için en zor yoludur. Veritabanı anında kapatılır ve bütün işlemler sonra ki Startup'ı bekler. Aslında bu kapatma türü Oracle'ı fazla etkilemez. Bu yöntem kesinkle ilk olarak kullanılacak yöntem olmamalıdır. Temiz bir kapatma metodu Oracle'da önemli rol oynar.
4) SHUTDOWN TRANSACTIONAL; --> Bu kapatma yöntemi ise bazı durumlar çok kritik olarak kullanılabilir. Önemli bir işlem yapılırken girilecek bir shutdown immediate komutu update veya insert yapan kişinin bütün işlemlerini rollback edebilir. Eğer tek kullanıcı ile çalışıyorsak ve işlemini bitirmesini bekliyorsak bu kapatma yöntemini uygulamalıyız. Kullanıcılar COMMIT ettikleri zaman veritabanından atılırlar ve temiz kapatma gerçekleşir. Commit edilmeyen sessionları bekleriz, bu komut ile. Yeni kullanıcılar kabul edilmez.

Genel olarak Oracle veritabanını bu komutlar ile kapatıp açabiliriz. Bu seçimleri yapmak tamamen DBA'in sorumluluğundadır. Hangi durumda hangi metodun kullanılacağına iyi karar vermek gerekebilir.

İyi çalışmalar,

Ogan
Takip et: @oganozdogan