OS環境:windows server 2008 64位
數據庫版本:11.2.0
今天在使用rman備份的時候隨意的查看了一下等待事件,除了了我們現在系統遇到的IO瓶頸外,還額外的發了enq: TX - row lock contention該等待事件
1:查詢當前系統的等待事件
select event,sid,p1,p2,p3 from v$session_wait where event not like 'SQL*%' and event not like 'rdbms%';
EVENT SID P1 P2 P3
---------------------------------- ---- ---------- ---------- ----------
enq: TX - row lock contention 4 1415053318 196638 55836
RMAN backup & recovery I/O 5 1 256 2147483647
enq: TX - row lock contention 12 1415053318 524293 51153
RMAN backup & recovery I/O 25 1 256 2147483647
db file sequential read 27 16 2876703 1
pmon timer 33 300 0 0
db file scattered read 39 33 790536 128
VKTM Logical Idle Wait 49 0 0 0
Streams AQ: qmn slave idle wait 50 1 0 0
asynch descriptor resize 53 1 4294967295 1237
jobq slave wait 54 0 0 0
EVENT SID P1 P2 P3
------------------------------------------- ------- ---------- ----------
db file sequential read 170 33 1100519 1
direct path read 181 44 469892 124
enq: TX - row lock contention 212 1415053318 524293 51153
smon timer 225 300 0 0
enq: TX - row lock contention 232 1415053318 524293 51153
direct path read 234 16 1099776 128
Streams AQ: qmn coordinator idle wait 242 0 0 0
上面的等待事件說明session4,12,212,232想加鎖,但是有別的session占著,所以等待。
enq是一種保護共享資源的鎖定機制,一個排隊機制,先進先出(FIFO)
發生TX鎖的原因一般有幾個
1.不同的session更新或刪除同一個記錄。
2.唯一索引有重復索引
3.位圖索引多次更新
4.同時對同一個數據塊更新
5.等待索引塊分裂
2:下面我們通過enq: TX - row lock contention來看看這些session都在等什么
select ROW_WAIT_OBJ#,ROW_WAIT_FILE#,ROW_WAIT_BLOCK#,ROW_WAIT_ROW# from v$session where event='enq: TX - row lock contention';
ROW_WAIT_OBJ# ROW_WAIT_FILE# ROW_WAIT_BLOCK# ROW_WAIT_ROW#
------------- -------------- --------------- -------------
87556 57 395 88
87564 57 435 0
87564 57 435 0
87564 57 435 0
87564 57 435 0
3:通過上面sql查找出來的對象編號找到對應的對象名稱
SQL> select object_name from dba_objects where object_id in (87564);
OBJECT_NAME
-----------
QRTZ_LOCKS
4:通過對象名稱找出該對象的對應屬性,對象屬性為TABLE
SQL> select OWNER,OBJECT_NAME,OBJECT_ID,DATA_OBJECT_ID, OBJECT_TYPE from all_objects where object_name='QRTZ_LOCKS';
OWNER OBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
SCHEDULE QRTZ_LOCKS 87564 87564 TABLE
5:通過正在等待的SID查看它們都在執行什么操作
SQL> select sid,sql_text from v$session a,v$sql b where sid in(4,12,41,212,232) and (b.sql_id=a.sql_id or b.sql_id=a.prev_sql_id);
SID SQL_TEXT
---- ----------------------------------------------------------------------------------------------------
4 UPDATE QRTZ_CRON_TRIGGERS SET CRON_EXPRESSION = :1 WHERE TRIGGER_NAME = :2 AND TRIGGER_GROUP = :3
12 SELECT * FROM QRTZ_LOCKS WHERE LOCK_NAME = :1 FOR UPDATE
41 SELECT * FROM QRTZ_LOCKS WHERE LOCK_NAME = :1 FOR UPDATE
212 SELECT * FROM QRTZ_LOCKS WHERE LOCK_NAME = :1 FOR UPDATE
232 SELECT * FROM QRTZ_LOCKS WHERE LOCK_NAME = :1 FOR UPDATE
從上面的結果可以看出,SCHEDULE用戶下的五個session同時在執行一條相同的sql語句,對應的對象則是QRTZ_LOCKS 這個表, 所以發生了鎖,從而產生等待,通過和同事的交流,得知這個一個ETL程序要訪問的表,里面只有五條數據,但是卻要時時調度。
6:下面我們去找一下對應sid產生的鎖
SQL> select SID,TY,ID1,ID2,LMODE,REQUEST,CTIME,BLOCK from V$lock where block=1 or request<>0;
SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
---------------- ---- -- ---------- ---------- ---------- ---------- ---------- ----------
41 TX 524293 51153 0 6 3846 0
12 TX 524293 51153 0 6 4190 0
232 TX 524293 51153 0 6 4626 0
212 TX 524293 51153 0 6 4749 0
4 TX 196638 55836 0 6 4755 1
44 TX 196638 55836 6 0 4765 1
由此可以查看,BLOCK=1的sid是該等待事件的根源,其他session則等待該鎖被釋放。
解決方法:
1:通過v$session找到BLOCK=1的用戶,告知用戶提交事務
2:通過sid找到pid,kill掉該進程
3:更改sql語句,SELECT * FROM QRTZ_LOCKS WHERE LOCK_NAME = :1 FOR UPDATE no wait
加nowait的意思是得到或者得不到,不會等待
posted on 2015-03-20 15:20
壞男孩 閱讀(1565)
評論(0) 編輯 收藏 所屬分類:
ORACLE篇章