Çeşitli tipte kuyruğa ekleme tipleri olmasından dolayı, bir kuyruğa ekleme bekleme olayı farklı sebeplerden meydana gelebilir. Yaygın sebepler ve bunlara karşı alınacak olan önlemler, farklı oturumlar tarafından çekişme yaşanan kuyruk ekleme tipine ve moduna göre değişmektedir. Oracle, her bir kuyruk ekleme tipi için X$KSQST yapısı içinde istek sayısı ve beklemelerin instance seviyesinde istatistiğini tutar.
select *
from v$enqueue_stat
where cum_wait_time > 0
order by inst_id, cum_wait_time;
INST_ID EQ TOTAL_REQ# TOTAL_WAIT# SUCC_REQ# FAILED_REQ# CUM_WAIT_TIME
---------- -- ---------- ----------- ---------- ----------- -------------
1 SQ 66551 437 66551 0 498
1 CU 64353 133 64353 0 1616
1 HW 453067 18683 453067 0 11811
1 CF 119748 76 119605 143 37842
1 TX 22687836 9480 22687758 71 672435
1 TC 3620 724 3620 0 679237
1 TM 89822967 91 89817200 5 4056333
Yukardaki alınan sonuç ile kullanıcıların hangi tip ve modda kuyruğa ekleme beklemeleri ile yüzyüze kaldığını tespit edebilirsiniz. Can acıtan nokta, kullanıcılar bu beklemeler sebebiyle herhangi bir hata mesajı almazlar ve oturumları donar. Zaten, arandığınızda söylenende oturumların ansızın donduğu ve cevap vermediği şeklindedir.
Tüm kuyruğa eklemeler hakkında detaya girmeyeceğim, çünkü bir kısmının gereksiz olduğunu düşünüyorum. Ancak, en sık ve yaygın karşılaşılan kuyruğa ekleme beklemelerine detaylı olarak aşağıda odaklanacağım.
Mod 6 TX kuyruğa ekleme bekleme olayı
Mod 6 TX kuyruğa ekleme beklemesi(P1= 1415053318, P1RAW= 54580006) en yaygın karşılaşılan kuyruğa ekleme bekleme olayıdır(Oracle Database 10g itibariyle enq: TX—row lock contention.) Bu bekleme olayı satır seviyesinde çakışma olduğuna işaret eder. Bu beklemeye olayı, satırlar bir işlem için kilitlendiği zaman, bu esnada başka bir işlemin aynı satırlara güncelleme veya silme işlemi yapmaya çalışmasında meydana gelir. Bu genellikle program tabanlı bir hatadır. Bu durumda bekleyen oturum, bloklayan oturumun işlemi için işleme(commit) veya geri alma (rollback) yapana kadar bekleyecektir. Kilidi, bloklayan oturumun sonlandırılması dışında, serbest bırakacak başka bir yol yoktur. Tabii, eğer bu bloklayan oturum sonlandırılırsa(kill) yaptığı işlem geri alınacak ve bu işleme bağlı girişlerde ortadan kalkacaktır. Bu genelde istenmez. Aşağıdaki liste mod 6 TX kuyruğa ekleme beklemesi için bir örnektir.
ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- --- -- ------ ------ ----- ------- ----- -----
A3950688 A395069C 10 TM 188154 0 3 0 3 0
-------- -------- --- -- ------ ------ ----- ------- ----- -----
A3950688 A395069C 10 TM 188154 0 3 0 3 0
A304E2A0 A304E2B0 10 TX 65585 147836 0 6 3 0
01AD23D4 01AD24A4 20 TX 65585 147836 6 0 10 1
A3950A28 A3950A3C 20 TM 188154 0 3 0 10 0
01AD23D4 01AD24A4 20 TX 65585 147836 6 0 10 1
A3950A28 A3950A3C 20 TM 188154 0 3 0 10 0
Ne zaman TX kuyruğa eklemesine bağlı bir bekleme olayı görülürse, ilk adım aşağıdaki sorguyu kullanarak, kimin blokladığını tespit etmek ve aynı kaynak için başka bekleyenlerin olup olmadığını görmektir. Eğer bloklayan oturum bir ad-hoc prosesi ise, o zaman bu kullanıcı bir mola verebilir. Bu durumda, bu bloklayan kullanıcının işleme(commit) veya geri alma ile kaynağı serbest bırakmasını talep edebilirsiniz. Eğer bloklayan bir OLTP uygulama prosesi veya batch ise, bu durumda oturumun hala aktif olup olmadığını kontrol edebilirsiniz. Eğer aktif bir oturumsa, bu durumdada alt proseslerinin ölü veya askıda olup olmadığını kontrol edebilirsiniz.
select /*+ ordered */
a.sid blocker_sid,
a.username blocker_username,
a.serial#,
a.logon_time,
b.type,
b.lmode mode_held,
b.ctime time_held,
c.sid waiter_sid,
c.request request_mode,
c.ctime time_waited
from v$lock b, v$enqueue_lock c, v$session a
where a.sid = b.sid
and b.id1 = c.id1(+)
and b.id2 = c.id2(+)
and c.type(+) = ’TX’
and b.type = ’TX’
and b.block = 1
order by time_held, time_waited;
a.sid blocker_sid,
a.username blocker_username,
a.serial#,
a.logon_time,
b.type,
b.lmode mode_held,
b.ctime time_held,
c.sid waiter_sid,
c.request request_mode,
c.ctime time_waited
from v$lock b, v$enqueue_lock c, v$session a
where a.sid = b.sid
and b.id1 = c.id1(+)
and b.id2 = c.id2(+)
and c.type(+) = ’TX’
and b.type = ’TX’
and b.block = 1
order by time_held, time_waited;
Ayrıca, çekişme yaşanan kaynağı ortaya çıkarabilirsiniz. Kaynak ID bilgisi, bu işlem için DML kilidinin(TM) V$LOCK.ID1 kolonunda yer almaktadır. Ayrıca, bekleyen oturumun V$SESSION.ROW_WAIT_OBJ# kolonundada bu bilgi yer alır. Aşağıdaki sorgu, TX kuyruğa ekleme bekleme olayının kaynağını listelemektedir.
select c.sid waiter_sid, a.object_name, a.object_type
from dba_objects a, v$session b, v$session_wait c
where (a.object_id = b.row_wait_obj# or
a.data_object_id = b.row_wait_obj#)
and b.sid = c.sid
and chr(bitand(c.P1,-16777216)/16777215) ||
chr(bitand(c.P1,16711680)/65535) = ’TX’
and c.event = ’enqueue’;
from dba_objects a, v$session b, v$session_wait c
where (a.object_id = b.row_wait_obj# or
a.data_object_id = b.row_wait_obj#)
and b.sid = c.sid
and chr(bitand(c.P1,-16777216)/16777215) ||
chr(bitand(c.P1,16711680)/65535) = ’TX’
and c.event = ’enqueue’;
Bununla beraber, bekleyen oturum tarafından çalıştırılan SQL komutu ile birlikte bloklayan oturum tarafından çalıştırılan SQL komutunuda ekstrakt ederek, hem bloklayan oturumun, hemde bekleyen oturumun ne tür bir işlem yaptığı hakkında detaylı bir fakir sahibi olabiliriz. Bu SQL komutlarının incelenmesi sonucunda, uygulama geliştiriciler hangi modüllerin çakışmalara sebep olduğunu teşhis edebilecek ve ilgili modüllerde düzeltici işlemler yapılabilecektir.
Mod 4 TX kuyruğa ekleme bekleme olayı - ITL eksikliği
Mod 4 TX kuyruğa ekleme bekleme olayı genellikle aşağıdaki sebeplerden birisi yüzünden meydana gelmektedir.
· Yetersiz blok alanı ve ITL (ilgili işlem listesi) eksikliği
· Farklı oturumlar tarafından aynı tekil(unique) anahtarın yazılması
· Bitmap indeks girişi
Bu bekleme olayına, bir veri bloğunda işlem yuvası olan ITL(İlgili İşlem Listesi) ile başlayacağım. ITL yuvalarının başlangıç sayısı INITRANS cümleciği tarafından tanımlanır ve MAXTRANS cümleciği ile sınırlandırılır. Varsayılan olarak, bir tablonun 1 ITL ve bir indeksin 2 ITL’i vardır. Her bir ITL 24 bytes ile çalışmaya başlar ve USN.SLOT#.WRAP#. formatı içinde işlem ID’sini içerir. Oracle 10g ile bu bekleme olayı, enq: TX—allocate ITL entry olarak yeniden adlandırılmıştır.
Veri değişikliğe uğramanda önce, her DML işlemi blok içindeki kendi ITL alanını elde eder. Bu ITL için çakışma olayı blok içindeki tüm uygun ITL’ler halihazırda kullanımda olduğunda(yani MAXTRANS değerine erişildiğinde) ve Oracle için dinamik olarak yeni bir ITL yuvası tahsisi için PCTFREE alanında yeterli alan kalmadığında meydana gelir. Bu durumda, işlemlerden birisi işlenmeden(commit) veya geri alınmadan(rollback) oturum bekleyecek ve bu ITL yuvasını tekrar kullanacaktır. ITL bir alışveriş merkezinin otopark alanı gibidir. Alışveriş merkezine arabasıyla gelen her müşteri boş park yeri arar, eğer otopark alanında boş yer yoksa birisi otoparktan çıkana kadar otopark alanı etrafında bulmak umuduyla turlar.
ITL yetersizliği sebebiyle oluşan Mod 4 TX kuyruğa ekleme bekleme olayı için bir örnek yer almaktadır.
ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- --- -- ------ ------ ----- ------- ----- -----
8A2B6400 8A2B6414 8 TM 3172 0 3 0 248 0
-------- -------- --- -- ------ ------ ----- ------- ----- -----
8A2B6400 8A2B6414 8 TM 3172 0 3 0 248 0
89EF3A0C 89EF3A1C 8 TX 131147 13 0 4 248 0
01A4177C 01A41848 9 TX 131147 13 6 0 376 1
8A2B6388 8A2B639C 9 TM 3172 0 3 0 376 0
8A2B6388 8A2B639C 9 TM 3172 0 3 0 376 0
Mod 4 TX kuyruğa ekleme bekleme olayı her zaman ITL yetersizliği sebebiyle oluşmaz. Bekleyen oturumun V$SESSION satırı kuyruğa ekleme nesnesi hakkında bilgi içermektedir. Kolonlar ROW_WAIT_FILE# ve ROW_WAIT_BLOCK# ‘dir. Bu değerleri kullanarak bloğun içeriğini görüntüleyebilir, blok içindeki aktif ITL sayısını(--U--) görebilir ve böylece sorunun ITL’den kaynaklanıp kaynaklanmadığına karar verebiliriz. Eğer sorun ITL’den kaynaklanıyorsa, bu objeye ait segment daha yüksek bir INITRANS değeri ile veya daha yüksek bir PCTFREE değeri ile yeniden oluşturularak sorun çözülür.
alter system dump datafile <file#> block <block#>;
Alttaki örnekte ,blok içeriğinde görüntülenen ITL kullanan bölüm kırmızı 2 satırda yer almaktadır. Yani INITRANS değerinden 2 ITL kullanılmış, 2 ITL ise daha kullanılmamıştır (C--)
Alttaki örnekte ,blok içeriğinde görüntülenen ITL kullanan bölüm kırmızı 2 satırda yer almaktadır. Yani INITRANS değerinden 2 ITL kullanılmış, 2 ITL ise daha kullanılmamıştır (C--)
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x000a.051.0001fcf2 0x07ca2145.4e11.18 --U- 0 scn 0x070e.03df2f08
0x02 0x0005.049.00022d46 0x090618b7.5967.1c C--- 0 scn 0x070e.03df2f6a
0x03 0x0012.008.0001244b 0x0580a510.26ac.0c --U- 0 scn 0x070e.03df2f7b
0x04 0x0014.00d.00012593 0x090d4f93.28d3.1e C--- 0 scn 0x070e.03e08919
Oracle 9i itibariyle nesne bazlı ITL bekleme sayısı izlemeleri saklanmakta ve V$SEGMENT_STATISTICS görünümünde bu bilgi yayınlanmaktadır. Veritabanındaki önemli ITL beklemelerini görmek için aşağıdaki sorgu kullanılabilir:
select owner,
object_name,
subobject_name,
object_type,
tablespace_name,
value,
statistic_name
from v$segment_statistics
where statistic_name = ’ITL waits’
and value > 0
order by value;
object_name,
subobject_name,
object_type,
tablespace_name,
value,
statistic_name
from v$segment_statistics
where statistic_name = ’ITL waits’
and value > 0
order by value;
Mod 4 TX kuyruğa ekleme bekleme olayı - Tekil Anahtar Kullanımı
Tekil veya birincil anahtar kullanımı Mod 4 TX kuyruğa ekleme bekleme olayının diğer bir sebebidir. Oracle 10g itibariyle bu bekleme olayının adı enq: TX—row lock contention olmuştur. Bu bekleme olayı bir veya birden fazla tekil anahtar kısıtlaması içeren bir tabloya, bir çok oturumun eşzamanlı olarak aynı değeri girmesiyle meydana gelir. İlk oturum değeri başarıyla girer, ancak “ORA-00001 unique constraint (%s.%s) violated” hatası alınmasıyla beraber geri kalanların işlemi donar ve ilk oturum işleme(commit) veya geri alma (rollback) yapana kadar geri kalanlar bekler.
Aşağıdaki örnekte görüldüğü gibi, tekil anahtar kullanımı sebebiyle oluşan Mod 4 TX kuyruk ekleme beklemesi V$LOCK görünümünde listelenmiştir. Peki o zaman tekil anahtra kullanımı ve ITL yetersizliği arasındaki farklılık nedir?
SID=8 olan bekleyenin iki tane TX girişi olduğuna dikkat edin. Bu demek değildirki SID=8, iki tane işleme sahiptir. Aslında, V$TRANSACTION sadece iki adet işlem göstermektedir, birisi SID 8’e ait, diğeri ise SID 9’a ait. Aşağıdaki liste bize, SID 8’in, SID 9 tarafından tutulan TX kilidini beklediğini göstermektedir ve SID 8, nesne üzerinde paylaşımlı kilidi(Mod 4) talep etmektedir. SID 8, aynı zamanda kendi işlemi içinde TX kilidi tutmaktadır. Bunun yanında, her zaman DML işleminin ID1’inde kayıtlı nesne ID’sinde dikkat edilmesi gereken nokta,-tekil anahtarın indeks üzerinde zorlanmasına rağmen- tablo ID’sidir, indeks ID’si değil. BLOCK kolonunda 1 değeri bloklayan, 0 değeri olan ise bekleyendir.
SID=8 olan bekleyenin iki tane TX girişi olduğuna dikkat edin. Bu demek değildirki SID=8, iki tane işleme sahiptir. Aslında, V$TRANSACTION sadece iki adet işlem göstermektedir, birisi SID 8’e ait, diğeri ise SID 9’a ait. Aşağıdaki liste bize, SID 8’in, SID 9 tarafından tutulan TX kilidini beklediğini göstermektedir ve SID 8, nesne üzerinde paylaşımlı kilidi(Mod 4) talep etmektedir. SID 8, aynı zamanda kendi işlemi içinde TX kilidi tutmaktadır. Bunun yanında, her zaman DML işleminin ID1’inde kayıtlı nesne ID’sinde dikkat edilmesi gereken nokta,-tekil anahtarın indeks üzerinde zorlanmasına rağmen- tablo ID’sidir, indeks ID’si değil. BLOCK kolonunda 1 değeri bloklayan, 0 değeri olan ise bekleyendir.
ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- --- -- ------ ----- ----- ------- ----- -----
01AF6120 01AF61EC 8 TX 131099 14 6 0 4051 0
8A2B6388 8A2B639C 8 TM 3176 0 3 0 4051 0
89EF37CC 89EF37DC 8 TX 131094 14 0 4 4051 0
01AF6120 01AF61EC 9 TX 131094 14 6 0 4461 1
8A2B6400 8A2B6414 9 TM 3176 0 3 0 4461 0
-------- -------- --- -- ------ ----- ----- ------- ----- -----
01AF6120 01AF61EC 8 TX 131099 14 6 0 4051 0
8A2B6388 8A2B639C 8 TM 3176 0 3 0 4051 0
89EF37CC 89EF37DC 8 TX 131094 14 0 4 4051 0
01AF6120 01AF61EC 9 TX 131094 14 6 0 4461 1
8A2B6400 8A2B6414 9 TM 3176 0 3 0 4461 0
Bunun yanında kimin kimi blokladığını net şekilde raporlamakta mümkündür.
SQL> select s1.username || '@' || s1.machine
|| ' ( SID=' || s1.sid || ' ) is blocking '
|| s2.username || '@' || s2.machine || ' ( SID=' || s2.sid || ' ) ' AS blocking_status
from v$lock l1, v$session s1, v$lock l2, v$session s2
where s1.sid=l1.sid and s2.sid=l2.sid
and l1.BLOCK=1 and l2.request > 0
and l1.id1 = l2.id1
and l2.id2 = l2.id2 ;
BLOCKING_STATUS
-----------------------------------------------------------------
trant12@antnb201 ( SID=9 ) is blocking trant43@antnb162 ( SID=8 )
Alınacak eylemler daha önce açıkladığım Mod 6 ile aynıdır; kimin blokladığını tespit etmek, hangi kaynak için çakışma yaşandığını bulmak, bekleyen ve bloklayan oturumların çalıştırdığı SQL komutlarının yapısını incelemek... Bu sorun, uygulama katmanında yaşanan bir sorundur ve kullanılan uygulama içerisinden uygulama geliştiriciler tarafından düzeltilmelidir.
Mod 4 TX kuyruğa ekleme bekleme olayı - Bitmap indeks girişi
Mod 4 TX kuyruğa ekleme bekleme olayı ayrıca, bitmap girişi tarafından kapsanmış değişik satırların bir çok oturum tarafından güncellenme veya silinme denemelerinde oluşabilir. Uygulama, bitmap indeksler kullanmıyorsa bu bekleme olayıda olmaz.
Tekil ROWID içeren B-tree indeks girişlerinden farklı olarak, bir bitmap girişi geniş ROWID dağılım aralığını kapsar. Böylece bir bitmap indeksi kilitlendiğinde, giriş tarafından kapsanan tüm ROWID lerde kilitlenir.
Aşağıdaki örnekte, bitmap girişi sebebiyle meydan gelen mod TX bekleme olayı V$LOCK görünümünden elde edilmektedir. Peki, aşağıdaki çıktının yukardaki tekil anahtar kullanımı örneğinden ne farkı vardır?
V$LOCK görünümü sonucuna bakarak Mod 4 TX kuyruk ekleme bekleme olayının bitmap indeks girişindenmi, yoksa tekil anahtar kullanımındanmı kaynaklandığı anlaşılırmı? Bunun cevabı HAYIR’dır. TM kilidindeki obje ID’side, tablonun obje ID’si olduğundan dolayı yardımcı olamaz. İşte bu sebeple, bloklayan ve bekleyen oturumların SQL komutlarını yakalamak ve bunlara bakmak önem kazanmaktadır.Eğer bekleyen oturum INSERT işlemi yapıyorsa, o zaman tekil anahtar kullanım sorunu yaşanmaktadır. Eğer bekleyen oturum UPDATE veya DELETE işlemi yapıyorsa, büyük ihtimalle bitmap giriş sorunu yaşanmaktadır.
V$LOCK görünümü sonucuna bakarak Mod 4 TX kuyruk ekleme bekleme olayının bitmap indeks girişindenmi, yoksa tekil anahtar kullanımındanmı kaynaklandığı anlaşılırmı? Bunun cevabı HAYIR’dır. TM kilidindeki obje ID’side, tablonun obje ID’si olduğundan dolayı yardımcı olamaz. İşte bu sebeple, bloklayan ve bekleyen oturumların SQL komutlarını yakalamak ve bunlara bakmak önem kazanmaktadır.
ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- --- -- ------ ----- ----- ------- ----- -----
01A52DB4 01A52E80 7 TX 131120 14 6 0 31 1
8A2B6310 8A2B6324 7 TM 3181 0 3 0 31 0
01A52DB4 01A52E80 9 TX 131107 14 6 0 9 0
8A2B6388 8A2B639C 9 TM 3181 0 3 0 9 0
89EF3A4C 89EF3A5C 9 TX 131120 14 0 4 9 0
-------- -------- --- -- ------ ----- ----- ------- ----- -----
01A52DB4 01A52E80 7 TX 131120 14 6 0 31 1
8A2B6310 8A2B6324 7 TM 3181 0 3 0 31 0
01A52DB4 01A52E80 9 TX 131107 14 6 0 9 0
8A2B6388 8A2B639C 9 TM 3181 0 3 0 9 0
89EF3A4C 89EF3A5C 9 TX 131120 14 0 4 9 0
0 yorum:
Yorum Gönder