For reference only.
If you've ever gotten a phone call from an annoyed user whose transaction just won't go through, or from a developer who can't understand why her application sessions are blocking each other, you know how useful it can be to identify not just whose lock is doing the blocking, but what object is locked. Even better, you can identify the exact row that a session is waiting to lock.
Create a blocking lock
To begin, create a situation where one user is actively blocking another. Open two sessions. Issue the following commands in Session 1 to build the test table:
SQL> create table tstlock (foo varchar2(1), bar varchar2(1));
Table created.
SQL> insert into tstlock values (1,'a');
1 row created.
SQL> insert into tstlock values (2, 'b');
1 row created.
SQL> select * from tstlock ;
FOO BAR
--- ---
1 a
2 b
2 rows selected.
SQL> commit ;
Commit complete.
Now grab a lock on the whole table, still in Session 1:
SQL> select * from tstlock for update ;
And in Session 2, try to update a row:
SQL> update tstlock set bar=
2 'a' where bar='a' ;
This statement will hang, blocked by the lock that Session 1 is holding on the entire table.
Identify the blocking session
Oracle provides a view, DBA_BLOCKERS, which lists the SIDs of all blocking sessions. But this view is often, in my experience, a good bit slower than simply querying V$LOCK, and it doesn't offer any information beyond the SIDs of any sessions that are blocking other sessions. The V$LOCK view is faster to query, makes it easy to identify the blocking session, and has a lot more information.
SQL> select * from v$lock ;
ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
AF9E2C4C AF9E2C60 479 TX 131078 16739 0 6 685 0
ADDF7EC8 ADDF7EE0 422 TM 88519 0 3 0 697 0
ADDF7F74 ADDF7F8C 479 TM 88519 0 3 0 685 0
ADEBEA20 ADEBEB3C 422 TX 131078 16739 6 0 697 1
.... .... ... ... .... .... .... .... .... ....
Note the BLOCK column. If a session holds a lock that's blocking another session, BLOCK=1. Further, you can tell which session is being blocked by comparing the values in ID1 and ID2. The blocked session will have the same values in ID1 and ID2 as the blocking session, and, since it is requesting a lock it's unable to get, it will have REQUEST > 0.
In the query above, we can see that SID 422 is blocking SID 479. SID 422 corresponds to Session 1 in our example, and SID 479 is our blocked Session 2.
To avoid having to stare at the table and cross-compare ID1's and ID2's, put this in a query:
SQL> select l1.sid, ' IS BLOCKING ', l2.sid
2 from v$lock l1, v$lock l2
3 where l1.block =1 and l2.request > 0
4 and l1.id1=l2.id1
5 and l1.id2=l2.id2
SQL> /
SID 'ISBLOCKING' SID
---------- ------------- ----------
422 IS BLOCKING 479
1 row selected.
Even better, if we throw a little v$session into the mix, the results are highly readable:
SQL> select s1.username || '@' || s1.machine
2 || ' ( SID=' || s1.sid || ' ) is blocking '
3 || s2.username || '@' || s2.machine || ' ( SID=' || s2.sid || ' ) ' AS blocking_status
4 from v$lock l1, v$session s1, v$lock l2, v$session s2
5 where s1.sid=l1.sid and s2.sid=l2.sid
6 and l1.BLOCK=1 and l2.request > 0
7 and l1.id1 = l2.id1
8 and l2.id2 = l2.id2 ;
BLOCKING_STATUS
----------------------------------------------------------------------------------------------------
BULKLOAD@yttrium ( SID=422 ) is blocking BULKLOAD@yttrium ( SID=479 )
1 row selected.
There's still more information in the v$lock table, but in order to read that information, we need to understand a bit more about lock types and the cryptically-named ID1 and ID2 columns.
Lock type and the ID1 / ID2 columns
In this case, we already know that the blocking lock is an exclusive DML lock, since we're the ones who issued the locking statement. But most of the time, you won't be so lucky. Fortunately, you can read this information from the v$lock table with little effort.
The first place to look is the TYPE column. There are dozens of lock types, but the vast majority are system types. System locks are normally only held for a very brief amount of time, and it's not generally helpful to try to tune your library cache, undo logs, etc. by looking in v$lock! (See the V$LOCK chapter in the Oracle Database Reference for a list of system lock types.)
There are only three types of user locks, TX, TM and UL. UL is a user-defined lock -- a lock defined with the DBMS_LOCK package. The TX lock is a row transaction lock; it's acquired once for every transaction that changes data, no matter how many objects you change in that transaction. The ID1 and ID2 columns point to the rollback segment and transaction table entries for that transaction.
The TM lock is a DML lock. It's acquired once for each object that's being changed. The ID1 column identifies the object being modified.
Lock Modes
You can see more information on TM and TX locks just by looking at the lock modes. The LMODE and REQUEST columns both use the same numbering for lock modes, in order of increasing exclusivity: from 0 for no lock, to 6 for exclusive lock. A session must obtain an exclusive TX lock in order to change data; LMODE will be 6. If it can't obtain an exclusive lock because some of the rows it wants to change are locked by another session, then it will request a TX in exclusive mode; LMODE will be 0 since it does not have the lock, and REQUEST will be 6. You can see this interaction in the rows we selected earlier from v$lock:
ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
AF9E2C4C AF9E2C60 479 TX 131078 16739 0 6 685 0
ADEBEA20 ADEBEB3C 422 TX 131078 16739 6 0 697 1
Note that ID1 and ID2 in Session 2, which is requesting the TX lock (LMODE=0, REQUEST=6), point back to the rollback and transaction entries for Session 1. That's what lets us determine the blocking session for Session 2.
You may also see TX locks in mode 4, Shared mode. If a block containing rows to be changed doesn't have any interested transaction list (ITL) entries left, then the session acquires a TX lock in mode 4 while waiting for an ITL entry. If you see contention for TX-4 locks on an object, you probably need to increase INITRANS for the object.
TM locks are generally requested and acquired in modes 3, aka Shared-Row Exclusive, and 6. DDL requires a TM Exclusive lock. (Note that CREATE TABLE doesn't require a TM lock -- it doesn't need to lock any objects, because the object in question doesn't exist yet!) DML requires a Shared-Row Exclusive lock. So, in the rows we selected earlier from v$lock, you can see from the TM locking levels that these are DML locks:
ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
ADDF7EC8 ADDF7EE0 422 TM 88519 0 3 0 697 0
ADDF7F74 ADDF7F8C 479 TM 88519 0 3 0 685 0
Identifying the locked object
Now that we know that each TM row points to a locked object, we can use ID1 to identify the object.
SQL> select object_name from dba_objects where object_id=88519 ;
OBJECT_NAME
--------------
TSTLOCK
Sometimes just knowing the object is enough information; but we can dig even deeper. We can identify not just the object, but the block and even the row in the block that Session 2 is waiting on.
Identifying the locked row
We can get this information from v$session by looking at the v$session entry for the blocked session:
SQL> select row_wait_obj#, row_wait_file#, row_wait_block#, row_wait_row#
2* from v$session where sid=479 ;
ROW_WAIT_OBJ# ROW_WAIT_FILE# ROW_WAIT_BLOCK# ROW_WAIT_ROW#
------------- -------------- --------------- -------------
88519 16 171309 0
This gives us the object ID, the relative file number, the block in the datafile, and the row in the block that the session is waiting on. If that list of data sounds familiar, it's because those are the four components of an extended ROWID. We can build the row's actual extended ROWID from these components using the DBMS_ROWID package. The ROWID_CREATE function takes these arguments and returns the ROWID:
SQL> select do.object_name,
2 row_wait_obj#, row_wait_file#, row_wait_block#, row_wait_row#,
3 dbms_rowid.rowid_create ( 1, ROW_WAIT_OBJ#, ROW_WAIT_FILE#, ROW_WAIT_BLOCK#, ROW_WAIT_ROW# )
4 from v$session s, dba_objects do
5 where sid=543
6 and s.ROW_WAIT_OBJ# = do.OBJECT_ID ;
OBJECT_NAME ROW_WAIT_OBJ# ROW_WAIT_FILE# ROW_WAIT_BLOCK# ROW_WAIT_ROW# DBMS_ROWID.ROWID_C
--------------- ------------- -------------- --------------- ------------- ------------------
TSTLOCK 88519 16 171309 0 AAAVnHAAQAAAp0tAAA
And, of course, this lets us inspect the row directly.
SQL> select * from tstlock where rowid='AAAVnHAAQAAAp0tAAA' ;
FOO BAR
--- ---
1 a
Conclusion
We've seen how to identify a blocking session, and how to inspect the very row that the waiting session is waiting for. And, I hope, learned a bit about v$lock in the process
分享到:
相关推荐
### Oracle V$SESSION 和 V$SESSION_WAIT 的详细解析 #### 概述 Oracle 数据库提供了大量的动态性能视图(Dynamic Performance Views),其中 `V$SESSION` 和 `V$SESSION_WAIT` 是两个非常重要的视图,它们能够帮助...
总结来说,“dumping oracle block”是一项用于深入洞察Oracle数据库内部运作的技术,它可以提供超出常规查询所能提供的信息。通过学习如何进行块转储以及如何解析其结果,DBA能够更好地理解和解决问题,同时满足对...
总的来说,Oracle Database Architecture 9i和10g Programming Techniques and Solutions涵盖了数据库设计、实施、管理和优化的各个方面,是理解Oracle数据库工作原理和提升数据库技能的重要资源。无论是DBA还是...
and (b.BLOCK=1 or b.REQUEST >0 ) and v.TYPE='TM' order by b.ID2,v.ID1,user_name desc; 这条语句可以查找当前数据库中阻塞的 Session,包括阻塞的Session ID、用户名、对象名称、状态等信息。 4. 阻塞和...
### Oracle V$SESSION 视图详解与应用 #### 概述 在Oracle数据库管理中,理解和掌握`V$SESSION`视图是非常重要的。这个视图提供了关于当前活动会话(session)的详细信息,包括用户的SID(会话标识符)、执行的SQL...
wait_event_block.txt wait_event_hash.txt wait_event_sqlid.txt wait_event.txt wait_session_hash.txt wait_session_sqlid.txt 四、Oracle中文手册合集(8个CHM) Ora9iSQL参考手册.chm Oracle函数大全.chm oracle...
FROM V$SESSION a LEFT JOIN V$SQL b ON (a.sql_address = b.address AND a.sql_hash_value = b.hash_value) ORDER BY b.CPU_TIME DESC; ``` 通过左连接`v$session`和`v$sql`视图,并按照`CPU_TIME`降序排列,...
Oracle性能监控SQL——监控当前会话执行的SQL及IO等信息 Oracle性能监控是数据库管理员的重要职责之一,通过监控数据库的性能,可以及时发现问题,避免数据库的宕机和性能下降。本文将介绍一些常用的Oracle性能监控...
AND L1.BLOCK = 1 AND L2.REQUEST > 0 AND L1.ID1 = L2.ID1 AND L2.ID2 = L2.ID2; ``` 此查询显示了阻塞方(SID1)和被阻塞方(SID2)的信息,帮助我们更好地理解锁定情况。 #### 六、注意事项 1. **SID小于100**...
《Oracle性能优化绝版好书:高级OWI与ORACLE性能调整》这本书深入探讨了Oracle数据库性能优化的关键技术和策略,特别关注了Oracle Wait Interface (OWI)和性能调整的实践应用。OWI是Oracle数据库中用于监控和诊断...
1. CPU used by this session:表示会话占用的CPU资源,不包括后台进程。 2. DB block changes:指示当前请求的块数目,这反映了数据库中数据块的更改情况。 这些指标可以帮助分析数据库的CPU使用率、I/O活动等,...
3. Oracle Trace and TKPROF:生成执行计划和性能报告,帮助优化SQL语句。 4. third-party工具:如SQL Developer, TOAD, JMeter, LoadRunner等,提供更丰富的测试选项。 四、性能测试指标 1. 吞吐量:单位时间内...
WHERE a.block = 1 AND b.request > 0 AND a.id1 = b.id1 AND a.id2 = b.id2; ``` 这个查询显示了哪个会话正在阻塞另一个会话,有助于定位死锁的源头。 3. 获取会话ID和锁定请求信息: ```sql SELECT a.id1, a....
st.event, st.p1text, si.physical_reads, si.block_changes FROM v$session se, v$session_wait st, v$sess_io si, v$process pr WHERE st.sid=se.sid AND st.sid=si.sid AND se.PADDR=pr.ADDR AND se.sid>6 ...
6. 查询用户是从哪台机器登录Oracle,可以使用`SELECT machine, terminal FROM V$SESSION;` 7. 查询表的结构、字段及其值,可以使用`DESC table_name`来获取列信息,`SELECT field_name FROM table_name`来获取字段...
"ORACLE数据库一次意外宕机的分析处理实记(ora-1578)" ...WHERE FILE_ID=<文件号 > AND <块号 > BETWEEN BLOCK_ID AND BLOCK_; 通过对故障的分析和解决,我们可以减少类似故障的发生,提高数据库的稳定性和可靠性。
1. CPU used by this session (V$SESSTAT1/[SYS]/ABCDEF/ORACLE.EXE) (绝对) 这个计数器记录了自用户调用开始到结束期间会话使用的CPU时间(以10毫秒为单位)。如果某些调用在10毫秒内完成,开始和结束时间可能相同...
### Oracle常用dump命令详解 #### 一、Memory Dumps **Memory Dumps** 主要用于获取Oracle内存区域的详细信息,这些信息对于诊断系统性能问题非常有用。下面将详细介绍几个常用的Memory Dump命令。 ##### 1\. ...
在Oracle数据库管理中,Session阻塞是一个常见的性能问题,它发生在一个会话(Session)等待另一个会话释放资源时。这种情况通常会导致系统响应速度变慢,甚至可能导致事务无法完成。解决此类问题的关键在于快速定位...
*.session_cached_cursors=100 *.sga_target=500m *.shared_pool_size=100m *.undo_management='AUTO' *.undo_retention=0 *.undo_tablespace='UNDOTS1' *.user_dump_dest='/home/oracle/admin/bipdb/udump' ``` ...