1、用dba权限的用户查看数据库都有啥样锁,此时的处境是那条语句平素在推行

 

当某个数据库用户在数据库中插入、更新、删除一个表的数量,或者扩大一个表的主键时仍然表的目录时,寻常会冒出ora-00054:resource
busy and acquire with nowait specified那样的荒唐。

死锁的原理:当对于数据库某个表的某一列做创新或删除等操作,执行已毕后该条语句不提交,另一条对于这一列数据做立异操作的口舌在推行的时候就会处于等候情况,此时的光景是那条语句一贯在执行,但直接没有进行成功,也绝非报错。

根本是因为有作业正在实施(或者工作已经被锁),所有导致执行不成事。

Oracle里锁有以下两种方式: 

1、用dba权限的用户查看数据库都有如何锁

*  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的锁。 
   
  以DBA角色, 查看当前数据库里锁的情形可以用如下SQL语句:*

select t2.username,t2.sid,t2.serial#,t2.logon_time from
v$locked_object t1,v$session t2 where t1.session_id=t2.sid order by
t2.logon_time;

  select object_id,session_id,locked_mode from v$locked_object;

如:testuser 339 13545 2009-3-5 17:40:05
知道被锁的用户testuser,sid为339,serial#为13545

  select t2.username,t2.sid,t2.serial#,t2.logon_time 
  from v$locked_object t1,v$session t2 
  where t1.session_id=t2.sid order by t2.logon_time;

2、依据sid查看具体的sql语句,如果sql不重要,可以kill

  假使有久远出现的一列,可能是从未有过自由的锁。 
   
  大家得以用下边SQL语句杀掉长时间没有自由非正常的锁:

select sql_text from v$session a,v$sqltext_with_newlines b   where
DECODE(a.sql_hash_value, 0, prev_hash_value,
sql_hash_value)=b.hash_value   and a.sid=&sid order by piece;

  alter system kill session ‘sid,serial#’;

查出来的sql,如: begin :id :=
sys.dbms_transaction.local_transaction_id; end;

  若是出现了锁的标题, 某个DML操作可能等待很久没有影响。 
   
  当您利用的是直接连接数据库的法子, 
  也毫无用OS系统命令 $kill process_num 或者 $kill -9
process_num来终止用户连接, 
  因为一个用户进度可能爆发一个之上的锁,
杀OS进度并不可以彻底清除锁的难题。 
   
  记得在数据库级别用alter system kill session
‘sid,serial#’;杀掉不健康的锁。

3、kill该事务 alter system kill session ‘339,13545’;

当事情得到行锁后,此事情也将活动得到该行的表锁(共享锁),以免备其余业务举办DDL语句影响记录行的立异。事务也可以在进展进程中得到共享锁或排它锁,只有当工作突显接纳LOCK
TABLE语句突显的概念一个排它锁时,事务才会收获表上的排它锁,也可使用LOCK
TABLE突显的定义一个表级的共享锁
,所以行锁的时候我还的拿个表锁,免得其余人该了本人的表结构依然去除了我的表。

4、那样就足以实施其它的工作sql语句了

 

如扩大表的主键: alter table test   add constraint PK_test primary key
(test_NO);

锁表查询SQL
SELECT object_name, machine, s.sid, s.serial#
FROM gv$locked_object l, dba_objects o, gv$session s
WHERE l.object_id = o.object_id
AND l.session_id = s.sid;

 

–释放SESSION SQL:
–alter system kill session ‘sid, serial#’;
如:  ALTER system kill session ’23, 1647′;

若提示:ORA-00030: User session ID does not exist

 

alter session set events ‘immediate trace name flush_cache level 1’;

–查出oracle当前的被锁对象
SELECT l.session_id sid, s.serial#, l.locked_mode 锁模式,
l.oracle_username 登录用户,
l.os_user_name 登录机器用户名, s.machine 机器名, s.terminal
终端用户名, o.object_name 被锁对象名,s.logon_time 登录数据库时间
FROM v$locked_object l, all_objects o, v$session s
WHERE l.object_id = o.object_id AND l.session_id = s.sid
ORDER BY sid, s.serial#;

结局不详

 

ORA-00031: session marked for kill

–查询什么SQL引起的锁表
select l.session_id sid,
s.serial#,
l.locked_mode,
l.oracle_username,
s.user#,
l.os_user_name,
s.machine,
s.terminal,
a.sql_text,
a.action
from v$sqlarea a, v$session s, v$locked_object l
where l.session_id = s.sid
and s.prev_sql_addr = a.address
order by sid, s.serial#;

部分ORACLE中的进程被杀掉后,状态被置为”killed”,可是锁定的资源很长日子不自由,有时实在不能,只能重启数据库。现在提供一种方法解决那种题材,那就是在ORACLE中杀不掉的,在OS一级再杀。

–kill掉当前的锁对象可以为
alter system kill session ‘sid, s.serial#‘;

 

 

1.上面的语句用来询问哪些对象被锁:

–查询死锁,并得以观察死锁的机器是那一台

select object_name,machine,s.sid,s.serial# from v$locked_object
l,dba_objects o ,v$session s where l.object_id = o.object_id and
l.session_id=s.sid;

select username,lockwait,status,machine,program from v$session where sid
in
(select session_id from v$locked_object)

2.底下的语句用来杀死一个经过: alter system kill session ‘24,111’;
(其中24,111分别是地点查询出的sid,serial#)

 

【注】以上两步,可以因此Oracle的管理控制台来执行。

假定还无法一蹴而就:

3.即使拔取方面的命令杀死一个经过后,进度情状被置为”killed”,可是锁定的资源很长日子不曾被保释,那么能够在os一流再杀死相应的经过(线程),
率先实施下边的说话得到进度(线程)号:
select spid, osuser, s.program from v$session s,v$process p where
s.paddr=p.addr and s.sid=24 (24是上边的sid)

select pro.spid from v$session ses,v$process pro where ses.sid=XX and
ses.paddr=pro.addr;

4.在OS上杀死那么些进度(线程):
1)在unix上,用root身份执行命令: #kill -9
12345(即第3步查询出的spid)
2)在windows(unix也适用)用orakill杀死线程,
orakill是oracle提供的一个可执行命令,语法为: orakill sid thread
其中:
sid:表示要杀死的进度属于的实例名
thread:是要杀掉的线程号,即第3步查询出的spid。
例:c:>orakill orcl 12345

内部sid用死锁的sid替换: exit

ORA-00031: session marked for kill

ps -ef|grep spid

Cause: The session specified in an ALTER SYSTEM KILL SESSION command
cannot be killed immediately (because it is rolling back or blocked on a
network operation), but it has been marked for kill. This means it will
be killed as soon as possible after its current uninterruptible
operation is done.

其间spid是其一历程的长河号,kill掉这些Oracle进度

Action: No action is required for the session to be killed, but further
executions of the ALTER SYSTEM KILL SESSION command on this session may
cause the session to be killed sooner.

 

 

kill -9 12345

http://www.cnblogs.com/chuanzifan/archive/2012/05/26/2519695.html

相关文章