v$lock 查找锁 locked objects ORA-54 dblink
Database has db_link created in other databases. 这个和dblink有什么情况?
How to find which database it is? And how to find the blocking session
Solution
Use the following SQL to detect the blocking session:
select SID,TYPE,ID1,ID2,LMODE,REQUEST,CTIME from v$lock l
where l.type = 'TX' or l.type = 'TM'
union
select /*+ ordered use_nl(l), use_nl(r) +*/
s.sid, r.ksqrsidt,
r.ksqrsid1, r.ksqrsid2, l.lmode, l.request,l.ctime
from v$_lock l,x$ksqrs r , v$transaction tx , v$session s
where l.raddr=r.addr
and tx.addr = l.saddr
and tx.ses_addr = s.saddr
and s.saddr = tx.ses_addr
and ( r.KSQRSIDT = 'TM' or r.KSQRSIDT = 'TX')
order by 1,2;
select blocking_session, sid, serial#, wait_class, seconds_in_wait from v$
session
where blocking_session is not NULL order by blocking_session;
SELECT DECODE(request,0,'Holder: ','Waiter: ')||sid sess,
id1, id2, lmode, request, type
FROM V$LOCK
WHERE (id1, id2, type) IN
(SELECT id1, id2, type FROM V$LOCK WHERE request>0)
ORDER BY id1, request
/
Goal
Script and explanation for finding blocking and blocked sessions in both RAC (multi instance) and non-RAC (single instance) environments.
Solution
Purpose
Locking Mechanism
Resources (rows, tables, control files ...) represented by enqueues (TX, TM, CF, ...) can be locked in various modes (i.e. shared, exclusive, ...). Concurrent locking requests can conflict as per compatibility rules. Resources (enqueues) are externalized via GV$RESOURCE and lock requests via GV$LOCK views. Details can be found in
'Oracle® Database Concepts' -> chapter 'Data Concurrency and Consistency' (10.2. version)
Locking Conflict Types
1. Local locking conflict (block) - conflicting sessions are connected to the same instance (also applies to one instance of RAC)
Drawback: V$LOCK column BLOCK contains value 1 for blocking lock (session)
2. Global locking conflict (block) - conflicting sessions are connected to different instances (multi instance RAC only)
Drawback: V$LOCK column BLOCK contains value 2 to mark potential conflict (value is always 2 in RAC environments unless there is local conflict)
锁定机制
由队列(TX(事务在行上)、TM、CF 等)表示的资源(行、表、控制文件等)可以在各种模式(即共享、独占等)中锁定。并发锁定请求可能会根据兼容性规则发生冲突。资源(排队)通过 GV$RESOURCE 外部化,并通过 GV$LOCK 视图锁定请求。详情可在
“Oracle® 数据库概念”->章“数据并发性和一致性”(10.2. 版本)
锁定冲突类型
1. 本地锁定冲突(块) - 冲突会话连接到同一实例(也适用于 RAC 的一个实例(RAC one))
缺点:V$LOCK 列 BLOCK 包含用于阻塞锁(会话)的值 1
2. 全局锁定冲突(块)——冲突的会话连接到不同的实例(仅限多实例 RAC)
缺点:V$LOCK列BLOCK包含值2以标记潜在冲突(在RAC环境中,值始终为2,除非存在本地冲突)
Script Principle
Display all sessions holding or requesting lock of resource some session is waiting for. Waiting session has non-zero value of column GV$LOCK.REQUEST. Resource is identified by (TYPE,ID1,ID2 columns of GV$LOCK view).
We cannot use GV$LOCK.BLOCK in RAC as it always contains value 2 ("potential locking conflict") unless there is local conflict detected.
脚本原理
显示所有会话持有或请求某些会话正在等待的资源锁定。等待会话的列 GV$LOCK .REQUEST值为非零。请求。资源由 (GV$LOCK 视图的 TYPE,ID1,ID2 列) 标识。
我们不能使用 GV$LOCK.BLOCK,因为它始终包含值 2(“潜在的锁定冲突”),除非检测到本地冲突。
Finding root blocker
Run query provided in Script section and do one of the following.
(1) Find and kill root blockers
a) - Find oldest resource request - row with highest CTIME (this is row L1)
b) - Exists there another row with the same SID as L1? (this is row L2 if exists)
NOT - this is root blocker, kill it
YES - Find row with the same values of ID1,ID2 columns as in L2 where LOCK > 0 (this is row L3)
- Repeat (b) with L3 (L3 becomes L1) until You find root blocker
(2) Or use simple rule (may not be best)
a) Kill oldest blocking session (highest CTIME)
b) Run script again and repeat (a) until blocking session exists
寻找根阻滞剂
运行脚本部分中提供的查询,并执行以下作之一。
(1)寻找并杀死根部阻滞剂
a) - 查找最旧的资源请求 - 具有最高 CTIME 的行(这是行 L1)
b) - 存在与 L1 具有相同 SID 的另一行?(如果存在,则为第 L2 行)
不是 - 这是根阻滞剂,杀死它
YES - 查找 ID1,ID2 列值与 L2 中的值相同的行,其中 LOCK > 0(这是行 L3)
- 用 L3 重复 (b)(L3 变成 L1),直到你找到根阻滞剂
(2) 或使用简单的规则(可能不是最好的)
a) 终止最旧的阻塞会话(最高 CTIME)
b) 再次运行脚本并重复 (a) 直到阻塞会话存在
检测锁定冲突对象
通常,有问题的冲突发生在“DML 锁”(事务 - TX 和表 - TM 锁类型)上,有时找出冲突的主题(即修复应用程序设计错误以防止出现)很重要。
TM 锁的对象名称可以很容易地识别为 V$LOCK。ID1 与 DBA_OBJECTS 匹配。OBJECT_ID。
从 dba_objects o 中选择 OBJECT_ID、OWNER,OBJECT_NAME,V$LOCK l
其中 l.SID=&sid 和 l.ID1=o.OBJECT_ID;
相反,没有简单的方法(选择)来找出哪一行(TX)是等待的会话,即将TX请求与TM锁(表名)匹配。这是由于锁定实现 - 数据库块中的指针指向撤消段中分配的插槽(事务 ID - XID)。可以猜测表名(使用 CTIME 列值的相似性)。即会话正在等待 TX 锁 100 秒,并且表 A 上的 TM 锁已在 100 秒前放置(这只是一个猜测,因为 TM 锁可能已获取以在同一事务中进行早期更新)。
注意:为简单起见,GV$LOCK 被称为视图,但实际上这是视图 GV_$LOCK 的同义词(这同样适用于 V$LOCK)。
Detecting Object of Locking Conflict
Typically problematic conflicts happen with "DML Locks" (transaction - TX and table - TM lock types) and sometimes it is important to find out subject of the conflict (i.e. fix application design error to prevent issue).
Object name for TM lock can be easily identified as V$LOCK.ID1 is matching to DBA_OBJECTS.OBJECT_ID.
select OBJECT_ID, OWNER,OBJECT_NAME from dba_objects o, V$LOCK l
where l.SID=&sid and l.ID1=o.OBJECT_ID;
Contrary there is no easy way (select) to find out which row (TX) is the session waiting for i.e. to match TX request to TM lock (table name). This is due to locking implementation - pointer in database block points to assigned slot in undo segment (transaction id - XID). It is possible to make a guess of table name (using similarity of CTIME column value). I.e. session is waiting for TX lock for 100s and TM lock on table A has been placed 100s ago (this is just a guess as TM lock could have been acquired for earlier update in the same transaction).
Note: For simplicity GV$LOCK is referred as view but actually this is synonym for view GV_$LOCK (the same applies to V$LOCK).
Requirements
SQL*Plus
Configuring
There are no steps required.
Instructions
Connect as user able to select from GV$LOCK (typically user having DBA role).
sqlplus '/ as sysdba'
start <script_name>
Script
prompt CTIME is in Seconds
set lines 120
col BLOCK for 9
col LMODE for 9
col INST_ID for 9
col REQUEST for 9
col SID for 999999
select INST_ID, SID, TYPE, ID1, ID2, LMODE, REQUEST, CTIME, BLOCK
from gv$lock where (ID1,ID2,TYPE) in
(select ID1,ID2,TYPE from gv$lock where request>0);
Sample Output
- example output showing two independent root conflicts
- there can be noted oldest conflict (sid 64 vs 38) is not the root as session 38 is blocked by session 67
INST_ID | SID | TYPE | ID1 | ID2 | LMODE | REQUEST | CTIME | BLOCK |
---------- | -------- | ---------- | --------- | ------- | ---------- | ---------- | ---------- | ---------- |
2 | 212 | TX | 1114116 | 1399221 | 6 | 0 | 308 | 2 |
1 | 248 | TX | 1114116 | 1399221 | 0 | 6 | 304 | 0 |
4 | 67 | TX | 6225949 | 1244199 | 6 | 0 | 26 | 2 |
1 | 38 | TX | 6225949 | 1244199 | 0 | 6 | 23 | 0 |
2 | 64 | TX | 131103 | 2270514 | 0 | 6 | 117 | 0 |
1 | 38 | TX | 131103 | 2270514 | 6 | 0 | 171 | 2 |
26s 的锁住了171s的,期间26s还锁住了同一个sid的23s的