Anasayfa > Administration, DBA scriptler, oracle > Oracle UNDO Parametrelerinin Optimize Edilmesi

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

  1. Henüz yorum yapılmamış.
  1. No trackbacks yet.

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Connecting to %s

%d blogcu bunu beğendi: