Oracle 阻塞(blocking blocked)
阻塞是DBA經常碰到的情形,尤其是不良的應用程式設計的阻塞將導致效能嚴重下降直至資料庫崩潰。對DBA而言,有必要知道如何定位到當前系統有哪些阻塞,到底誰是阻塞者,誰是被阻塞者。本文對此給出了描述並做了相關示範。
1、阻塞及其類型
a、什麼是阻塞
一個會話持有某個資源的鎖,而另一個會話在請求這個資源,就會出現阻塞(blocking)。也就是說新的會話會被掛起,直到持有鎖的會話放棄鎖定資源。大多數情況下,在一個互動式應用中被嚴重阻塞,即可表明應用邏輯有問題,這才是阻塞的根源。
b、阻塞得類型
資料庫中有5條常見的DML語句可能會阻塞,即:INSERT、UPDATE、DELETE、MERGE 和SELECT FOR UPDATE。
2、幾種不同類型阻塞的處理辦法
a、INSERT阻塞主要是由於有一個帶主鍵的表,或者表上有惟一的約束,在兩個會話試圖用同樣的值插入一行時引發阻塞。多表通過參考完整性約束相互連結時,在其依賴的父表正在建立或刪除期間,對子表的插入可能會阻塞。對於該類情形建議使用序列來產生主鍵/惟一列值。
b、對於UPDATE、DELETE、MERGE 和SELECT FOR UPDATE阻塞,只要有任一session使用這些操作已經鎖定行,其餘的必須處於等待狀態。直到當前鎖定行上的鎖(獨佔鎖定)釋放。對於該類情形,建議儘可能快速提交事務,或採用批量SQL方式提交。
c、對於一個阻塞的SELECT FOR UPDATE,解決方案很簡單:只需增加NOWAIT 子句,它就不會阻塞了。
3、示範阻塞
--更新表,注,提示符scott@CNMMBO表明使用者為scott的session,使用者名稱不同,session不同。
scott@CNMMBO> update emp set sal=sal*1.1 where empno=7788;
1 row updated.
scott@CNMMBO> @my_env
SPID SID SERIAL# USERNAME PROGRAM
------------ ---------- ---------- --------------- ------------------------------------------------
11205 1073 4642 robin Oracle@SZDB (TNS V1-V3)
--另起兩個session更新同樣的行,這兩個session都會處於等待,直到第一個session提交或復原
leshami@CNMMBO> update scott.emp set sal=sal+100 where empno=7788;
goex_admin@CNMMBO> update scott.emp set sal=sal-50 where empno=7788;
--下面在第一個session 查詢阻塞情況
scott@CNMMBO> @blocker
BLOCK_MSG BLOCK
-------------------------------------------------- ----------
pts/5 ('1073,4642') is blocking 1067,10438 1
pts/5 ('1073,4642') is blocking 1065,4464 1
--上面的結果表明session 1073,4642 阻塞了後面的2個
--即session 1073,4642是阻塞者,後面2個session是被阻塞者
--Author : Leshami
--Blog :
--------------------------------------------------------------------------------
Linux-6-64下安裝Oracle 12C筆記
在CentOS 6.4下安裝Oracle 11gR2(x64)
Oracle 11gR2 在VMWare虛擬機器中安裝步驟
Debian 下 安裝 Oracle 11g XE R2
--------------------------------------------------------------------------------