模擬mode=4 and name='TX'的enqueue

hanson發表於2019-06-17

事情源於一個朋友問到,他的生產庫中出現很多enqueue等待。重啟應用後沒多久,又出現這些等待。於是,我先讓他執行以下語句,先找到enqueue的mode和name:

select sid,
chr(bitand(p1, -16777216)/16777215) ||
chr(bitand(p1,16711680)/65535) "Name",
(bitand(p1, 65535)) "Mode"
from v$session_wait
where event = 'enqueue';

[@more@]

然後他告訴我,mode為4,name為TX。

這是基本上可以確定應該是由於ITL過低而引起的。ITL由兩個引數決定:init trans和max trans。通常table的max trans為255,應該不會超過。而init trans預設是2,該值在併發性較大的table上顯然不夠用。所以我告訴他,應該是init trans過低引起的。

如何證明?我想,兩種方法:一種是讓3個人同時喊一、二、三,大家同時更新同一個表的同一個block裡的不同行。這實現起來比較麻煩。還有一種方法就是將max trans降低,比如降低到3。然後開4個session去更新同一個表的同一個block裡的不同行。應該可以復現這種情況。

SQL> create table t as select object_name,object_type from user_objects where rownum<10;

表已建立。

SQL> alter table t maxtrans 3;

表已更改。

SQL> select ini_trans,max_trans from user_tables where table_name='T';

INI_TRANS MAX_TRANS
---------- ----------
1 3

然後開4個session,分別提交以下sql語句:

SQL> update t set object_type='aaa' where object_name='ADD_JOB_HISTORY';

已更新 1 行。

可以發現第四個session發生等待。於是再開第五個session,執行如下sql:

select sid,
chr(bitand(p1, -16777216)/16777215) ||
chr(bitand(p1,16711680)/65535) "Name",
(bitand(p1, 65535)) "Mode"
from v$session_wait
where event = 'enqueue';

SID Name Mode
---------- ---- ----------
10 TX 4

從而可以復現該現象,從而從側面證明,由於ITL過低會導致mode為4,name為TX的enqueue等待。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9842/viewspace-850634/,如需轉載,請註明出處,否則將追究法律責任。

相關文章