“Ortalama Aktif Oturumlar”(Average Active Session - AAS) metriği, Oracle veritabanının tüm çalışma performansının ölçümünde olağandışı bir şekilde basit ve bir o kadar kullanışlı şekilde hizmet sunmaktadır. AAS metriği, kısaca “DB Time” değerinin “işlem süresi-elapsed time” değerine bölünmesiyle tanımlanmaktadır.
Sırayla, “DB Time”, hem CPU üzerinde hemde boşta olmayan bekleme durumlarında sıkışmış tüm oturumlar tarafından harcanan zaman olarak tanımlanmaktadır. Diğer bir deyişle, “DB Time” tüm aktif oturumlar tarafından harcanan zamanların toplamı olarakta düşünülebilir.
Mesela, bir dakikalık gözlem süresince aktif olan dört oturum olduğunu düşünelim. Her bir oturum toplamda dört dakikalık “DB Time” değerini vercek şekilde numeratörde birer dakikalık toplam “DB Time” değerine karşılık gelecektir. Bu örnekte, “geçen süre” paydası bir dakikadır. Her iki değerin bölümü AAS değeri olarak 4 sonucunu vermektedir. Bu örnektende görüldüğü gibi, 4 AAS metriği 4 aktif oturuma sahip olmaya karşılık gelmektedir. Bu örnekte, ortalama olarak dört aktif oturum bulunmaktadır.
Eğer bu örneği çeşitli dönemlerde aktif durumda olan daha fazla oturum ilave ederek genelleştirirsek, AAS metriğinin hesaplaması gözlem periyodu süresince hala ortalama sayıda aktif oturumlar hakkında bir fikir verecektir.
AAS metriği CPU sayısı ile kıyaslandığında oldukça kullanışlı olmaktadır. Eğer AAS metriği CPU sayısını çok aşarsa, bu durumda veritabanı performansı zarar görecektir. Öte yandan, eğer AAS metriği belirgin şekilde CPU sayısından düşükse, o zaman veritabanı performansı iyi olacaktır. Veritabanı perfomansını sekteye uğratan üst sınırdaki AAS metriğinin eşikdeğeri, uygulamanın davranışına ve son kullanıcıların beklentilerine bağlıdır. Bu yüzden, bu eşikdeğeri uygulama bağlamında belirlenmelidir. AAS eşikdeğeri belirlendiğinde, bu metrik oldukça güvenilir, hazır biçimde bütün veritabanı performans sorunlarının teşhisinde hizmet verecektir. Aslında, “DB Time“ metriğinin düşürülmesi Oracle ADDM iyileştirme aracının yegane hedefi olmaktadır.
Bu AAS metriği tam olarak eksiksiz hesaplanmalı, veya aşağıda belirtileceği gibi tahmin edilmelidir. Bütün metotlar, hem tahminleri kullanarak hemde kesin hesaplamaları kullanarak, “işlem süresi” paydasınının seçimine bağlı olmaktadır.
İşlem süresi paydası ve anti homojenlik
AAS doğal bir kümedir veya ortalama bir metriktir. Ortalama tabanlı metrikler, temel verinin homojen olmayan durumunu her zaman gizlerler. Sıklıkla, bu gizli anti-homojenlik aslında Oracle performans probleminin anlaşılmasında en önemli bilgi kaynağı olmaktadır. İşte bu sebeple metriğin etkili kullanımı, anti-homojenliğin tespitini ve anlaşılmasını gerektirmektedir.
Bazı Oracle uzmanları, homojen olmayan herhangi bir tipi adlandırmak için “eğrilik-skew” tanımı kullanmaktadır. Eğriliğin istatistiksel tanımı, aslında belirli bir tip anti-homojenlik ile sınırlandırılmıştır.
Aşağıdaki örneklerde de görüleceği üzere, “işlem süresi” paydası eğriliğin tespitinde çok önemlidir. Daha geniş “işlem süresi” (mesela bir saat), nispeten birkaç satıra bakılması gerekeceğinden kullanım için daha uygundur. Ayrıca, saatlik ortalama pek çok uygulama ve çalışma için daha uygun olabilir. Ancak, daha düşük “işlem süresi” (mesela bir dakika), kısa anlık tepkilerin açığa çıkarılmasında faydalı olabilmektedir, ancak bu da yoğun bir veri hacmi oluşturacaktır. En iyi yaklaşım, kolaylık için mümkünse daha geniş “işlem süresi” kullanmak, ancak kısa anlık tepkilerin açığa çıkarılması gerektiği durumalarda ise daha kısa “işlem süresi” metriklerinin kullanılmasıdır.
ASH raporlarını kullanarak AAS tahmin metotları
AWR verisinden AAS metirklerini tahmin etmek için metodu belirleme noktasında kullanılan mantık ve matematik sırasıyla artalan biçimde aşağıdaki adımlarda yer almaktadır.
Adım 1 – Her bir gözlem için aktif oturum hesabı
Oracle, aktif oturumlar için temel durumları saniyede birkez kaydeder ve gözlemlerinin geçmiş bilgilerini V$ACTIVE_SESSION_HISTORY sistem tablosunda saklar. Her bir gözlem örneği SAMPLE_ID kolonu tarafından belirlenir. Verilen SAMPLE_ID için bu tablodaki satır sayısı, esasen bu gözlem için aktif oturum miktarıdır. Aşağıdaki örnek, her bir ASH gözlemi için 2 den 12 ye kadar aktif oturumların miktarını sorgu sonucu olarak getirmektedir.
AAS tahmini için gerekmemesine rağmen, aşağıdaki sorgu, CPU üzerinde olduğunu düşündüğü bekleme durumundaki oturumları birbirinden ayırmaktadır. Bu ilave analiz sıklıkla faydalıdır, ancak gereklide değildir.
select
sample_id,
sample_time,
sum(decode(session_state, 'ON CPU', 1, 0)) as on_cpu,
sum(decode(session_state, 'WAITING', 1, 0)) as waiting,
count(*) as active_sessions
from
v$active_session_history
where
-- en son 15 saniye
sample_time > sysdate - (0.25/1440)
group by
sample_id,
sample_time
order by
sample_id;
SAMPLE_ID SAMPLE_TIME ON_CPU WAITING ACTIVE_SESSIONS
---------- ------------------------- ---------- ---------- ---------------
25325213 24-NOV-11 15.32.03.078 PM 3 9 12
25325214 24-NOV-11 15.32.04.085 PM 1 6 7
25325215 24-NOV-11 15.32.05.095 PM 0 4 4
25325216 24-NOV-11 15.32.06.105 PM 1 2 3
25325217 24-NOV-11 15.32.07.115 PM 0 3 3
25325218 24-NOV-11 15.32.08.125 PM 0 2 2
25325219 24-NOV-11 15.32.09.135 PM 3 1 4
25325220 24-NOV-11 15.32.10.155 PM 0 4 4
25325221 24-NOV-11 15.32.11.165 PM 1 2 3
25325222 24-NOV-11 15.32.12.175 PM 0 4 4
25325223 24-NOV-11 15.32.13.185 PM 1 2 3
25325224 24-NOV-11 15.32.14.195 PM 1 3 4
25325225 24-NOV-11 15.32.15.205 PM 1 4 5
25325226 24-NOV-11 15.32.16.215 PM 1 2 3
14 rows selected.
Bunu bir kenara bırakırsak, aktif bir oturumun ASH tanımının V$SESSION_STATE görünümü değeri ile tam olarak eşleşmesi çokta gerekli değildir. Ayrıca, bazen ASH “idle” bekleme durumundaki oturumları, aktif olacaklarını normalde beklemesekte, kaydeder. Ancak, hiçbir ikincil düşünce bu yaklaşımın gereksiz olduğunu pekiştirmez.
Adım 2 – Bir zaman aralığı boyunca aktif oturum sayısını bulmak
Adım 1’deki sorguda, belirli zaman aralığında ASH tarafından kayıt edilen herbir gözlem için oturumların sayısı tespit edildi. Aktif oturumların ortalama sayısını hesaplamak için Adım 1’deki sorguyu bir satır içi görününüm ile altsorguya dönüştürüp, ortalamasını alacak bir dış sorgu ile saracağız. Bu örnekte, ortalamaları tekli ondalığa yuvarlayacak ve ortalamaları altsorgudaki en erken zaman mühürü ile ilişkilendireceğim.
select
to_char(min(sub1.sample_time), 'YYYY-MM-DD HH24:MI:SS') as sample_time,
round(avg(sub1.on_cpu),1) as cpu_avg,
round(avg(sub1.waiting),1) as wait_avg,
round(avg(sub1.active_sessions),1) as act_avg
from
( -- altsorgu 1: saniye başı bir satır, SAMPLE_TIME çözümü
select
sample_id,
sample_time,
sum(decode(session_state, 'ON CPU', 1, 0)) as on_cpu,
sum(decode(session_state, 'WAITING', 1, 0)) as waiting,
count(*) as active_sessions
from
v$active_session_history
where
sample_time > sysdate - (0.25/1440)
group by
sample_id,
sample_time
) sub1;
SAMPLE_TIME CPU_AVG WAIT_AVG ACT_AVG
------------------- ---------- ---------- ----------
2011-11-24 15:45:30 .7 2.8 3.8
1 row selected.
Yukarıdaki sorgu sonucu ortalaması veritabanı boştayken çekilen ASH snapshotlarından herhangi bir veri içermemektedir. ASH aktif olmayan oturumlar olarak bulunan gözlemler için bir satır kaydetmez. Bu yüzden, bu şekilde hesaplanan ortalamalar, aktif oturumlar olmadan gözlemler içeren bu aralıklar için yapay olarak çok yüksek olacaktır(çünkü AVG() fonksiyonu için N=örnekler paydası yapay olatak çok düşüktür). Ancak, ilgilenilen periyotlar genellikle performans krizlerini kapsadığından, pratikte bu önemli bir mesele değildir. Belli ki, ilgilenilen pek çok periyot bolca aktif oturumu kapsamakta, tipik olarakta CPU dan daha fazla aktif oturum kapsamaktadır.
Adım 3 - Çarpıklık bulmak için ortalaması ile bölünmüş varyans eklemek
Adım 2’deki sorguya , ortalama için hem varyans hemde varyans oranı eklenir. Yüksek oran çarpıklığı işaret etmektedir.
select
to_char(min(sub1.sample_time), 'YYYY-MM-DD HH24:MI:SS') as sample_time,
round(avg(sub1.on_cpu),1) as cpu_avg,
round(avg(sub1.waiting),1) as wait_avg,
round(avg(sub1.active_sessions),1) as act_avg,
round(variance(sub1.active_sessions),1) as act_var,
round( (variance(sub1.active_sessions)/avg(sub1.active_sessions)),1) as act_var_mean
from
(-- altsorgu 1: saniye başı bir satır, SAMPLE_TIME çözümü
select
sample_id,
sample_time,
sum(decode(session_state, 'ON CPU', 1, 0)) as on_cpu,
sum(decode(session_state, 'WAITING', 1, 0)) as waiting,
count(*) as active_sessions
from
v$active_session_history
where
sample_time > sysdate - (0.25/1440)
group by
sample_id,
sample_time
) sub1;
SAMPLE_TIME CPU_AVG WAIT_AVG ACT_AVG ACT_VAR ACT_VAR_MEAN
------------------- ---------- -------- ---------- --------- ------------
2011-11-24 15.47:10 .7 2.8 3.8 5.8 1.4
1 row selected.
Adım 4 – Birden fazla zaman aralıkları için tahmin
Adım 3’teki sorguya aşağıdaki değişiklikler yapılarak bu yaklaşımı birçok ardışık zaman aralığına genişletiyoruz. Aşağıdaki sorguda birer dakika aralığını seçiyorum.
· round(sub1.sample_time, 'MI') fonksiyonu ile GROUP BY temeli oluşturulur.
· Bir sqlplus yer değiştirme değişkeni eklenerekk ilgilenilen genel bir zaman aralığı belirtilir.
· Varyans kolonu sadece hata ayıklama ile ilgilendiği için kaldırıldı.
select
to_char(round(sub1.sample_time, 'MI'), 'YYYY-MM-DD HH24:MI') as sample_minute,
round(avg(sub1.on_cpu),1) as cpu_avg,
round(avg(sub1.waiting),1) as wait_avg,
round(avg(sub1.active_sessions),1) as act_avg,
round( (variance(sub1.active_sessions)/avg(sub1.active_sessions)),1) as act_var_mean
from
( -- altsorgu 1: saniye başı bir satır, SAMPLE_TIME çözümü
select
sample_id,
sample_time,
sum(decode(session_state, 'ON CPU', 1, 0)) as on_cpu,
sum(decode(session_state, 'WAITING', 1, 0)) as waiting,
count(*) as active_sessions
from
v$active_session_history
where
sample_time > sysdate - (&dakika/1440)
group by
sample_id,
sample_time
) sub1
group by
round(sub1.sample_time, 'MI')
order by
round(sub1.sample_time, 'MI');
old 18: sample_time > sysdate - (&dakika/1440)
new 18: sample_time > sysdate - (1/1440)
SAMPLE_MINUTE CPU_AVG WAIT_AVG ACT_AVG ACT_VAR_MEAN
-------------------- ---------- ---------- ---------- ------------
2011-11-24 16.15:00 1.8 3.3 4.9 .5
2011-11-24 16:16:00 1 3.4 4.5 .4
2011-11-24 16:17:00 .6 2.8 3.6 .3
2011-11-24 16:18:00 1 3.7 4.5 .5
2011-11-24 16:19:00 .7 3.2 4.3 .3
2011-11-24 16:20:00 .8 3.5 4.4 .4
2011-11-24 16:21:00 1 2.5 3.5 .4
2011-11-24 16:22:00 .6 1.8 2.3 .3
8 rows selected.
Adım 5 – Daha uzun zaman gemişi için AWR oluşturmak (saatlik)
Adım 4’ deki sorguyu, V$ACTIVE_SESSION_HISTORY tablosundan alınacak veriler yerine daha uzun zaman aralıklarına genişleme yapabilmek için aşağıdaki hale dönüştürüyorum.
· Yuvarlamayı dakika yerine saate çevirdik.
· Eski veriyi elde etmek için DBA_HIST_ACTIVE_SESS_HISTORY görünümünü referans aldık.
column sample_hour format a17
select
to_char(round(sub1.sample_time, 'HH24'), 'YYYY-MM-DD HH24:MI') as sample_hour,
round(avg(sub1.on_cpu),1) as cpu_avg,
round(avg(sub1.waiting),1) as wait_avg,
round(avg(sub1.active_sessions),1) as act_avg,
round( (variance(sub1.active_sessions)/avg(sub1.active_sessions)),1) as act_var_mean
from
( -- altsorgu 1: saniye başı bir satır, SAMPLE_TIME çözümü
select
sample_id,
sample_time,
sum(decode(session_state, 'ON CPU', 1, 0)) as on_cpu,
sum(decode(session_state, 'WAITING', 1, 0)) as waiting,
count(*) as active_sessions
from
dba_hist_active_sess_history
where
sample_time > sysdate - (&saat/24)
group by
sample_id,
sample_time
) sub1
group by
round(sub1.sample_time, 'HH24')
order by
round(sub1.sample_time, 'HH24');
Bunun yanında cputime-dbtime-usercalls-gets-awr-daytime.sql.txt sorgusu ile AWR raporundan her saat çekilen snapshotlar kullanılarak birer saatlik dilimlerde CPU kaynak tüketimi, bekleme süresi ve “buffer gets” ile “user calls” işyükü metirlkleri aşağıdaki gibi elde edilebilir.
SNAP_ID BEGIN_HOUR DB_CPU DB_TIME PCNT_CPU WAIT_ USER_CALLS BUFFER_
_CSPH _CSPH _UTILIZE CSPH _PH GETS_PH
------ --------------- ------- ------- -------- ------ ---------- -------
16554 2011-12-22 08:00 1251 375846 0 374595 133809 157182
16555 2011-12-22 09:00 1288 373080 0 371792 98995 175902
16556 2011-12-22 10:01 7847 399668 1 391821 65215 1578118
16557 2011-12-22 11:00 798 370192 0 369394 55754 212906
16558 2011-12-22 12:00 4249 403034 0 398785 247632 504779
16559 2011-12-22 13:00 10796 479532 1 468736 400502 1215195
16560 2011-12-22 14:00 7820 572684 1 564864 420180 542239
16561 2011-12-22 15:00 7555 476859 1 469304 458131 574445
16562 2011-12-22 16:00 6633 472670 0 466037 356792 421098
16563 2011-12-22 17:00 4724 423283 0 418559 282467 310253
16578 2011-12-23 08:00 2267 391711 0 389444 208237 336309
16579 2011-12-23 09:00 2677 404537 0 401860 325800 202084
16580 2011-12-23 10:00 3254 441378 0 438124 202435 278814
Bununda yanında, aşağıdaki sorgu kullanılarak belirli bir toplam işyükü yüzdesi üzerinde “DB CPU” süresine sahip snapshot aralıkları tespit edilebilir. Ortalama zaman ile ilgilenilmeyip, soruna ilk teşhis amacıyla yaklaşılacağı zamanlarda oldukça faydalı bir sorgudur ve AWR raporundan %45 üzerinde beklemeye sebebiyet veren “DB CPU” ile bekleme olaylarını getirmektedir. Sonuçtanda görüleceği üzere 24 ve 25 Aralık tarihlerinde 22.00 sırasında oldukça yüksek "DB CPU" beklemeleri olmuştur ve bu süreyi analiz edip neyin buna sebebiyet verdiğinin incelenmesi gerekecektir.
select s.begin_interval_time,m.* from
(select ee.instance_number,ee.snap_id,ee.event_name,round(ee.event_time_waited/1000000) event_time_waited,ee.total_waits,
round((ee.event_time_waited*100)/et.total_time_waited,1) pct,round((ee.event_time_waited/ee.total_waits)/1000) avg_wait
from (select ee1.instance_number,ee1.snap_id,ee1.event_name,ee1.time_waited_micro-ee2.time_waited_micro event_time_waited,
ee1.total_waits - ee2.total_waits total_waits
from dba_hist_system_event ee1 join dba_hist_system_event ee2
on ee1.snap_id = ee2.snap_id+1 and ee1.instance_number = ee2.instance_number and ee1.event_id = ee2.event_id
and ee1.wait_class_id <> 2723168908 and ee1.time_waited_micro-ee2.time_waited_micro > 0
union
select st1.instance_number,st1.snap_id,st1.stat_name event_name,st1.value - st2.value event_time_waited,1 total_waits
from dba_hist_sys_time_model st1 join dba_hist_sys_time_model st2 on st1.instance_number = st2.instance_number
and st1.snap_id = st2.snap_id + 1 and st1.stat_id = st2.stat_id and st1.stat_name='DB CPU'
and st1.value - st2.value > 0) ee join
(select et1.instance_number,et1.snap_id,et1.value - et2.value total_time_waited
from dba_hist_sys_time_model et1 join dba_hist_sys_time_model et2 on et1.snap_id=et2.snap_id+1
and et1.instance_number = et2.instance_number and et1.stat_id = et2.stat_id and et1.stat_name='DB time'
and et1.value - et2.value > 0 ) et
on ee.instance_number = et.instance_number and ee.snap_id = et.snap_id) m join dba_hist_snapshot s on m.snap_id = s.snap_id
where event_name like 'DB CPU' and pct>45
order by m.instance_number,m.snap_id,event_time_waited desc;
BEGIN_INTERVAL_TIME INSTANCE_NUMBER SNAP_ID EVENT_NAME EVENT_TIME_WAITED TOTAL_WAITS PCT AVG_WAIT
23-DECEMBER -2011 06:00:48,005 1 16576 DB CPU 12 1 55,2 12219
23-DECEMBER -2011 18:00:42,468 1 16588 DB CPU 6 1 76,8 5594
24-DECEMBER -2011 02:00:06,020 1 16596 DB CPU 5 1 69,7 4969
24-DECEMBER -2011 09:00:47,738 1 16603 DB CPU 5 1 74,9 5328
24-DECEMBER -2011 13:00:22,603 1 16607 DB CPU 6 1 77,7 6391
24-DECEMBER -2011 17:01:03,253 1 16611 DB CPU 6 1 71,5 6000
24-DECEMBER -2011 21:00:43,758 1 16615 DB CPU 7 1 76,8 7047
24-DECEMBER -2011 22:00:23,115 1 16616 DB CPU 101 1 73,2 100594
25-DECEMBER -2011 06:00:49,762 1 16624 DB CPU 6 1 76,2 6359
25-DECEMBER -2011 10:00:30,452 1 16628 DB CPU 5 1 66,4 5234
25-DECEMBER -2011 14:00:05,864 1 16632 DB CPU 6 1 70,8 6016
25-DECEMBER -2011 17:00:07,622 1 16635 DB CPU 2 1 46,4 2234
25-DECEMBER -2011 18:00:47,090 1 16636 DB CPU 3 1 57,5 2703
25-DECEMBER -2011 22:00:21,855 1 16640 DB CPU 105 1 76,1 104766
26-DECEMBER -2011 02:00:53,972 1 16644 DB CPU 6 1 65,2 6344
26-DECEMBER -2011 06:00:26,805 1 16648 DB CPU 5 1 67,4 5328
26-DECEMBER -2011 10:00:02,420 1 16652 DB CPU 5 1 57,3 5391
26-DECEMBER -2011 18:00:26,902 1 16660 DB CPU 3 1 65,1 3125
26-DECEMBER -2011 19:00:06,399 1 16661 DB CPU 2 1 53,8 2328
27-DECEMBER -2011 03:00:11,050 1 16669 DB CPU 7 1 70,1 6656
27-DECEMBER -2011 07:00:57,589 1 16673 DB CPU 6 1 76,2 5969
27-DECEMBER -2011 19:00:45,861 1 16685 DB CPU 7 1 83 7281
27-DECEMBER -2011 23:00:21,132 1 16689 DB CPU 7 1 54,8 7250
28-DECEMBER -2011 03:00:56,765 1 16693 DB CPU 6 1 63,6 5859
28-DECEMBER -2011 18:00:55,270 1 16708 DB CPU 6 1 66,8 6078
29-DECEMBER -2011 01:00:34,398 1 16715 DB CPU 4 1 49,8 3797
29-DECEMBER -2011 02:00:11,066 1 16716 DB CPU 7 1 68 6500
29-DECEMBER -2011 09:00:53,304 1 16723 DB CPU 5 1 50,2 5297
Referans:
1)Method-Gapp UKOUG 2011 - Predicting and Profiling of End-User Performance while Focussing on AWR Data
2) A Tour of the AWR Tables, Northern California Oracle Users' Group (NoCOUG) Summer Conference 2008, August 21 2008, Dave Abercrombie
3) Oracle Wait Interface: A Practical Guide to Performance Diagnostics & Tuning, Published 2004 McGraw-Hill Professional, 2004, Richmond Shee, Kirtikumar Deshpande, K. Gopalakrishnan
4) Average Session Load (ASL)The Golden Metric? , Kyle Hailey
0 yorum:
Yorum Gönder