ITPub博客

首页 > 数据库 > Oracle > 无工具情况下Oracle应急诊断思路(二)

无工具情况下Oracle应急诊断思路(二)

原创 Oracle 作者:kuqlan 时间:2012-07-10 02:03:06 0 删除 编辑

二、锁表(Lock)导致的系统无响应或慢

在多用户能够后台登录进行维护的系统中,经常会发生某些表被锁定而直接影响业务的情况,在这样的情况下我们可以将v$session结合v$locked_object和v$lock视图,如下为简单的查找语句:

select lo.oracle_username,

lo.object_id,

s.sid,

s.serial#,

s.seconds_in_wait

from v$locked_object lo, v$session s

where lo.session_id = s.sid

order by seconds_in_wait

也可以通过以上的OBJECTID和USER_OBJECTS(ALL_OBJECTS、DBA_OBJECTS)的OBJECTS_ID关联,得到锁的是哪个对象;

select b.owner, b.object_name, a.session_id, a.locked_mode

from v$locked_object a, dba_objects b

where b.object_id = a.object_id;

[@more@]

根据查询结果定位导致锁表的session或Process所对应的用户,提醒用户释放锁(即放弃自己进行DML操作),如果无法定位用户,则可以采取如下两种方式:

(1)释放锁的方法:

我们可以用下面SQL语句杀掉长期没有释放非正常的锁:

alter system kill session 'sid,serial#'; --sid,serial#是上面查询出来的

(2)系统级杀进程方法释放锁:

select spid from v$process where addr = (select paddr

from v$session where sid=&sid);

$ kill -9 spid --spid是上面查询出来的

--如下是查看当前是否存在锁表较复杂的SQL语句:

select /*+ RULE */ ls.osuser os_user_name, ls.username user_name,

decode(ls.type, 'RW', 'Row wait enqueue lock', 'TM', 'DML enqueue lock', 'TX',

'Transaction enqueue lock', 'UL', 'User supplied lock') lock_type,

o.owner,o.object_id,o.object_name object,o.subobject_name, decode(ls.lmode, 1, null, 2, 'Row Share', 3,

'Row Exclusive', 4, 'Share', 5, 'Share Row Exclusive', 6, 'Exclusive', null)

lock_mode, o.owner, ls.sid, ls.serial# seria ,ls.serial# serial_num, ls.id1, ls.id2

from sys.dba_objects o, ( select s.osuser, s.username, l.type,

l.lmode, s.sid, s.serial#, l.id1, l.id2 from v$session s,

v$lock l where s.sid = l.sid ) ls where o.object_id = ls.id1 and o.owner

<> 'SYS' order by o.owner, o.object_name

--alter system kill session 'sid,serial';

alter system kill session '1012,7580';

如下为oracle10g中 v$locked_object和 v$lock的描述和定义,可以看出这两个视图都来自于视图

SQL> desc v$locked_object;

Name Type Nullable Default Comments

--------------- ------------ -------- ------- --------

XIDUSN NUMBER Y

XIDSLOT NUMBER Y

XIDSQN NUMBER Y

OBJECT_ID NUMBER Y

SESSION_ID NUMBER Y

ORACLE_USERNAME VARCHAR2(30) Y

OS_USER_NAME VARCHAR2(30) Y

PROCESS VARCHAR2(12) Y

LOCKED_MODE NUMBER Y

SQL> select * from v$fixed_view_definition

where view_name='V$LOCKED_OBJECT';

------------------------------------------------------------

select xidusn,xidslot,xidsqn,object_id,session_id,oracle_username, os_user_name,process,locked_mode from gv$locked_object where inst_id = USERENV('Instance')

SQL> desc v$lock;

Name Type Nullable Default Comments

------- ----------- -------- ------- --------

ADDR RAW(8) Y

KADDR RAW(8) Y

SID NUMBER Y

TYPE VARCHAR2(2) Y

ID1 NUMBER Y

ID2 NUMBER Y

LMODE NUMBER Y

REQUEST NUMBER Y

CTIME NUMBER Y

BLOCK NUMBER Y

select * from v$fixed_view_definition

where view_name='V$LOCK';

------------------------------------------------------------

select ADDR , KADDR , SID , TYPE , ID1 , ID2 , LMODE , REQUEST , CTIME , BLOCK from GV$LOCK where inst_id = USERENV('Instance')

ORACLE里锁有以下几种模式:
0:none
1:null 空
2:Row-S 行共享(RS):共享表锁
3:Row-X 行专用(RX):用于行的修改
4:Share 共享锁(S):阻止其他DML操作
5:S/Row-X 共享行专用(SRX):阻止其他事务操作
6:exclusive 专用(X):独立访问使用
数字越大锁级别越高, 影响的操作越多。
一般的查询语句如select ... from ... ;是小于2的锁, 有时会在v$locked_object出现。
select ... from ... for update; 是2的锁。
当对话使用for update子串打开一个游标时,
所有返回集中的数据行都将处于行级(Row-X)独占式锁定,
其他对象只能查询这些数据行,不能进行update、delete或select...for update操作。
insert / update / delete ... ; 是3的锁。
没有commit之前插入同样的一条记录会没有反应,
因为后一个3的锁会一直等待上一个3的锁, 我们必须释放掉上一个才能继续工作。
创建索引的时候也会产生3,4级别的锁。
locked_mode为2,3,4不影响DML(insert,delete,update,select)操作,
但DDL(alter,drop等)操作会提示ora-00054错误。
有主外键约束时 update / delete ... ; 可能会产生4,5的锁。

DDL语句时是6的锁。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/18841027/viewspace-1058774/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
Oracle技术爱好者,Oracle10g OCM,网名 KUQLAN ,具有7的年Oracle数据库管理实践,曾经参加过BOSS、ERP、云计算(OpenStack+kvm)等项目的一线工作。以前写博客是为了自己,而现在是为了自己和别人。因为领会了帮助别人和分享、沉淀和积累会创造快乐和价值...

注册时间:2009-01-26

  • 博文量
    183
  • 访问量
    1681016