Oracle UNDO Parametrelerinin Optimize Edilmesi

Merhaba Arkadaşlar,

Bu makale ile ORACLE ayrılmaz parçası UNDO muzu nasıl optimize edebiliriz sorusunun cevabını inceliyor olacağız.

Veritabanında oluşan transaction undo bilgileri commit veya rollback yapılana kadar rollback segmentlerinde tutulmaktadır. Bazen veritabanındaki uzun süren sorgularımız “ORA-01555:Snapshot Too Old” hatası ile karşılaşmaktadır. Bu UNDO parametrelerimizin doğru konfigüre edilmediğinden kaynaklanmaktadır.  UNDO_RETENTION parametresiyle, biz veritabanının commit sonrası ne kadar undo verisini tutacağına karar veririz. Bu parametre default 900 sn gelmektedir. Sonradan bu değeri yükseltmek bizim elimizdedir. 900sn(15 dk) değerini yükseltmek doğru orantılı olarak daha fazla space gerektirecektir. Rollback segmentlerini tanımlamak ve yönetmek zahmeti yerine, undo tablespace i oluşturmak ve undo yönetimini oracle a bırakmak oldukça kolaydır. UNDO_MANAGEMENT parametresini AUTO olarak set ettiğinizde ORACLE gerisini kolay bir şekilde halledecektir. “ORA-01555:Snapshot Too Old” hatasından kurtulmanın yolları UNDO_RETENTION parametresi ve UNDO Tablespace büyüklüğünün doğru konfigüre edilmesinden geçmektedir 🙂

Peki UNDO_RETENTION süremiz ne kadar olmalıdır? Bu sorunun cevabı UNDO Tablespace büyüklüğünüzle orantılıdır. UNDO Tablespace için diskinize ve verilerinizin kritikliğine göre bir alan verebilirsiniz. Bu büyüklüğe görede optimum süreyi hesaplayarak UNDO_RETENTION parametresini set etmelisiniz.

Şimdi biraz matematiksel hesap yapalım. Önce Undo tablespace büyüklüğümüzü aşağıdaki sorgu ile tespit edelim;

SELECT SUM(a.bytes) as UNDO_SIZE
  FROM v$datafile a,
       v$tablespace b,
       dba_tablespaces c
 WHERE c.contents = 'UNDO'
   AND c.status = 'ONLINE'
   AND b.name = c.tablespace_name
   AND a.ts# = b.ts#;

Sonra saniye başına undo block sayısını bulalım;

SELECT MAX(undoblks/((end_time-begin_time)*3600*24)) as UNDO_BLOCK_PER_SECOND
  FROM v$undostat;

Son olarak veritabanı block size ımızı bulalım;

SELECT TO_NUMBER(value) as DB_BLOCK_SIZE
 FROM v$parameter
WHERE name = 'db_block_size';

Şimdi elde ettiğimiz üç sonuca göre optimum UNDO_RETENTION süremizi hesaplayacağız. Kullanacağımız formül şu şekilde;

 UNDO RETENTION TIME=(UNDO SIZE)/(DB BLOCK SIZE × UNDO BLOCK PER SECOND)

 Yukarıda hesapladığımız değerleri bu formülde yerlerine yerleştirdiğimizde optimum UNDO_RETENTION süremizi bulmuş olacağız.

Şimdi olaya tersden bakalım. Yeteri kadar disk yerimiz ve kritik veritabanı işlemlerimiz varsa, commitlenmiş undo verilerimizi tutmak için  UNDO RETENTION süremizi 1 saat (3600 sn) olarak düşünüyorsak optimum UNDO büyüklüğümüzü yukarıda vermiş olduğum formülden yararlanarak hesaplayabiliriz. Bu durumda formülümüz;

UNDO SIZE=UNDO RETENTION TIME × DB BLOCK SIZE × UNDO BLOCK PER SECOND

Son olarak hepsini tek bir sorgu ile çözelim. Optimum UNDO_RETENTION süresini bulmak için;

SELECT d.undo_size/(1024*1024) as UNDO_SIZE,
       SUBSTR(e.value,1,25) as UNDO_RETENTION,
       ROUND((d.undo_size / (to_number(f.value) *
       g.undo_block_per_sec))) as OPTIMUM_UNDO_RETENTION
  FROM (
       SELECT SUM(a.bytes) undo_size
          FROM v$datafile a,
               v$tablespace b,
               dba_tablespaces c
         WHERE c.contents = 'UNDO'
           AND c.status = 'ONLINE'
           AND b.name = c.tablespace_name
           AND a.ts# = b.ts#
       ) d,
       v$parameter e,
       v$parameter f,
       (
       SELECT MAX(undoblks/((end_time-begin_time)*3600*24))
              undo_block_per_sec
         FROM v$undostat
       ) g
WHERE e.name = 'undo_retention'
  AND f.name = 'db_block_size';

Belirleyeceğimiz UNDO RETENTION süresine göre optimum UNDO büyüklüğünü bulmak için;

SELECT d.undo_size/(1024*1024) as UNDO_SIZE,
       SUBSTR(e.value,1,25) as UNDO_RETENTION,
       (TO_NUMBER(e.value) * TO_NUMBER(f.value) *
       g.undo_block_per_sec) / (1024*1024)
      as NEEDED_UNDO_SIZE"
  FROM (
       SELECT SUM(a.bytes) undo_size
         FROM v$datafile a,
              v$tablespace b,
              dba_tablespaces c
        WHERE c.contents = 'UNDO'
          AND c.status = 'ONLINE'
          AND b.name = c.tablespace_name
          AND a.ts# = b.ts#
       ) d,
      v$parameter e,
       v$parameter f,
       (
       SELECT MAX(undoblks/((end_time-begin_time)*3600*24))
         undo_block_per_sec
         FROM v$undostat
       ) g
 WHERE e.name = 'undo_retention'
  AND f.name = 'db_block_size';

Veritabanımızın son açıldığı andan itibaren kaç ORA-1555 hatası aldığını merak ediyorsanız aşağıdaki sorgu ile bulabilirsiniz.

  select '"ORA-01555 (Snapshot too old)" hata sayısı: ' 
  || sum(ssolderrcnt)
  from v$undostat;

Optimum değerlerimizle sağlıklı çalışan veritabanlarınız olması dileğiyle 🙂

Talip Hakan ÖZTÜRK

Reklamlar

Oracle DBA için Linux Komutları

Merhaba Arkadaşlar bu yazımda bir Oracle DBA in bilmesi gereken Linux komutlarını sizlerle paylaşacağım. Aklıma gelen komutları ilerleyen zamanlarda da bu makaleye ekliyor olacağım.

mounting disk:
——————————
1- önce diski mount edeceğimiz klasör oluşturulur.
mkdir /media/newdisk
mkdir /DATA

FAT32 olarak mount etmek için :
mount -t vfat -o umask=ooo /dev/hdb1 /media/newdisk

NTFS olarak mount etmek için:
mount -t ntfs -o umask=0222 /dev/hdb1 /media/newdisk

CDROM u mount etmek için:
mount -t iso9660 -r /dev/cdrom /media/cdrom

OCFS2 olarak mount etmek için:
mount -t ocfs2 -o noatime,_netdev,datavolume,nointr /dev/emcpowera1 /DATA

EXT3 olarak mount etmek için:
mount -t ext3 /dev/sdb1 /software

unmounting disk:
————————–
umount -l /dev/sdb1
umount /DATA

Partitioning
—————
fdisk /dev/sdb

Formatting
————

EXT3 olarak formatlamak için:

mkfs -t ext3 /dev/sdb1

OCFS2 olarak formatlamak için:

mkfs.ocfs2 -b 4K -C 128K -N 5 -L /DATA /dev/emcpowera1

FILE SYSTEM CHECK
———————————————
fsck.ocfs2 -n /dev/sdf2
fsck.ocfs2 -y /dev/sdf2 –>repair
List drives
————–
df -h

tmpfs artırma
—————————————————-
mount -t tmpfs shmfs -o size=3g /dev/shm

Getting user id
———————–
id username
id oracle

Bir klasörde bir kullanıcıyı owner yapmak
——————————————-
chown -R oracle:dba /oracle

Bir klasörün veya dosyanın yetkisi değiştirmek
——————————————–
chmod 775 file_name

Bir rpm in yüklü olup olmadığını kontrol etmek için
————————————————–
rpm -qa | grep “package name”

Rpm yüklemek için
——————
rpm -ivh package

Rpm update etmek için
———————–
rpm -Uvh package

Rpm silmek için
——————
rpm -e package

Oracle kurulumu için gereken rpmleri listelemek,versiyon ve yüklü olup olmadığı bilgisini bulmak için
—————————————————————————————————————-

rpm -q binutils compat-db compat-libstdc++-33 libgcc glibc glibc-devel glibc-headers gcc gcc-c++ libgcc libstdc++ cpp make libaio ksh elfutils-libelf make sysstat libaio libaio-devel setarch libXp unixODBC –qf “%{NAME}-%{VERSION}-%{RELEASE} (%{ARCH})\n”|sort

Kurulum tarihe göre rpmler
———————
rpm -qa –last | more

CPIO dosyasının extract edilmesi
———————————-
cat cpio_file | cpio -idmv

Dosya taşımalarında kopyalamayı validate etmek için MD5 oluşturma
————————————————————-
md5sum file > file.md5

Taşınan dosyanın MD5 dosyası ile kontrol edilmesi
————————————————-
md5sum -c file.md5

sunucular arası dosya transferi
———————————
scp 192.168.2.1:oracle/tlp.pw /oracle #karşıdan dosya indirme
scp /oracle/full.dmp ora10g@192.168.3.5:/export #dosya kopyalama

Dosyada arama
———————-
grep -ins 192.168.2.1(Text) -A2 -B1 list1.log

Process sayısı bulma
————————
ps -ef |grep TALIPDB|wc

Tarih değiştirme
———————————–
date -s “30 MAR 2010 12:32:00”

SEMAPHORE
——————–
ipcs -s
ipcrm

OS process i trace etmek için
—————————-
strace -p pid

Tar zip dosyasının içeriğini listelemek için
—————————————
tar -tf java_patch.tar

Tar zip dosyasına bir kkasör veya dosya eklemek için
———————————————–
tar -rf java_patch.tar jre

Tar zip dosyası oluşturmak için

—————————–
tar -cf java_patch.tar jdk

Bir kullanıcının ID bilgisini değiştirmek
—————————————–
usermod -u UID user

process öldürmeden dosya içeriğini boşaltmak için
———————————————-
echo “”>talipdb_ora_7001.trc

kelimenin path olarak nerede geçtiğini bulmak için
———————————————–
which exp

klasöre kısayol oluşturmak için
——————————————
ln -s path kısayol_adı

SELinux statüsünü görme
——————————-
sestatus

Yuklenilecek rpm paket versiyonunu öğrenmek için
———————————————–
echo ocfs2-`uname -r`

i/o istatisklerini izlemek için
——————————-
iostat 3

RAC sunucular arası tarih kontolu:
—————————————
ssh taliprac1 date; ssh taliprac2 date; date

sudoers komut ekleme. root şifresine ihtiyaç duymadan bir kullanıcın komut çalıştırabilmesi
——————————————————————————————–
/etc/SUDOERS
ora10g localhost=NOPASSWD:/bin/mount,/bin/umount
ora10g talipdb=NOPASSWD:/bin/mount,/bin/umount

Broadcast mesaj
——————-
wall mesaj

Son login bilgileri
——————-
last | more

O anki dizininin size bilgisi
———————–
du . -sh

o anki dizinin içindeki tüm dosyaların size bilgisini sıralı olarak
————————————————————–
du * -sh | sort -n

bir dosya içeriğini mail gonderme
———————————–
mail -s “deneme” talip_hakan_ozturk@hotmail.com < sqlnet.log(gönderilecek dosya)

dosya içinde word kelimesi geçenler
———————————-
grep -ins word *

process_name olan processleri toplu kill etmek için process kill script oluşturmak
——————————————————————————–
ps -ef |grep “process_name” |awk ‘{print ” kill -9 ” $2}’>/tmp/kill.sh

process_name processleri 2 saniye aralıklarla izlemek
—————————————————–
watch -n 2 “ps -ef | grep process_name | grep -v ps”

bir dosya içeriğindeki değişiklikleri anlık izlemek
—————————————————-
tail -f /var/log/messages