Pages

6 Temmuz 2011 Çarşamba

Sıcak blok kavramı üzerine bir inceleme

Ön bellek içinde muhtemel “sıcak bloklar” CACHE BUFFERS CHAINS mandalında yüksek veya hızla artış gösteren bekleme sayılarından belirlenebilmektedir.

Bu mandal, tampon bellek içerisinde önbelleklenmiş data bloklarını araştırırken elde edilir. Tampon bellek, blok zincirlerinin toplamı olarak uygulandığından itibaren, her bir zincirin taranması gerektiğinde alt bir mandal tarafından korunmaktadır. Bu mandal içindeki içerik, tekil bir bloğa çok yüksek sayıda erişimden kaynaklanmaktadır. Bu durum, uygulamanın yeniden gözden geçirilmesini gerektirebilir.
 
Bu mandal üzerindeki beklemeler incelenerek, aşağıdaki sorgularda kullanılarak ilgili segment ve spesifik blok hakkında bilgiler elde edilebilir.

Önce, bu mandal için uyku sayısı incelemesiyle hangi mandal ID(ADDR) lerinin etkilendiği belirlenmelidir. Yüksek uyku sayısı, daha etkili mandal IDsi(ADDR)ni işaret etmektedir:


select CHILD#  "cCHILD", ADDR    "sADDR",     
       GETS    "sGETS" , MISSES  "sMISSES",
       SLEEPS  "sSLEEPS"
from v$latch_children
where name = 'cache buffers chains'
order by 4, 1, 2, 3;


En fazla sürekli uyku sayısına sahip mandal IDsi(ADDR) oluşturmak için yukarıdaki sorgu sıklıkla çalıştırılabilir. En yüksek uyku sayısına sahip ID bulunduğunda, sonrasında bu mandal tarafından korunan tampon bellek içindeki mevcut bloklar hakkında daha fazla detay almak için bu mandal adresi kullanılabilir.
 
En yüksek uyku sayısına sahip ID yi belirledikten sonra aşağıdaki sorgu çalıştırılmalıdır.

    
select /*+ RULE */
       e.owner ||'.'|| e.segment_name  segment_name,
       e.extent_id  extent#,
       x.dbablk - e.block_id + 1  block#,
       x.tch,
       l.child#
     from
       sys.v$latch_children  l,
       sys.x$bh  x,
       sys.dba_extents  e
     where
       x.hladdr  = 'ADDR' and
       e.file_id = x.file# and
       x.hladdr = l.addr and
       x.dbablk between e.block_id and e.block_id + e.blocks -1
     order by x.tch desc ;


SEGMENT_NAME  EXTENT#  BLOCK#   TCH    CHILD#
------------  -------- -------- ------ ---------
SCOTT.EMP_PK  5        474      17      7,668
SCOTT.EMP     1        449       2      7,668

TCH kolonuna bağlı olarak bir “sıcak blok” belirlenebilir. TCH kolonun değerinin yüksekliği neticesinde, SQL cümlelerince erişilen en sık blok anlaşılır. “Sıcak blokları” bulmak için aşağıdaki sorgu çalıştırılabilir.


SELECT c.addr, sleeps, file#, dbablk, class, state, TCH
FROM sys.v$latch_children c, sys.v$latchname n , sys.x$bh
WHERE n.name=’cache buffers chains’
and c.latch#=n.latch#
and sleeps >10000
and x$bh.hladdr = c.addr
ORDER BY sleeps;

Bunun yanında RAC platformunda sıcak blokların bulunması için interconnect bağlantısından diğer instance’a talep edilen bloğa erişimde meydana gelen beklemeleri işaret eden “gc buffer busy” bekleme olayı incelenmelidir. “gc buffer busy” bekleme olayı, birden fazla RAC instance’ının aynı bloğa erişim talebinde bulunmasıdır, bu bloklar tampon bellek içinde olmasada veya uyumsuz modda olsa bile… Aşağıdaki sorgu ile “gc buffer busy” bekleme olayını oluşum sayısı ve ortalama bekleme zamanı ile elde edebilmekte ve bunun neticesinde yüksek bekleme sayısı ve ortalama bekleme değerine sahip objeler tespit edilip bunların üzerinde odaklanılabilir.

select /*+ rule */
de.owner, de.segment_name, de.segment_type,
ash.event, sum(ash.time_waited) total_time,
count(*) count,sum(ash.time_waited)/count(*) Avg_wait
from V$ACTIVE_SESSION_HISTORY ash,
dba_extents de
where ash.event like 'gc%' and
ash.P1TEXT='file#' and
ash.P2TEXT='block#' and
ash.p1=de.file_id and
ash.time_waited > 0 and
ash.p2 between de.block_id AND (de.block_id+de.blocks-1)
group by de.owner, de.segment_name, de.segment_type, ash.event
order by 5 desc;

Swingbench ile 2 düğümlü RAC test platformuma yaptığım yükleme sonunda yukardaki sorguyu çalıştırdığımda elde ettiğim sonuç aşağıda yer almaktadır.

OWNER      SEGMENT_NAME     SEGMENT_TYPE EVENT          TOTAL_TIME COUNT  AVG_WAIT
---------- -------------    ----------- ------------    ---------- ------ ---------
BUGRA1    STOCKS_CCR_RQS    TABLE       gc buffer busy   1093170590 1647 663734.42
BUGRA1    STOCKS_CCR_RQS_N2 INDEX       gc buffer busy   308449809   379 813851.739
BUGRA1    STOCKS_CCR_QUQ    TABLE       gc buffer busy   57052295     82 695759.695
BUGRA1    IC_TRAN_PND       TABLE       gc buffer busy   20919444    590 35456.6847
SYS       SYSSMU194$        TYPE2 UNDO  gc buffer busy   4866157       5 973231.4
BUGRA1    FND_CACHE_VS_PK1  INDEX       gc buffer busy   3500004       4 875001
BUGRA1    STOCKS_CCR_RQS_U1 INDEX       gc buffer busy   2894350       6 482391.667 

Oracle 10g sürümünde _DB_BLOCK_HOT_TRACKING olarak adlandırılan gizli bir parametre, sıcak blokları X$KSLHOT tablosunda kayıt etmeye yarar.Varsayılan olarak bu parametre devredışıdır, böylece bu tablo herhangi bir ilginç bilgi yer almaz. Bu parametrenin data dictionary tanımı: “hash mandal içeriği için sıcak blokları izler” diye belirtilmektedir.

Aşağıdaki örnekte X$KSLHOT tablosunu kullanarak sıcak blokların tespiti üzerinde bir örnek yer almaktadır.

  • İlk aşamada  _DB_BLOCK_HOT_TRACKING gizli parametresi etkinleştirilir.
alter system set "_db_hot_block_tracking"=true scope=spfile sid='*';
System altered.

  • Veritabanı yeniden başlatılır.
  • Bir kısım yükleme yapılır. Swingbench ile test ortamında hot blok oluşturmak üzere farklı oturumlardan aynı segmentlere çeşitli kombinazyonlarda yükleme yapıyorum.
·         Şimdi X$KSLHOT  tablosu içerisinde ne oluştuğuna bakıyorum

select * from x$kslhot;

ADDR           INDX    INST_ID  KSLHOT_ID KSLHOT_REF
-------- ---------- ---------- ---------- ----------
4FA19190          0          1  121634997          1
4FA19198          1          1  121634836          1
4FA191A0          2          1  180355114          0
4FA191A8          3          1  157285880          0
4FA191B0          4          1  157285837          0
4FA191B8          5          1  180355093          0
4FA191C0          6          1    8415258          0
4FA191C8          7          1  121634835          0
4FA191D0          8          1  157285782          0
4FA191D8          9          1  157285775          0

10 rows selected

Yukarda görüldüğü üzere 10 satır yer almakta ve Oracle mevcut olarak bunların sıcak blok olduğunu değerlendirmeye almaktadır.

  • Bu yaklaşımı kullanarak X$KSLHOT  tablosu içerisindeki KSLHOT_ID kolonunu rfile#, block#, segment tipi, tablo ve tablespace ismi gibi daha detaylı bilgilere dönüştürüyoruz.
select x.*, de.owner, de.segment_name, de.segment_type
de.tablespace_name, df.name file_name
from ( select addr, indx, inst_id
, trunc( kslhot_id/ power(2,22) ) as rfile#
, trunc(kslhot_id-
trunc(kslhot_id/power(2,22))*power(2,22) ) as block#
, kslhot_ref
from x$kslhot ) x, v$datafile df, dba_extents de
where x.rfile# = df.rfile#
and x.rfile# = de.relative_fno
and x.block# between de.block_id and de.block_id+de.blocks


ADDR           INDX    INST_ID RFILE     BLOCK# KSLHOT_REF OWNER SEGMENT_NAME    SEGMENT_TYPE    TABLESPACE_NAME FILE_NAME
-------- ---------- ---------- ----- ---------- ---------- ----- --------------- --------------- --------------- ---------------
3FA391C0          4          1    29        204          0 HR   STOCKS     TABLE PARTITION TBS_ARDA_DATA +DATA01/ugurdb/tbs_arda_data.265.343317892                                                                                                                                                                                                                           
...

10 rows selected

Sıcak blok oluşumunu azaltmak için sırasıyla aşağıdaki önlemler alınabilir.

1) Belirli DML ve SELECT komutları obje içeriğini azaltmak için yeniden organize edilebilecekmi diye  uygulamayı incelenmelidir.
2) Tampon bellek düşürülebilir, buna ragmen bu bazı durumlarda sınırlı derecede yardımcı olacaktır.
3) DBWR çıktısı bunun için bir etken olabilir. Eğer bir çok BBWR kullanılıyorsa, bu durumda DBWR sayısı arttırılmalıdır.
4) ALTER TABLE komutuyla veya tabloyu yeniden inşa ederek PCTFREE değeri arttırılmalıdır. Automatic Segment etkin tablo oluşumunda PCTFREE kaynaklı sıkınıtlar pek olmamaktadır. Bu değerin yüksek olması blok başına daha az satır şeklinde olmaktadır.Böylece aynı blok adresinin farklı SQL komutları tarafından aynı anda taranması sebebiyle “sıcak blok” oluşumu ihtimali azaltılabilir.
5) Sekuans tabanlı primary key indeksleri Ters taraf(reverse) anahtar indeskleri şeklinde yeniden oluşturmayı gözönünde bulundurun.


1 yorum:

  1. Selamlar Ugur Bey,

    Yorumumu mumkun oldugunca Turkce kelimeler ile yapmaya calisacagim, ama sizin kadar basarili olamayabilirim :).
    Yazdiginiz makale bu sorunla karsilasan arkadaslara muhakkak buyuk olcude yararli olacaktir.
    Daha once "Sicak Block" nedeni ile yilbasi gecesini sirkete baglanarak, bu problemi cozmekle ugrasmis biri olarak, performans acisindan ne kadar onemli oldugunu, ben de birkez daha hatirlatmak isterim.
    Benim karsilastigim durumda, problemi, sizin de onlemler kisminda belirttiginiz gibi 4. maddedeki yontem ile cozmustum. Benim gozlemledigim durumda, 50 civari paralel session ayni tabloya insert yapmaya calisip, daha cok, tablo uzerindeki bir index'te "Sicak Blok" olusmasina neden oluyordu. Hem tablo ve hem index tanimini degistirip, islemin hizlanmasini saglamistim.

    Gorusmek uzere, kolay gelsin,
    Ural Ural

    YanıtlaSil