ORA-00054:资源正忙,但指定以NOWAIT⽅式获取资源,或者超时失效
当我删除某个数据库中表的数据的时候,我⽤truncate table 表名删除的时候,提⽰这个错误,我从⽹上百度了下,有这种⽅法解决
select session_id from v$locked_object
SESSION_ID
1 163
session_id 为163.
SELECT sid, serial#, username, osuser FROM v$session where sid =163
SID SERIAL# USERNAME OSUSER
1 163 500
2 CREDITFW Administrator
ALTER SYSTEM KILL SESSION '163,5002'
执⾏后就可以执⾏语句truncate table 表名删除表中数据了。
======================================================下⾯从⽹上复制的原理:
数据库的锁类型
根据保护的对象不同,数据库锁可以分为以下⼏⼤类:锁(data locks,数据锁),⽤于保护数据的完整性;锁(dictionary locks,字典锁),⽤于保护数据库对象的结构,如表、索引等的结构定义;内部锁和闩(internal locks and 锁的⽬的在于保证并发情况下的数据完整性,。在数据库中,锁主要包括TM锁和锁,其中TM锁称为表级锁,锁称为事务锁或⾏级锁。
当Oracle 执⾏DML语句时,系统⾃动在所要操作的表上申请TM类型的锁。当TM锁获得后,系统再⾃动申请类型的锁,并将实际锁定的数据⾏的锁标志位进⾏置位。这样在事务加锁前检查TX锁相容性时就不⽤再逐⾏检查锁标志,⽽在数据⾏上只有X锁(排他锁)。在 Oracle数据库中,当⼀个事务⾸次发起⼀个DML语句时就获得⼀个TX锁,该锁保持到事务被提交或回滚。当两个或多个会话在表的同⼀条记录上执⾏ DML语句时,第⼀个会话在该条记录上加锁,当Oracle数据库发⽣TX锁等待时,如果不及时处理常常会引起Oracle数据库挂起,或导致死锁的发⽣,产⽣ORA-60的错误。这些现象都会对实际应⽤产⽣极⼤的危害,如长时间未响应,⼤量事务失败等。
悲观封锁和乐观封锁
⼀、悲观封锁
锁在⽤户修改之前就发挥作⽤:
Select ..for update(nowait)
Select * from tab1 for update
⽤户发出这条命令之后,oracle将会对返回集中的数据建⽴⾏级封锁,以防⽌其他⽤户的修改。
如果此时其他⽤户对上⾯返回结果集的数据进⾏dml或操作都会返回⼀个错误信息或发⽣阻塞。
1:对返回结果集进⾏update或delete操作会发⽣阻塞。
2:对该表进⾏操作将会报:Ora-00054:resource busy and acquire with nowait specified.
原因分析
此时Oracle已经对返回的结果集上加了排它的⾏级锁,所有其他对这些数据进⾏的修改或删除操作都必须等待这个锁的释放,产⽣的外在现象就是其他的操作将发⽣阻塞,这个这个操作commit或rollback.
同样这个查询的事务将会对该表加表级锁,不允许对该表的任何ddl操作,否则将会报出ora-00054错误::resource busy and acquire with nowait specified.
⼆、乐观封锁
乐观的认为数据在select出来到update进取并提交的这段时间数据不会被更改。这⾥⾯有⼀种潜在的危险就是由于被选出的结果集并没有被锁定,是存在⼀种可能被其他⽤户更改的可能。因此Oracle仍然建议是⽤悲观封锁,因为这样
阻塞
定义:
当⼀个会话保持另⼀个会话正在请求的资源上的锁定时,就会发⽣阻塞。被阻塞的会话将⼀直挂起,直到持有锁的会话放弃锁定的资源为⽌。4个常见的dml语句会产⽣阻塞
INSERT
UPDATE
DELETE
SELECT…FOR UPDATE
INSERT
Insert发⽣阻塞的唯⼀情况就是⽤户拥有⼀个建有主键约束的表。当2个的会话同时试图向表中插⼊相同的数据时,其中的⼀个会话将被阻塞,直到另外⼀个会话提交或会滚。⼀个会话提交时,另⼀个会话将收到主键重复的错误。回UPDATE 和DELETE当执⾏Update和delete操作的数据⾏已经被另外的会话锁定时,将会发⽣阻塞,直到另⼀个会话提交或会滚。
Select …for update
当⼀个⽤户发出select..for update的错作准备对返回的结果集进⾏修改时,如果结果集已经被另⼀个会话锁定,就是发⽣阻塞。需要等另⼀个会话结束之后才可继续执⾏。可以通过发出 select… for update nowait的语句来避免发⽣阻
死锁-deadlock
定义:当两个⽤户希望持有对⽅的资源时就会发⽣死锁.
即两个⽤户互相等待对⽅释放资源时,oracle认定为产⽣了死锁,在这种情况下,将以牺牲⼀个⽤户作为代价,另⼀个⽤户继续执⾏,牺牲的⽤户的事务将回滚.
例⼦:
1:⽤户1对A表进⾏Update,没有提交。
2:⽤户2对B表进⾏Update,没有提交。
此时双反不存在资源共享的问题。
3:如果⽤户2此时对A表作update,则会发⽣阻塞,需要等到⽤户⼀的事物结束。
4:如果此时⽤户1⼜对B表作update,则产⽣死锁。此时Oracle会选择其中⼀个⽤户进⾏会滚,使另⼀个⽤户继续执⾏操作。
起因:
Oracle的死锁问题实际上很少见,如果发⽣,基本上都是不正确的程序设计造成的,经过调整后,基本上都会避免死锁的发⽣。
DML锁分类表
表1 Oracle的TM锁类型
锁模式锁描述解释 SQL操作
0 none
1 空 Select
2 SS(Row-S) ⾏级共享锁,其他对象只能查询这些数据⾏ Select for update、Lock for update、Lock row share
3 SX(Row-X) ⾏级排它锁,在提交前不允许做DML操作 Insert、Update、Delete、Lock row share
4 S(Share) 共享锁 Create index、Lock share
5 SSX(S/Row-X) 共享⾏级排它锁 Lock share row exclusive
6 X(Exclusive) 排它锁 table、Drop able、Drop index、Truncate table 、Lock exclusive
1.关于V$lock表和相关视图的说明
Column Datatype Description
ADDR (4 | 8) Address of lock state object
KADDR (4 | 8) Address of lock
SID NUMBER Identifier for session holding or acquiring the lock
TYPE VARCHAR2(2) Type of user or lock
The locks on the user types are obtained by user applications. Any process that is blocking others is likely to be holding one of these locks. The user type locks are:
TM - DML enqueue
TX - Transaction enqueue
UL - User supplied
--我们主要关注TX和TM两种类型的锁
--UL锁⽤户⾃⼰定义的,⼀般很少会定义,基本不⽤关注
--其它均为系统锁,会很快⾃动释放,不⽤关注
ID1 NUMBER Lock identifier #1 (depends on type)
ID2 NUMBER Lock identifier #2 (depends on type)
---当lock type 为TM时,id1为DML-locked object的object_id
---当lock type 为TX时,id1为usn+slot,⽽id2为seq。
--当lock type为其它时,不⽤关注
LMODE NUMBER Lock mode in which the session holds the lock:
0 - none
1 - ()
2 - row-S (SS)
3 - row-X (SX)
4 - share (S)
5 - S/Row-X (SSX)
6 - exclusive (X)
--⼤于0时表⽰当前会话以某种模式占有该锁,等于0时表⽰当前会话正在等待该锁资源,即表⽰该会话被阻塞。
--往往在发⽣TX锁时,伴随着TM锁,⽐如⼀个sid=9会话拥有⼀个TM锁,⼀般会拥有⼀个或⼏个TX锁,但他们的id1和id2是不同的,请注意
REQUEST NUMBER Lock mode in which the process requests the lock:
0 - none
1 - null (NULL)
2 - row-S (SS)
3 - row-X (SX)
4 - share (S)
5 - S/Row-X (SSX)
6 - exclusive (X)
--⼤于0时,表⽰当前会话被阻塞,其它会话占有改锁的模式
CTIME NUMBER Time since current mode was granted
BLOCK NUMBER The lock is blocking another lock
0, 'Not Blocking',
1, 'Blocking',
2, 'Global',
--该锁是否阻塞了另外⼀个锁
2.其它相关视图说明
视图名描述主要字段说明
v$session 查询会话的信息和锁的信息。 sid,serial#:表⽰会话信息。
program:表⽰会话的应⽤程序信息。
row_wait_obj#:表⽰等待的对象,和dba_objects中的object_id相对应。
lockwait :该会话等待的锁的地址,与v$lock的kaddr对应.
v$session_wait 查询等待的会话信息。 sid:表⽰持有锁的会话信息。
Seconds_in_wait:表⽰等待持续的时间信息
Event:表⽰会话等待的事件,锁等于enqueue
dba_locks 对v$lock的格式化视图。 Session_id:和v$lock中的Sid对应。
Lock_type:和v$lock中的type对应。
Lock_ID1:和v$lock中的ID1对应。
Mode_held,mode_requested:和v$lock中
的lmode,request相对应。
v$locked_object 只包含DML的锁信息,包括回滚段和会话信息。 Xidusn,xidslot,xidsqn:表⽰回滚段信息。和
v$transaction相关联。
Object_id:表⽰被锁对象标识。
Session_id:表⽰持有锁的会话信息。
Locked_mode:表⽰会话等待的锁模式的信
息,和v$lock中的lmode⼀致。
以下是命令⾏部分
================
1.查询数据库中的锁
select * from v$lock;
select * from v$lock where block=1;
2.查询被锁的对象
select * from v$locked_object;
3.查询阻塞
查被阻塞的会话
truncated zip file怎么解决select * from v$lock where lmode=0 and type in ('TM','TX');
查阻塞别的会话锁
select * from v$lock where lmode>0 and type in ('TM','TX');
4.查询数据库正在等待锁的进程
select * from v$session where lockwait is not null;
5.查询会话之间锁等待的关系
select a.sid holdsid,b.sid pe,a.id1,a.ime from v$lock a,v$lock b
where a.id1=b.id1 and a.id2=b.id2 and a.block=1 and b.block=0;
6.查询锁等待事件
select * from v$session_wait where event='enqueue';
解决⽅案:
select session_id from v$locked_object; --⾸先得到被锁对象的session_id
SELECT sid, serial#, username, osuser FROM v$session where sid = session_id; --通过上⾯得到的session_id去取得v$session的sid和serial#,然后对该进程进⾏终⽌。ALTER SYSTEM KILL SESSION 'sid,serial';
example:
ALTER SYSTEM KILL SESSION '13, 8';
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论