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 AUTOolarak
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 konfigure 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_RETENTIONparametresini
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 optimumUNDO_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;
Alıntıdır: http://taliphakanozturk.wordpress.com/tag/undo-tablespace/
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#;
SELECT
MAX(undoblks/((end_time-begin_time)*3600*24)) as UNDO_BLOCK_PER_SECOND
FROM
v$undostat;
SELECT
TO_NUMBER(value) as DB_BLOCK_SIZE
FROM
v$parameter
WHERE name =
'db_block_size';
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';
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';
select '"ORA-01555 (Snapshot too
old)" hata sayısı: '
|| sum(ssolderrcnt)
from v$undostat;
Hiç yorum yok:
Yorum Gönder