Oracle:select 或 inactive 會話語句產生鎖?
最近發生的幾起 enq: TX - row lock contention 等待事件很怪,透過 blocking session id 檢視,不是語句是 select,就是會話是 inactive 的。
實驗
準備工作
-
進入 hr 使用者,同時檢視會話 id,下面會稱為 會話 38
SQL> select userenv('sid') from dual; USERENV('SID') -------------- 3
-
建立測試表
create table emp_bak as select * from employees
-
建立被鎖會話,同時檢視會話 id,下面會稱為 會話 28
SQL> select userenv('sid') from dual; USERENV('SID') -------------- 28
測試
-
會話 38 產生鎖操作,注意,此處不進行提交操作,且操作完不進行 exit 操作
SQL> SELECT employee_id, first_name, last_name, salary 2 FROM emp_bak 3 WHERE employee_id = 166; EMPLOYEE_ID FIRST_NAME LAST_NAME SALARY ----------- ---------------------------------------- -------------------------------------------------- ---------- 166 Sundar Ande 6400 SQL> update emp_bak 2 set salary = salary + 100 3 where employee_id = 166; 1 row updated
-
會話 28,為了區分操作語句,此處我們執行 delete 操作,此時會出現 hang,暫且不去管它
SQL> delete from emp_bak 2 where employee_id = 166
-
此時,我們新啟會話查一下鎖情況
col event for a30 col username for a8 col process for a7 col machine for a7 col program for a30 col sql for a80 SELECT a.sid, b.status, b.event, b.USERNAME, b.PROCESS, b.MACHINE, b.program, CASE WHEN rawtohex(b.SQL_ADDRESS) <> '00' THEN 'CURR' ELSE 'PREV' END STAT, c.sql_text "SQL" FROM v$lock a, v$session b, v$sql c WHERE (a.id1, a.id2) IN (SELECT ID1, ID2 FROM gv$lock WHERE TYPE = 'TX' AND request > 0) AND a.sid = b.sid AND CASE WHEN rawtohex(b.SQL_ADDRESS) <> '00' THEN b.SQL_ADDRESS ELSE b.PREV_SQL_ADDR END = c.address AND CASE WHEN b.SQL_HASH_VALUE > 0 THEN b.SQL_HASH_VALUE ELSE b.PREV_HASH_VALUE END = c.hash_value;
由於長時間未對資料庫進行操作,所以會話狀態為 INACTIVE 狀態,鎖的語句為 update
-
那麼此時,我們在會話 38 上執行 select 語句,查詢的狀態是怎樣的呢?
SQL> SELECT employee_id, first_name, last_name, salary 2 FROM emp_bak 3 WHERE employee_id = 166; EMPLOYEE_ID FIRST_NAME LAST_NAME SALARY ----------- ---------------------------------------- -------------------------------------------------- ---------- 166 Sundar Ande 6500
-
我們此時可以再關聯 v$transaction,來檢視具體資訊
SELECT a.sid, b.status, b.event, b.USERNAME, b.PROCESS, b.MACHINE, b.program, CASE WHEN rawtohex(b.SQL_ADDRESS) <> '00' THEN 'CURR' ELSE 'PREV' END STAT, c.sql_text "SQL", d.start_time, d.status, d.xid, d.USED_UBLK, d.USED_UREC FROM v$lock a, v$session b, v$sql c, v$transaction d WHERE (a.id1, a.id2) IN (SELECT ID1, ID2 FROM gv$lock WHERE TYPE = 'TX' AND request > 0) AND a.sid = b.sid AND CASE WHEN rawtohex(b.SQL_ADDRESS) <> '00' THEN b.SQL_ADDRESS ELSE b.PREV_SQL_ADDR END = c.address AND CASE WHEN b.SQL_HASH_VALUE > 0 THEN b.SQL_HASH_VALUE ELSE b.PREV_HASH_VALUE END = c.hash_value AND rawtohex(d.addr(+)) = b.taddr;
結論
-
blocking session id 記錄的是誰鎖的自己
-
sqltext 記錄的是當前執行的語句,而並非是被哪句鎖住了
-
inactive 僅表示處於此狀態的會話沒有正在執行,但由於之前執行的語句,依然會產生鎖
-
v$transaction 可以獲取事務的狀態以及進度,重複查詢 USED_UBLK、USED_UREC 這兩個值,可以看到變化,可以估計事務的進度,尤其是長時間的回滾操作,當這兩個值為0,回滾也就完成了。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31490526/viewspace-2780067/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle 定期清理inactive會話Oracle會話
- Sqlserver的merge into或delete語句堵塞select語句,鎖型別是LCK_M_ISSQLServerdelete型別
- Oracle 什麼時候select會產生redo?Oracle
- oracle鎖會話Oracle會話
- 【Mysql】兩條insert 語句產生的死鎖MySql
- 查詢處理死鎖會話的sql語句(轉貼)會話SQL
- Oracle SQL select練習語句OracleSQL
- oracle 鎖表、解鎖的語句Oracle
- 在Oracle中,如何定時清理INACTIVE狀態的會話?Oracle會話
- oracle 檢視死鎖語句Oracle
- 資料庫會話數量過多,定期清理inactive會話資料庫會話
- SQL SELECT 語句SQL
- Go select 語句Go
- 在oracle中跟蹤會話執行語句的幾種方法Oracle會話
- 【SQL】14 UNION 操作符、SELECT INTO 語句、INSERT INTO SELECT 語句、CREATE DATABASE 語句、CREATE TABLE 語句SQLDatabase
- SQL update select語句SQL
- 【Oracle】死鎖的產生與處理Oracle
- 如何透過sid查詢造成死鎖的sql語句,並殺死會話SQL會話
- 如何通過sid查詢造成死鎖的sql語句,並殺死會話SQL會話
- INSERT...SELECT語句對查詢的表加鎖嗎
- Oracle select 語句字串拼接小例項-quote使用Oracle字串
- Oracle OCP(01):使用SQL SELECT語句檢索資料OracleSQL
- oracle實用sql(7)--單個會話或會話間statistics對比OracleSQL會話
- 生產SQL語句突然變慢問題定位SQL
- oracle SELECT INTO 和 INSERT INTO SELECT 兩種表複製語句詳解Oracle
- Go select語句詳解Go
- SQL語言基礎(SELECT語句)SQL
- oracle 會話(session)被鎖瞭解決方法Oracle會話Session
- 6. Oracle開發和應用—6.3. 基本SQL語句—6.3.4. select語句OracleSQL
- mysql鎖與會話MySql會話
- 簡單的反向生產DDL語句的指令碼指令碼
- 圖解Go select語句原理圖解Go
- 學習MySQL的select語句MySql
- Select語句執行順序
- Sql Server系列:Select基本語句SQLServer
- select 語句的解析過程
- 延遲塊清理介紹(select也會產生redo的原因)
- select for update語句造成ORA-00060 deadlock死鎖問題分析