天天看點

鎖等待分析處理

  1. 鎖的作用及影響

  鎖是Oracle管理共享資料庫資源并發通路并防止并發資料庫事務之間“互相幹涉”的核心機制之一。

當應用系統複雜、業務量大時,經常會出現應用程序之前的鎖等待現象,影響系統正常運作。當資料庫出現鎖等待的情況下快速定位阻塞程序,分析阻塞原因。

  1. 定位鎖類型

資料庫的鎖有多種類型,每種不同的類型對業務的影響是不一樣的,大緻可分為以下三類:

DML鎖

DDL鎖

内部鎖與LATCH鎖

下面給出每種不同類型的鎖的定位分析過程,各種鎖處理流程如下:

2.1、 DML鎖

鎖等待分析處理

1、 TX鎖與行鎖

TX鎖不是行鎖,一個事務不管修改了多少行,都隻會有一個TX鎖。TX鎖算是行鎖的代表,行鎖上發生了等待,會表現為TX鎖的等待。行鎖是屬于事務的,事務開始,行鎖産生,事務結束,行鎖也被釋放。

2、 行級鎖對應用的影響比較小,一般隻會影響部份業務或某個特殊的程序。

3、 模拟重制TX鎖

(1)會話181執行如下操作:

gyj@OCM>select distinct sid from v$mystat;

SID           
181           

gyj@OCM>update t1 set name ='gyj111' where id=1;

1 row updated.

修改t1表中的id=1這行記錄,不送出。

(2)會話179執行如下操作:

SID           
179           

修改t1表id=1這行記錄,這裡被阻塞

(3)使用以下腳本查找資料庫中的行級鎖資訊:

gyj@OCM> col username for a10

gyj@OCM> col program for a25

gyj@OCM> col sid for 9999

gyj@OCM> col SERIAL# for 9999

gyj@OCM> col BLOCKING_INSTANCE for 99

gyj@OCM>select sid,serial#,username,program,status,sql_id, blocking_instance,blocking_session

2 from v$session where event='enq: TX - row lock contention';

SID SERIAL# USERNAME PROGRAM STATUS SQL_ID BLOCKING_INSTANCE BLOCKING_SESSION

179 241 GYJ sqlplus@ocm (TNS V1-V3) ACTIVE gxzu79ffmrp35 1 181

(4)輸出結果說明:

SID: TX鎖等待的SID号

SERIAL#: TX鎖等待程序的序列号

USERNAME: 資料庫使用者

PROGRAM: 程序程式名

STATUS: 程序狀态

SQL_ID: 正在執行的SQL語句

BLOCING_INSTANCE :阻塞程序所在的執行個體

BLOCING_SESSION: 阻塞程序SID号

可以得到鎖等待程序資訊,及阻塞者的SID (注意在RAC中通過blocking_session得到的SID需要減去1,才是實際的SID) 。

4、 查找阻塞者程序資訊

gyj@OCM> col event for a30gyj@OCM> select sid,serial#,username,program,status,sql_id,event from v$session where sid='&sid';Enter value for sid: 181old 1: select sid,serial#,username,program,status,sql_id,event from v$session where sid='&sid'new 1: select sid,serial#,username,program,status,sql_id,event from v$session where sid='181'SID SERIAL# USERNAME PROGRAM STATUS SQL_ID EVENT----- ------- ---------- ------------------------- -------- ------------- ------------------------------181 236 GYJ sqlplus@ocm (TNS V1-V3) INACTIVE SQL*Net message from client

SID:阻塞程序的SID号輸出結果說明:

SERIAL#:阻塞程序的序列号

USERNAME:資料庫使用者

PROGRAM:程序程式名

STATUS:程序狀态

SQL_ID:正在執行的SQL語句

EVENT:阻塞程序的等待事件

上述程序的的STATUS為INACTIVE,參考處理流程,直接跳到第7步執行。

5、 如果阻塞者程序為ACTIVE狀态,查找阻塞者程序正在執行的SQL語句

gyj@OCM> select sql_text from v$sqltext where sql_id='gxzu79ffmrp35';

SQL_TEXT

update t1 setname='aaaaaaa' where id=1

6、 如果阻塞者程序為ACTIVE狀态,查找阻塞者程序SQL語句執行計劃

gyj@OCM> select * from table(dbms_xplan.display_cursor(‘gxzu79ffmrp35’));

PLAN_TABLE_OUTPUT

SQL_ID f9mwduaxs47kk, child number 0

Plan hash value:2927627013

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

| 0 | UPDATE STATEMENT | | | | 3 (100)| |

| 1 | UPDATE | T1 | | | | |

|* 2 | TABLE ACCESS FULL| T1 | 1 | 65 | 3 (0)| 00:00:01 |

PredicateInformation (identified by operation id):

2 - filter("ID"=1)

Note

  • dynamic sampling used for this statement(level=2)

23 rows selected.

7、 分析阻塞原因

TX鎖阻塞原因一般有兩種,一種是阻塞程序沒有及時送出事務;另一種是阻塞程序SQL語句執行緩慢。對于第一種情況可找到相關程序結束程序事務,釋放鎖資源。第二種情況通過分析SQL語句執行計劃,找到SQL執行緩慢的原因,提供優化建議,要求開發人員優化SQL語句。

8、 若情況緊急,可與項目經理和開發人員确認後終止阻塞者程序,釋放鎖資源。

9、 TM鎖這裡就不詳細說了網上資料很多。

2.2、 DDL鎖

鎖等待分析處理

引用DSI405中的圖

1、 對象鎖等待,一般發生在重編譯存儲過程等對象維護時,相關對象的library cache pin等待。發生該種鎖等待時,長時間無法完成存儲過程編譯。

2、 使用下面的腳本查到對象鎖等待的程序資訊

selectsid,serial#,username,program,status,sql_id from v$session where event like'library cache%';

輸出結果如下:

SID   SERIAL# USERNAME                      PROGRAM                                          STATUS   SQL_ID       EVENT           
6577        456  GYJ                        sqlplus@ocm(TNS V1-V3)                 INACTIVE 1h3aq2wzhn5n6 SQL*Net message from client           

輸出結果說明:

SID:阻塞程序的SID号

3、 使用下面語句查找阻塞程序資訊

select Distinct /+ ordered / w1.sid waiting_session,

h1.sid holding_session,

w.kgllktype lock_or_pin,

od.to_owner object_owner,

od.to_name object_name,

oc.Type,

decode(h.kgllkmod, 0, 'None', 1, 'Null', 2, 'Share', 3, 'Exclusive',

'Unknown') mode_held,

decode(w.kgllkreq, 0, 'None', 1, 'Null', 2, 'Share', 3, 'Exclusive',

'Unknown') mode_requested,

xw.KGLNAOBJ wait_sql,xh.KGLNAOBJ hold_sql

from dba_kgllock w, dba_kgllock h, v$session w1,

v$session h1,v$object_dependency od,V$DB_OBJECT_CACHE oc,x$kgllkxw,x$kgllk xh

where

(((h.kgllkmod != 0) and (h.kgllkmod != 1)

and ((h.kgllkreq = 0) or (h.kgllkreq = 1)))

and

(((w.kgllkmod = 0) or (w.kgllkmod= 1))

and ((w.kgllkreq != 0) and (w.kgllkreq != 1))))

and w.kgllktype = h.kgllktype

and w.kgllkhdl = h.kgllkhdl

and w.kgllkuse = w1.saddr

and h.kgllkuse = h1.saddr

And od.to_address = w.kgllkhdl

And od.to_name=oc.Name

And od.to_owner=oc.owner

And w1.sid=xw.KGLLKSNM

And h1.sid=xh.KGLLKSNM

And (w1.SQL_ADDRESS=xw.KGLHDPAR And w1.SQL_HASH_VALUE=xw.KGLNAHSH)

And (h1.SQL_ADDRESS=xh.KGLHDPAR And h1.SQL_HASH_VALUE=xh.KGLNAHSH)

    WAITING_SESSION HOLDING_SESSION LOCK_OR_PIN OBJECT_OWNER OBJECT_NAME TYPE MODE_HELD MODE_REQUESTED WAIT_SQL HOLD_SQL

    ---------- ---------------------------------------- -------------------------------------------------------- -----------------------------------------------------------------------------

20 45 Lock SUK P_SLEEP PROCEDURE Exclusive Exclusive grant execute on p_sleep to system grant execute on p_sleep to system

WAITING_SESSION:被阻塞程序号

HOLDING_SESSION:阻塞程序号

LOCK_OR_PIN:鎖類型

OBJECT_OWNER:被鎖對象屬主

OBJECT_NAME:被鎖對象名

TYPE:鎖定類别

MODE_HELD:阻塞模式

MODE_REQUESTED:請求模式

WAIT_SQL:被阻塞程序正在執行的SQL

HOLD_SQL:阻塞程序正在執行的SQL

select sid,serial#,username,program,status,sql_id,eventfrom v$session where sid=’&sid’;

5、 查找阻塞者程序正在執行的SQL語句

select sql_text from v$sqltextwhere sql_id=’&sql_id’ order by piece;

6、 查找阻塞者程序SQL語句執行計劃

select * fromtable(dbms_xplan.display_cursor(‘&sql_id’));

對象鎖阻塞一般在使用PL/SQL DEV等工具程序相關對象操作時容易引發該種鎖等待。正常的業務事務不會導緻該種等待事件發生。

2.3、 LATCH鎖

鎖等待分析處理

1、 資料庫級别的LATCH鎖,往往是由于性能不良的應用程式程序,長時間持有相關LATCH不釋放引起。引如熱點塊問題,資料庫運作異常緩慢,資料庫HANG住等問題。

2、 對于熱點塊問題,使用下面語句查找熱點塊競争的程序資訊,并将相關資訊送出開發人員,要求分析避免資料的熱點通路

selectsid,serial#,username,program,status,sql_id from v$session where event like'%cache buffers chains%';

輸出結果如下所示:

SID SERIAL# USERNAME PROGRAM STATUS SQL_ID

3054 41415 GYJ sqlplus@ocm (TNS V1-V3) ACTIVE 1h3aq2wzhn5n6

7029 51613 GYJ sqlplus@ocm (TNS V1-V3) ACTIVE 1h3aq2wzhn5n6

3064 16713 GYJ sqlplus@ocm (TNS V1-V3) ACTIVE 1h3aq2wzhn5n6

6089 30813 GYJ sqlplus@ocm (TNS V1-V3) ACTIVE 1h3aq2wzhn5n6

3055 50213 GYJ sqlplus@ocm (TNS V1-V3) ACTIVE 1h3aq2wzhn5n6

3、 檢查資料庫latch鎖等待程序數,如果資料超過50個,并不斷增加,則可能導緻資料庫異常緩慢甚至hang住。用下面語句檢查latch等待程序數。

sys@OCM>select sid,serial#,username,program,status,sql_id from v$session where eventlike '%latch%';

SID   SERIAL# USERNAME                      PROGRAM                                          STATUS   SQL_ID           
181          2 GYJ                            sqlplus@ocm (TNSV1-V3)                          ACTIVE   1h3aq2wzhn5n6
           

4、 取得資料庫hang analyze trace

sqlplus'/as sysdba'

oradebugsetmypid

oradebugsetinst all;

oradebug-g def hanganalyze 3

5、 分析資料庫hang analyze trace 資訊,找出阻塞程序的源頭

6、 如果資料庫還能查v$session程序資訊,則查找出源頭程序的相關資訊及SQL語句。

selectb.spid,a.sid,a.serial#,a.program,a.machine,a.sql_id,a.event,a.PREV_SQL_ID fromv$session a,v$process b wherea.paddr=b.addr and a.sid=&sid;

7、 用下面的方法對源頭程序做DUMP。

$sqlplus '/ as sysdba'

SQL>oradebug setospid xxx (作業系統程序ID)

SQL>oradebug unlimit

SQL>oradebug dump processstate 10

SQL>exit

DUMP出來的檔案在USER_DUMP_DEST所指向的目錄,将相關檔案取出,并送出ORACLE分析。

8、 與項目經理和開發人員确認後,中止源頭程序。資料庫可恢複正常。

9、 分析源頭程序資訊,獲得阻塞原因,如SQL語句執行緩慢,程序未及時結束事務等。并提供優化建議,提給開發人員改進。