天天看點

ORACLE等待事件:enq: TX - row lock contention

enq: TX - row lock contention等待事件,這個是資料庫裡面一個比較常見的等待事件。enq是enqueue的縮寫,它是一種保護共享資源的鎖定機制,一個排隊機制,先進先出(FIFO)。enq: TX - row lock contention等待事件,OACLE将其歸類為application級别的等待事件。有些場景是因為應用邏輯設計不合理造成的。下面我們看看enq: TX - row lock contention的英文介紹:

This wait indicates time spent waiting for a TX lock, typically due to waiting to gain access to a row in a table that is currently locked by that transaction. The TX lock waited on is "TX-P2RAW-P3RAW" and the object / row that triggered the wait can usually be found in the ROW_WAIT_* columns of V$SESSION for the waiting session.

A TX lock is acquired when a transaction initiates its first change and is held until the transaction does a COMMIT or ROLLBACK. It is used mainly as a queuing mechanism so that other sessions can wait for the transaction to complete. The lock name (ID1 and ID2) of the TX lock reflect the transaction ID of the active transaction.

下面我們模拟一下enq: TX - row lock contention等待事件出現的場景,希望能對這個等待事件有較深的了解,主要參考了官方文檔 ID 62354.1

<b>1</b><b>:</b><b> Waits due to Row being locked by an active Transaction</b>

<b></b>

這個是因為不同的session同時更新或删除同一個記錄。例如,會話1持有row level lock,會話2在等待這個鎖釋放。準備測試環境和資料

會話1(會話ID為75)更新某一行

會話2(會話ID為200)也更新這一行(删除亦可)

在會話3中檢視對應的會話、鎖以及等待相關資訊,這些SQL各

<a href="http://images2015.cnblogs.com/blog/73542/201609/73542-20160919232525902-1824482175.png"></a>

此時隻能等待持有鎖的會話commit或者rollback。 通常為會話1在某行上執行 update/delete 未送出,會話2對同一行資料進行 update/delete,或其它原因(例如SQL性能差)造成的鎖釋放速度緩慢或網絡問題,都會造成後續的會話進入隊列等待。

<b>2</b><b>:</b><b>Waits due to Unique or Primary Key Constraint Enforcement</b>

表上存在主鍵或唯一索引,會話1插入一個值(未送出),會話2同時或随後也插入同樣的值;會話送出後1,enq: TX - row lock contention消失。

會話1(會話ID為8)

會話2(會話ID為14)

會話3 在會話3中檢視對應的會話、鎖、以及等待資訊

會話1(會話ID為8)送出事務後

會話2(會話ID為14)遇到ORA-00001錯誤提示

這個在ORACLE 10g以及以上版本都無法測試(Oracle 9i可以測試),因為ORACLE 10g中,對于單個資料塊,Oracle預設最大支援255個并發,MAXTRANS參數在ORACLE 10g以及以上版本被廢棄了,即使你使用下面SQL指定了maxtrans為1, 但是你檢視表的定義,你會發現maxtrans依然為255。

是以這個場景隻會發生在ORACLE 9i的版本中或是并發非常高的系統當中。

<b></b> 

<b>Waits due to rows being covered by the same BITMAP index fragment</b>

這個源于位圖索引的特性,更新位圖索引的一個鍵值,會指向多行記錄,是以更新一行就會把該鍵值指向的所有行鎖定

<b>其它場景</b><b></b>

There are other wait scenarios which can result in a SHARE mode wait for a TX lock but these are rare compared to the examples given above.

Example:

If a session wants to read a row locked by a transaction in a PREPARED state then it will wait on the relevant TX lock in SHARE mode (REQUEST=4). As a PREPARED transaction should COMMIT , ROLLBACK or go to an in-doubt state very soon after the prepare this is not generally noticeable.

例如,表存在主外鍵讀情況,主表不送出,子表那麼必須進行等待.

初始化測試表

會話1:

會話2:

會話3

另外遇到enq: TX - row lock contention等待事件,單執行個體與RAC是否有所差別呢,如果是RAC,需要注意<b>識别執行個體</b>,否則很容易誤殺其它會話?如果你查到了blocker,是不是應該直接kill掉呢? 這個必須要先征詢客戶的意見,确認之後才可以殺掉。不能因為外在壓力和自己的急躁而擅自Kill會話。

在WAITEVENT: "enq: TX - row lock contention" Reference Note (文檔 ID 1966048.1)中,也有一些比較有意思的SQL,可以參考一下

<b>診斷定位</b><b>enq: TX - row lock contention</b><b>等待事件</b><b></b>

在官方文檔 ID 62354.1裡面,提供了一個根據AWR 快照ID查找那些段出現row lock 等待較多的SQL,這個也有一定的參考意義。

在一些事務頻繁,并發較高的環境下,為了盡可能減少 TX - row lock contention 等待事件的發生,應當從應用設計到資料庫多個層面進行考慮。

<b>應用層面:</b>

1、限制通常是為了保證資料完整性,在并發場景下,應充分考慮事務進行的邏輯順序,避免多個會話事務交叉進行,觸發限制沖突在事務級别發生競争;

2、要提高并發效率,應當盡可能拆分大事務為小事務,提高 tx enqueue 鎖的擷取釋放速度;

3、如果要使用悲觀鎖(for update),應盡可能減少鎖定的行範圍;

<b>資料庫層面:</b>

1、在 dml 頻繁的表上建立适當的索引,提高 SQL 執行的效率,減少 tx enqueue 鎖持有的時間;避免全表掃描這種,容易造成 IO 開銷巨大,熱塊競争,會話堆積的通路方式。

2、在 dml 頻繁的表上不應使用位圖索引;

3、對于 dml 頻繁的表,不應使用 IOT 表,物化視圖等;

4、RAC 環境下,對于批量的 dml 操作,盡可能固定在單一節點,盡量降低網絡開銷、叢集競争、一緻性塊擷取和日志刷盤等帶來的影響。

<b>參考資料:</b>

https://support.oracle.com/epmos/faces/DocumentDisplay?_afrLoop=521417992978367&amp;id=62354.1&amp;displayIndex=1&amp;_afrWindowMode=0&amp;_adf.ctrl-state=1d01vq0378_227

http://mp.weixin.qq.com/s?__biz=MjM5MzExMTU2OQ==&amp;mid=2650603515&amp;idx=1&amp;sn=275956ad38d26168e44027336644e5a0&amp;scene=2&amp;srcid=0711qxhIykeqO278x7VZFx5k&amp;from=timeline&amp;isappinstalled=0#wechat_redirect

http://www.dbform.com/html/2015/2317.html

http://www.killdb.com/2015/07/13/%E5%85%B3%E4%BA%8Eenq-tx-row-lock-contention%E7%9A%84%E6%B5%8B%E8%AF%95%E5%92%8C%E6%A1%88%E4%BE%8B%E5%88%86%E6%9E%90.html

http://blog.chinaunix.net/uid-23284114-id-3390180.html

http://yunlongzheng.blog.51cto.com/788996/411205