31 Ocak 2012 Salı

RMAN ile yedek almak.



RMAN ' de Backup çeşitleri aşağıda verilmiştir.

Whole Backup:Tüm veri tabanı objelerinin yedeğinin alınmasıdır.

Full Backup:
Tüm data blokların yedeğinin alınması işlemidir

Partial Backup:  database objelerinin yedeğinin alınmasıdır. Örnek olarak controlfile yedeğinin alınmasıdır yada datafile 4' ün yedeğinin alınması gibi.


Incremental Backup:
Incremental backup,  en son alınan full backup tan sonra  sadece modifiye uğramış olan blokların backup alınma işlemdir.Incremental level 0 ve Incremantal level 1 olarak iki çeşittir.Incremantal Level 0 tüm database yedeğini alır. Incremental Level 1 ise differential ve cumulative olarak ikiye ayrılır.
 Incremental Cumulative  Backup bir full backup ' tan sonra değişen blokların yedeğini alır. Aşağıda Kümülatif(Cumulative) yedek stratejisini açıklayan bir resim bulunmaktadır.





Incremental Differential backup ise her yedekte sadece bir öncesindeki differential backuptan sonraki değişen blokları yedekler. Aşağıda Incremental Differantial backup ile ilgili resim örneği verilmiştir.


Önce bir Full backup alınır. Ve sonraki günlerde differantial backup alınabilir.
 Kurtarma senaryolarında Önce Full backup daha sonra ise bu incremental backupların uygulanması gerekmektedir.
Not: NoArchivelog modunda database mount duruma getirilir. Ve böylece Incremental yedek alınır. Database çalışır durumunda ıncremental backup alınırsa veri kaybı söz konusudur. Çünkü Online Redo Log dosyaları arşivlenmeyeceğinden dolayı veri kaybolur.




Cold Backup, Consistent backup' tır.Database kapalı iken gerçekleşen backup' tır. Böylece Controlfile deki SCN bilgis ile datafile header' daki SCN bilgisi tutarlıdır. Sağlıklı bir backup türüdür.

Hot Backup,  inconsistent Backup' tır. Yani database açıkken alınan backup' tır. Bunun anlamı Controlfile 'deki SCN ile Datafile header' lardaki SCN bilgisi tutarsız kalabilir. kalması durumunda kurtarma işlemi söz konusudur.


ORACLE_SID aşağıdaki gibi  environment ortamına XDB isminde bir  database olarak set edilir.

yada
 oracle@mhm ~]$ export ORACLE_SID=XDB
oracle@mhm ~]$ . oraenv
ORACLE_SID = [orcl] ? XDB
The Oracle base for ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1 is /u01/app/oracle

Şimdi Recovery Manager' a bağlanalım. Katalog database kullanmak istediğimde ise aşağıdaki komutta ilave  olarak ekleme yapabilirdik. Ama biz şuan ki controlfile bilgisi dahilinde çalışacağız.

oracle@mhm ~]$ . rman target /

Recovery Manager: Release 11.2.0.1.0 - Production on Tue Jan 31 09:52:02 2012
Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.
connected to target database: XDB (DBID=3401130493)


veritabanımıza ait tablepace ve onlara ait olan datafile bilgilerini RMAN de aşağıdaki komutla öğrenebiliriz.

 RMAN> report schema;

using target database control file instead of recovery catalog
Report of database schema for database with db_unique_name XDB

List of Permanent Datafiles
===========================
File Size(MB) Tablespace           RB segs Datafile Name
---- -------- -------------------- ------- ------------------------
1    680      SYSTEM               ***     +XDATA/xdb/datafile/system.256.751571183
2    500      SYSAUX               ***     +XDATA/xdb/datafile/sysaux.257.751571183
3    50       UNDOTBS1             ***     +XDATA/xdb/datafile/undotbs1.258.751571183
4    5        USERS                ***     +XDATA/xdb/datafile/users.259.751571183
List of Temporary Files
=======================
File Size(MB) Tablespace           Maxsize(MB) Tempfile Name
---- -------- -------------------- ----------- --------------------
1    20       TEMP                 32767       +XDATA/xdb/tempfile/temp.264.751571629

Rman configrasyonu için kontrol ediyorum. Konfigrasyon için aşağıdaki komutu giriyorum.

RMAN> show all;

RMAN configuration parameters for database with db_unique_name XDB are:
CONFIGURE RETENTION POLICY TO REDUNDANCY 1; # default
CONFIGURE BACKUP OPTIMIZATION OFF; # default
CONFIGURE DEFAULT DEVICE TYPE TO DISK; # default
CONFIGURE CONTROLFILE AUTOBACKUP OFF; # default
CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '%F'; # default
CONFIGURE DEVICE TYPE DISK PARALLELISM 1 BACKUP TYPE TO BACKUPSET; # default
CONFIGURE DATAFILE BACKUP COPIES FOR DEVICE TYPE DISK TO 1; # default
CONFIGURE ARCHIVELOG BACKUP COPIES FOR DEVICE TYPE DISK TO 1; # default
CONFIGURE MAXSETSIZE TO UNLIMITED; # default
CONFIGURE ENCRYPTION FOR DATABASE OFF; # default
CONFIGURE ENCRYPTION ALGORITHM 'AES128'; # default
CONFIGURE COMPRESSION ALGORITHM 'BASIC' AS OF RELEASE 'DEFAULT' OPTIMIZE FOR LOAD TRUE ; # default
CONFIGURE ARCHIVELOG DELETION POLICY TO NONE; # default
CONFIGURE SNAPSHOT CONTROLFILE NAME TO '/u01/app/oracle/product/11.2.0/dbhome_1/dbs/snapcf_XDB.f'; # default

Her backup ta controlfile ve spfile  dosyalarının otamatik olarak yedeğinin alınmasını istediğimden aşağıdaki komutu on yapıyorum.

RMAN> configure controlfile autobackup on;

new RMAN configuration parameters:
CONFIGURE CONTROLFILE AUTOBACKUP ON;
new RMAN configuration parameters are successfully stored


Eğer backup ' alınmış dosyaların tekrardan backup'ını almak istemiyorsak;

RMAN>CONFIGURE BACKUP OPTIMIZATION ON;





Örnek olarak System tablespace' ine ait datafile olan system.256.751571183 dosyasının yedeğini alalım.
Normalde alınan backuplar eğer biir yer belirtmemişsek database kurulurken belirttiğiniz Flash  yada Fast Recovery Area ( FRA ) olarak adlandırılan alan kaydedilir. Ben bu alan için ASM  diskgroupları içinde XFRA isimli diskgroubunu tercih etmişttim.


Partial Backup:

RMAN> backup datafile 1;


 yada 


RMAN> backup datafile 'system.256.751571183';


Starting backup at 31-JAN-12
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=38 device type=DISK
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00001 name=+XDATA/xdb/datafile/system.256.751571183
channel ORA_DISK_1: starting piece 1 at 31-JAN-12
channel ORA_DISK_1: finished piece 1 at 31-JAN-12
piece handle=+XFRA/xdb/backupset/2012_01_31/nnndf0_tag20120131t100240_0.263.774007363 tag=TAG20120131T100240 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:01:49
Finished backup at 31-JAN-12

Starting Control File and SPFILE Autobackup at 31-JAN-12
piece handle=+XFRA/xdb/autobackup/2012_01_31/s_774007471.264.774007475 comment=NONE
Finished Control File and SPFILE Autobackup at 31-JAN-12

Whole database:
RMAN> backup database plus archivelog all format '%U';


Full Backup Örneği:
RMAN> backup database format '%U';


yada Backup setler şeklinde backup oluşturmek için;


RMAN> backup as backupset database format '%U'; 


yada


image copy şeklinde yedek oluşturmak içinse;


RMAN> backup  as copy database format '%U'; 

yada  incremental  level 0  şeklinde de full yedek alınabilir.

RMAN> backup incremental level  0 database format '%U';



Starting backup at 31-JAN-12
using channel ORA_DISK_1
channel ORA_DISK_1: starting incremental level 0 datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00001 name=+XDATA/xdb/datafile/system.256.751571183
input datafile file number=00002 name=+XDATA/xdb/datafile/sysaux.257.751571183
input datafile file number=00003 name=+XDATA/xdb/datafile/undotbs1.258.751571183
input datafile file number=00004 name=+XDATA/xdb/datafile/users.259.751571183
channel ORA_DISK_1: starting piece 1 at 31-JAN-12
channel ORA_DISK_1: finished piece 1 at 31-JAN-12
piece handle=/u01/app/oracle/product/11.2.0/dbhome_1/dbs/08n24r8b_1_1 tag=TAG20120131T101434 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:03:50
Finished backup at 31-JAN-12

Starting Control File and SPFILE Autobackup at 31-JAN-12
piece handle=+XFRA/xdb/autobackup/2012_01_31/s_774008306.265.774008309 comment=NONE
Finished Control File and SPFILE Autobackup at 31-JAN-12




RMAN> backup incremental level 1 cumulative database format '%U';


Yukarıdaki komutlar Incremental Cumulative backup alır.

Aşağıdaki komut ise Incremental  Differential backup almak için kullanılır.

RMAN> backup incremental level 1 database format '%U';


Image copy olarak alınan backupların avantajı geriye dönük kurtarmalar için copy' in restore edilmesi süreci çok hızlı gerçekleşmesi  bir diğer avantajı ise veritabanında image copy olarak yedeği alınan datafile'lerin bu kopyaya switch edilmesidir.Switch işlemi  bundan sonra datafile orjinalinde değil copyası üzerinde bir başka yerde çalışacaktır şeklindeki bilgiyi Controlfile 'a bildirme işlemidir.Dezavantajı ise boş- dolu farketmez tüm data bloklarının yedeğini alacağı için Kopyanın çok alan kaplamasıdır.

Backup Set ler ise boş data bloklarının yedeği alınmaz.  Binary dosyalar şeklinde oluşturulur.Böylelikle sadece dolu olan blokların yedeği alınmış ve alandan tasarruf edilmiş olur. Ayrıca Backup Setler 11g ile gelen br özellikle yaklaşık %20 civarında sıkıştırılma yapılabilir.   Datafile 5' in sıkıştırılmış yedeğini almak için aşağıdaki komut kullanılır.

RMAN> backup as compressed backupset datafile 5 ;


Squence nosu (sırası ile) 13 -16 arasındaki archivelogların yedeğini almak için ise;

RMAN> backup archivelog sequence between 13 and 16;

Starting backup at 31-JAN-12
using channel ORA_DISK_1
channel ORA_DISK_1: starting archived log backup set
channel ORA_DISK_1: specifying archived log(s) in backup set
input archived log thread=1 sequence=13 RECID=12 STAMP=774008535
input archived log thread=1 sequence=14 RECID=13 STAMP=774008914
input archived log thread=1 sequence=15 RECID=14 STAMP=774008917
input archived log thread=1 sequence=16 RECID=15 STAMP=774008919
channel ORA_DISK_1: starting piece 1 at 31-JAN-12
channel ORA_DISK_1: finished piece 1 at 31-JAN-12
piece handle=+XFRA/xdb/backupset/2012_01_31/annnf0_tag20120131t103219_0.259.774009141 tag=TAG20120131T103219 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
Finished backup at 31-JAN-12

Starting Control File and SPFILE Autobackup at 31-JAN-12
piece handle=+XFRA/xdb/autobackup/2012_01_31/s_774009141.258.774009143 comment=NONE
Finished Control File and SPFILE Autobackup at 31-JAN-12


Rman ile Yedek almak avantajlıdır. Recovery (kurtarma) sürecinde geriye dönük kurtarmalarda yada felaket senaryolarında Rman ile alınmış bir backup 'ı restore edip sonra archive log ları uygulama (Recover) işi çok hızlı ve kolaydır. veri kaybını minimize eder.

24 Ocak 2012 Salı

Export ve datapump Araçları ile Yedek almak

Yedek alma işi çok değişik yöntemlerle yapılabilir.
En klasik yöntem olarak, işletim sistemi komutlarıyla önemli veritabanı dosyalarının fiziksel olarak kopyalanıp yedeklenmesi
Mantıksal olarak Export aracı ile yedek almak;
Datapump(expdp) aracı ile yedek almak;
RMAN ile yedek alınarak veritabanının sürekliliği sağlanmış olur.

Veritabanı için olmazsa olmaz üç tip dosya vardır.

Kontrol dosyaları(control file), veritabanı için önemli sayılan dosyalar ve onların path’leri, veritabanının yedek bilgisi, varsa bir standby veritabanı bilgisi gibi önemli bir çok bilginin kayıtlı olduğu kütük dosyasıdır. Çok önemli bir dosyadır. Default olarak 2 adettir. Fakat çoğaltılması isteğe bağlıdır. Yedeklerinde de aynı bilgiler mevcuttur. Bir controlfile kaybolur yada silinirse bu yedekler devreye sokulur. Bu dosya olmazda veritabanı çalışması durur ve açılmaz. Çözüm ise En güncel controlfile devreye sokulmasıdır yada yedeği alınmış controlfile ‘den yedekten dönülmesidir.

Veri dosyaları(data file), verilerin kaydedildiği dosyalardır. Önemli dosyalardır. Eksikliği yada silinmesi durumunda veri tabanını açılmaz. Yedek ihtiyacı hissedilir. Çözüm ise yedekten geri dönme ile sağlanılır.

Online Redo Log dosyaları, veritabanında yapılan tüm transactionların (değişikliklerin) kaydedildiği log dosyalarıdır. Bu log dosyaları default 3 group’tur. İsteğe görede çoğaltılabilir. Yada grouplara yeni üye log file’ lar eklenebilir. Ve doldur boşalt(switch) sistemiyle çalışan log mekanizmalarıdır. Eğer biz Veritabanı için Archivelog moduna alırsak, bu log dosyaları geriye dönük kurtarmalar(Recovery) için arşivlenir. Aksi halde yani veritabanı Noarchivelog modunda ise bu log dosyaları dolduktan sonra içeriği boşaltılıp tekrar loglanmaya hazır hale gelecektir. Veritabanı için önemli dosyalardır. Kaybı olması durumunda veritabanı sistemi logların mod yapısına göre değişiklik gösterilecektir.
Yukarıdaki üç dosya tipi veri tabanı için hayati dosyalardır. Bu dosyalar veri tabanın açılış safhasında önce parameter file, sonra controlfile okunarak veritabanı mount moduna getirilebilir. Daha sonra ise open moduna gelebilmesi içinde datafile ve online redo log dosyaları okunur. Controlfile okunarak içerisindeki yazılan datafile ve online redo log file eksiksiz ve tutarlı hale gelmiş ise sistem open moduna gelip hizmet vermeye başlayacaktır. O yüzden aşağıdaki dynamic performans view larini kullanarak bu dosyların yerlerini öğrenip bu dosyaların yedeğini almak istiyorum.

SQL> select name from v$controlfile union
2 select name from v$datafile union
3 select member from v$logfile;
NAME
--------------------------------------------------------------------
+DATA/mytablespace Veridosyası
+DATA/myundo Veridosyası
+DATA/neworcl/datafile/example.265.745007059 Veridosyası
+DATA/neworcl/datafile/sysaux.257.745006719 Veridosyası
+DATA/neworcl/datafile/system.256.756697091 Veridosyası
+DATA/neworcl/datafile/test.269.745702809 Veridosyası
+DATA/neworcl/datafile/undotbs1.258.745006721 Veridosyası
+DATA/neworcl/datafile/users.259.745006721 Veridosyası
+DATA/neworcl/onlinelog/group_1.261.765328145 Redo Log dosyası 1
+DATA/neworcl/onlinelog/group_2.262.765328167 Redo Log dosyası 2
+DATA/neworcl/onlinelog/group_3.263.765328189 Redo Log dosyası 3
+DATA/neworcl/onlinelog/group_4.273.765328207 Redo Log dosyası 4
+DATA/neworcl/controlfile/current.260.745007003 Kontrol Dosyası1
+FRA/neworcl/onlinelog/group_1.257.765328155 Redo Log dosyası 1 yed.
+FRA/neworcl/onlinelog/group_2.258.765328177 Redo Log dosyası 2 yed.
+FRA/neworcl/onlinelog/group_3.259.765328197 Redo Log dosyası 3 yed.
+FRA/neworcl/onlinelog/group_4.310.765328219 Redo Log dosyası 4 yed.
+FRA/neworcl/controlfile/current.256.745007003 Kontrol Dosyası yedek
/home/oracle/df_test.dbf

Fiziksel bir yöntem olarka unix cp ile mevcut bu dosyaları hedef yedek klasötlerine kopyalıyorum. Ve birer yedeklerini almış oluyorum.
$ cp +DATA/neworcl/datafile/sysaux.257.745006719 /home/oracle/yedekdatafile/
$ cp +DATA/neworcl/datafile/system.256.756697091 /home/oracle/yedekdatafile/
$ cp +FRA/neworcl/onlinelog/group_1.257.765328155 /home/oracle/yedekloglar/
$ cp +FRA/neworcl/onlinelog/group_2.258.765328177 /home/oracle/yedekloglar/
$ cp +FRA/neworcl/onlinelog/group_3.259.765328197 /home/oracle/yedekloglar/
$ cp +DATA/neworcl/datafile/users.259.745006721 /home/oracle/yedekdatafile/
$ cp +DATA/neworcl/datafile/undotbs1.258.745006721 /home/oracle/yedekdatafile/
$ cp +FRA/neworcl/controlfile/current.256.745007003 /home/oracle/yedekcontrolfile/

Export ile yedek Almak: Mantıksal bir yedek almak için kullanılan en eski yöntemdir. Database yedek almak için sysdba rolüne yada EXP_FULL_DATABASE yetkisine sahip bir kullanıcı olmak gerekir.

$ Exp help=y
Yazılarak export işlemi hakkında bilgiler yada seçenekler yardımı görülebilir.
Eğer siz kullanıcı adı ve password ‘u hangi backup mode alınacağını yada alınacak yedek ismini sonra da girebilirsiniz. Zaten export aracı sizden bu bilgileri prompt şeklinde sizden isteyecektir.
Örnek bir exp işlemi:

$ exp dbamhm/sifre full=Y file=/home/oracle/full_database.dmp; Test veritabanım yok denecek kadar az bir veri olmasına rağmen yaklaşık olarak 12 dk sürdü. “Full=y “ seçeneği tüm database yedek alınmasıdır.
Tables seçeneği ile yazılan tabloların yedeği alınmaktadır.
$ exp dbamhm/sifre tables=(employees,departments) file=/home/oracle/tbl_emp_dept.dmp;

Parametre dosyası ile de yedek alınabilmektedir. Yani tüm bilgilerin bu console ekranına yazmaktansa bir parametre dosysı oluşturulur ve PARFILE=dosya kullanılarak erişim yapılır.
Örnek kullanım:
$ exp dbamhm/sifre PARFILE=ydk.txt;
Ydk.txt içeriği:
FILE=fulldb.dmp
BUFFER=2000000
FULL=Y
OWNER=dbamhm
GRANTS=y
COMPRESS=n

Alınan bu yedek default olarak COMPRESS seçeneği Yes dir. Yani otamatik olarak alandan tasarruf için sıkıştırılma yapılmaktadır. İstenilmediği takdirde COMPRESS=N olarak belirtilmelidir.
BUFFER tagı ise Expor işlemi için tanınmış bir tampon bellek ayracıdır. Bu değerin çok olması exp işlemini hızlandıracaktır. 2000000=2MB anlamına gelmektedir.

Bir Query sonucunuda yedekleyebiliriz. Bunun için QUERY tagına Where şartı ile yazılaması gerekir.
Örnek kullanım;

exp file=yedeksorgu.dmp tables=deneme query=\"where name=\'MHM\'\" rows=yes

Expdp(Datapump) yedek Almak:

$ Expdp help=Y

komutu Tüm backup seçenekleri için yardım sunar.
Yedek alınacak bir dizin oluşturulur ve yetkili kullanıcıya bu dizin için yazma ve okuma hakları verilir.

SQL>CREATE OR REPLACE DIRECTORY exp_dir AS '/home/oracle/';
SQL>GRANT READ, WRITE ON DIRECTORY exp_dir TO exp_usr;

Tabloların yedeğini almak için;

$ expdp exp_usr/palavra tables=deneme,deneme01,deneme02 directory=EXP_DIR dumpfile=denemes.dmp logfile=denemes.log

Schema/Schemaların yedeğini almak için;

$ expdp exp_usr/palavra schemas=exp_usr,tx01 directory=EXP_DIR dumpfile=sch_exp_usr.dmp logfile=sch_exp_usr.log


Tablespace yedeğini almak için;

$ expdp exp_usr/palavra tablespaces=examples directory=EXP_DIR dumpfile=tbs_examples.dmp logfile=tbs_examples.log

Bütün bir database yedeğini almak için;

$ expdp exp_usr/palavra full=Y directory=EXP_DIR dumpfile=fulldb.dmp logfile=fulldb.log


Niçin Exp/imp yada expdp/impdp aracı kullanılır?
  • Küçük boyutlu database’ lerde backup ve recovery için uygundur.
  • Databaseler arasında tablespace,tablo yada schema taşımak için uygundur.
  • Farklı platformlardaki oracle databaseler arasında veri transferi için uygundur.
  • Test makinesine database taşımak ve test etmek için uygundur.
  • Oracle farklı versiyonlarda Upgrade etmek için exp/imp araçları kullanılabilir. Yalnız burada bilinmesi gereken düşük versiyondan alınan bir backup için bir üst yada son versiyondaki bir database veri taşıncaksa catexpX.sql dosyasını çalıştırılarak son sürümdeki bir veritabanına eski exp yedeği(dump) yeni sürümde import edilebilir hale gelir.ancak bu şekilde tutarlı olur. Örnek oracle 9i da alınmış bir exp dump’ ı oracle 10g ‘deki catxp9.sql çalıştırıldıktan sonra imp aracı kullanılır.
Bir sonraki yazımızda da RMAN(Recovery Manager) teknolojisi ile yedek almayı göreceğiz. Oracle,  veri sürekliliği  açısından yedek alma/kurtarma aracı olarak RMAN teknolojisini tavsiye etmektedir. 

Bir sonraki makalemizde görüşmek üzere...




13 Ocak 2012 Cuma

Oracle Indexes 2

Bitmap Index:
Bitmap indeksler tablodaki değerleri bit şeklinde depolarlar. Veriler, başlangıç bitiş rowid ‘ler arasında oluştulan bitmaplar içinde depolanır.
Örnek:
create bitmap index person_region on person (region);

Row Region North East West South
1 North
1 0 0 0
2 East
0 1 0 0
3 West
0 0 1 0
4 West
0 0 1 0
5 South
0 0 0 1
6 North
1 0 0 0
Avantajları:
Örnekte de görüldüğü gibi düşük çeşitliğe sahip (low cardinality) Region columnu için bir Bitmap indeks oluşturulmuştur. Column değerleri ne kadar az çeşitse Bitmap okadar kısa olacak ve verinin bitlerden okunup getirilme işi o kadar hızlı olacaktır. Low cardinality columnlar için b tree indeksler yerine Bitmap indeks kullanmak daha verimli olacaktır.
Bitmap indeksler Bitmap sıkıştırılması mümkün olabilmektedir. Sıkıştırılmış bitmapin decompress(çözümleme) işi extra cpu kaynağı ve geniş bant genişliği ihtiyacını gerektirmektedir. Fakat sıkıştırılmış yapının diskten okunma hızı hızlı olmaktadır.
“Where” cümlesinde kullanılan “and” yada ” or “ operatörleri ile şartlar çoğaltıldığında Bitmap indeks kullanmak çok daha avantajlıdır.
Bitmap indeksler datawarehouse yapıdaki veritabanı sistemleri için idealdir. Hiç yok denecek kadar az transaction yapılar için kullanılması avantajdır. Aksi durumu performans kaybı olur. B tree indeksler ise OLTP transctional yapılar için uygun indeks yapılarıdır.
Dezavantajları:
Read only table or no DML:
Eğer tablomuz read-only değilde yani dml aktivesi varsa kesinlikle Bitmap index tercih etmeyiniz. Bunu sebebinde dml esnasında Bitmap oluşturma yada var olan bitmapın update edilmesi cpu bazında extra zaman demektir ve dolayısıyla kaynak tüketimini artıracaktır. Bir değere sebep ise dml esnasında dml deadlock’ ların oluşma sebebidir.
Kullanımı sadece datawarehouse sistemler için sınırlandırılmıştır. Diğer sistemler için kullanılması Bitmap modifikasyonu olacağından istenilmeyen performans kaybı yaşatır.

6 Ocak 2012 Cuma

Oracle Indexes


Tablo içerisinde rastgele dağıtılmış kayıtları(rows) aranılan küçük bir set getirmek için kullanılırlar. Bilindiği gibi indeksler indeks segmentinde saklanır. Logical olarak hiyerarşik bir zincir oluşturup ve bu zincirin leaf(yaprak) seviyelerinde referans alınan tablo rowidleri ile aranılan datayı/dataları nokta atışı olarak bulmamızı sağlayan objelerdir.Disk I/O ‘unu azaltırlar.Eğer indeks kullanılmayan bir HOT(heap Organization Table) istenilen bir küme setini FTS(Full Table Scan) olarak tarayacaktır FTS demek, tablo içerisindeki tüm kayıtlardaki her satırı inceleyerek sorgulanan yöntemdir. Indeks kullanıldığında ise , aranılan veri/verilerin hızlı bir şekilde bulunup sorgu nun en kısa zamanda çalışması hedeflenir. Yanlış index kullanımı, yanlış indeks tipi seçimi, yanlış yazılamış Hintler, ve invalidate indeksler performansa kötü etki yapmaktadır.
İndeks oluşturma:
CREATE INDEX ord_customer_ix ON orders (customer_id);
İndex ne zaman kullanılmalıdır?
İndeks gerekliği, tablodaki tüm satırlara bakıldığında aranılan sorgu sonucunun tüm kayıtlara oranı olarak hesaplanır. Genel olarak %2 ile %10 arası indeks kullanılması tavsiye edilebilir.
Unique/Nonunique indexes:
Unique bir indeks , her bir tek değer için tek bir rowid içerir. Aynı olan kayıttan bir tane saklar. Leaf (yaprak)’ larda sıralı bir şekilde bu bilgiler tutulur.
NonUnique indeksler ise, birden fazla aynı datayı(örneğin isim column’ u için birden fazla Ahmet değeri gibi) tutmayı izin verir.Nonunique indeksler index leaf’lerda indeks key tarafından artan şekilde sıralanmış rowid’ ler içermektedir.
Not:Primary key ve unique constraintleri otoamitik olarak unique(benzersiz) index oluşturular.
İndekslerin karakteristik Özellikleri:
Unusable: Mevcut olan bir indeksi kullanılamaz duruma düşürmektir. Kullanılmak istenildiğinde tekrar rebuild edilerek usable duruma getirilebilir. Genellikle mevcut bir indeksi kullanmayı önlemek için unusable kullanılır. Unusable indeksler, DML(insert-update-delete-merge) operasyonlarında ve optimizer tarafından dikkate alınmazlar.Bir indeks unusable olduğu zaman data tarafından indeks segmentinden silinir. Default olarak oluşan tüm indeksler usable’dir.
Bir indexin usable/unusable olduğunu görebilmek için aşağıdaki sorguya bakmamız gerekir.
SELECT index_name, status
FROM user_indexes;
ALTER INDEX test_idx UNUSABLE;
Online yapmak için
ALTER INDEX test_idx_state REBUILD;
Invisible: Indeksi gizli duruma getirmektir. Bir invisible index DML operayonları tarafından dikkate alınırlar. Fakat optimizer tarafından dikkate alınmazlar. İndeksi invisible yapmadaki amaç, silinmiş gibi gösterip optimizer tarafından dikkate alınmayıp (indeks kullanmayıp)mevcut sorgulardaki performans testi yapmaktır. Default olarak tüm indeksler oluşturulduklarında visible’ dır.
Yeniden adlandırma:
ALTER INDEX test_idx RENAME TO i my_test_idx;
Rebuild etme:
ALTER INDEX my_test_idx REBUILD ONLINE;
Paralel özelliği verme:
ALTER INDEX my_test_idx PARALLEL 3;
Reverse özelliği verme:
ALTER INDEX _test_idx _person_id REBUILD REVERSE;
İstatistik toplama:
ALTER INDEX idx_last_name
REBUILD COMPUTE STATISTICS;

ifadesi indeks oluşturma esnasında istatistiklerin toplanması istenmeyebilir yada unutulabilir. Alter index komutuyla sonradan verilen indeks için istatistikler toplanabilir.
Index silme:
DROP INDEX idx_last_name;
Komutuyla verilen isimdeki bir indeksi silebiliriz.

B tree Index:
B tree indeks , Balanced Trees ifadesinin kısaltılmış halidir.
Örnek olarak employees tablosundaki department_id column için b tree indeks yapısına bakalım. Leaf seviyesinde önce value sonra rowid gelecek şekilde temsil edilir. Şuan burada kullanılan indeks nonunique bir indekstir. Zincirin leaf seviyesinde sıralı şekilde duplicate kayıtlar mevcuttur.
B tree indeksler veriyi sıralı bir şekilde kaydederler. dolayısıyla herhangi bir sort işlemini önlemek içinde kullanılırlar. Bitmap indexler için böyle bir durum söz konusu değildir.
Btree indeksler OLTP sistemler için idealdir.
B tree indeksler null değerler için index kullanamazlar.
Kullanımı:
CREATE [UNIQUE] INDEX index_name ON table_name (column1, column2, column_n) [ COMPUTE STATISTICS ];
Compute Statistics:
Genel olarak bir indeksi yukarıdaki şekilde oluştururuz.
COMPUTE STATISTICS, index oluşturma esnasında istatistiklerin oracle tarafından söylenilmesini bildirir.
CREATE INDEX t_id_idx ON t(id);
Peki bu aşamada neler yaşanır? “id” kolonunun değerleri artan sırada dizilir.Degeri ve tablodaki satır adresi(rowid) bilgisi saklanır, bu şekilde indeksimiz oluşturulmuş olur.Aşağıdaki sorguya bakalım :
select * from T where id = 12345
sorgusunda normal şartlarda indeks tarama (index scan) yapılır, önce “id” değeri indeksten bulunur ve satırının rowid bilgisine ulaşılır ve rowid bilgisi ile tabloya nokta atışı yapılarak veriler getirilir. “….where id between 200 and 300…” gibi bir sorguda “leafler üzerinde gezilerek aralık (range) bilgisine ulaşılır.B Tree indeks yapısında tekil(unique) olmayan bir indeks değeri yoktur.
Concatenated btree index:
ÖRNEK:
SQL>create table xcount(t1 number,t2 number);
SQL> begin
2 for k in 0..10000
3 loop
4 insert into xcount values(k,mod(k,5));
5 end loop;
6 end;
7 /
PL/SQL procedure successfully completed.
SQL>create index xc_idx1 on xcount(t1);
SQL>create index xc_idx1 on xcount(t2);
SQL>create index xc_idx3 on xcount(t1,t2);
SQL> set autotrace on
SQL> select * from xcount where t1=0 and t2=0 order by t1 desc;
T1 T2
---------- ----------
0 0
Execution Plan
----------------------------------------------------------
Plan hash value: 2128003261
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 26 | 1 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| XC_IDX3 | 1 | 26 | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T1"=0 AND "T2"=0)
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
4 recursive calls
0 db block gets
30 consistent gets
0 physical reads
0 redo size
478 bytes sent via SQL*Net to client
419 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
Yukarıdaki sorgumuz xc_idx3 indeksini kullanarak CPU bazında en düşük Cost'u çıkarıp en iyi execution planı seçmiştir. Şayet aynı sorguda xc_idx3 değilde xc_idx1 yada xc_idx 2 yi seçseydik o zaman sonuç aşağıdaki gibi olacaktı.
SQL> select /*+INDEX(xcount xc_idx2)*/ * from xcount where t1=0 and t2=0 order by t1 asc;

T1 T2
---------- ----------
0 0


Execution Plan
----------------------------------------------------------
Plan hash value: 3776712309

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

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Tim
e |

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

| 0 | SELECT STATEMENT | | 1 | 26 | 24 (0)| 00:
00:01 |

|* 1 | TABLE ACCESS BY INDEX ROWID| XCOUNT | 1 | 26 | 24 (0)| 00:
00:01 |

|* 2 | INDEX RANGE SCAN | XC_IDX2 | 2001 | | 6 (0)| 00:
00:01 |

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


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

1 - filter("T1"=0)
2 - access("T2"=0)

Note
-----
- dynamic sampling used for this statement (level=2)


Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
24 consistent gets
0 physical reads
0 redo size
478 bytes sent via SQL*Net to client
419 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

Hint kullanarak xc_idx2 indeksini kullanarak sorguyu çalıştır dedik. Fakat böyle bir (t1 and t2) filtresinde CPU bazındaki cost'u 24 çıkmıştır.Combine indexler böyle durumlarda verimli olabilir.
Function-based Index:
indeksler sadece kolonlar için değil aynı zamanda fonksiyonlar içinde kullanılırlar.
ÖRNEK:


SQL>create index idx_adv_f_name on adv_table(lower(first_name));
index created.
SQL>create table adv_table as select * from hr.employees;
table created.
SQL> set timing on
SQL> set autotrace on
sQL> select first_name from adv_table where lower(first_name)='anthony';

FIRST_NAME
------------------------------
Anthony

Elapsed: 00:00:00.01

Execution Plan
----------------------------------------------------------
Plan hash value: 3152802285

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

| Id | Operation | Name | Rows | Bytes | Cost (%CP
U)| Time |

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

| 0 | SELECT STATEMENT | | 1 | 24 | 2 (
0)| 00:00:01 |

| 1 | TABLE ACCESS BY INDEX ROWID| ADV_TABLE | 1 | 24 | 2 (
0)| 00:00:01 |

|* 2 | INDEX RANGE SCAN | IDX_ADV_F_NAME | 1 | | 1 (
0)| 00:00:01 |

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


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

2 - access(LOWER("FIRST_NAME")='anthony')

Note
-----
- dynamic sampling used for this statement (level=2)


Statistics
----------------------------------------------------------
4 recursive calls
0 db block gets
8 consistent gets
0 physical reads
0 redo size
434 bytes sent via SQL*Net to client
419 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed