ORA-00054:资源忙,并获得与NOWAIT指定或超时过期

为什么在更新表格时出现此数据库错误?

第1行出现错误:ORA-00054:资源繁忙,并以NOWAIT指定或超时过期获取

您的表已被某些查询locking。 就像你已经执行“select更新”,但还没有提交/回滚,再次发射select查询。 在执行查询之前执行提交/回滚。

从这里ORA-00054:资源忙,并获得指定的NOWAIT

您也可以查看sql,用户名,机器,端口信息并进入持有连接的实际进程

SELECT O.OBJECT_NAME, S.SID, S.SERIAL#, P.SPID, S.PROGRAM,S.USERNAME, S.MACHINE,S.PORT , S.LOGON_TIME,SQ.SQL_FULLTEXT FROM V$LOCKED_OBJECT L, DBA_OBJECTS O, V$SESSION S, V$PROCESS P, V$SQL SQ WHERE L.OBJECT_ID = O.OBJECT_ID AND L.SESSION_ID = S.SID AND S.PADDR = P.ADDR AND S.SQL_ADDRESS = SQ.ADDRESS; 

请杀死Oracle会话

使用下面的查询来检查活动的会话信息

 SELECT O.OBJECT_NAME, S.SID, S.SERIAL#, P.SPID, S.PROGRAM, SQ.SQL_FULLTEXT, S.LOGON_TIME FROM V$LOCKED_OBJECT L, DBA_OBJECTS O, V$SESSION S, V$PROCESS P, V$SQL SQ WHERE L.OBJECT_ID = O.OBJECT_ID AND L.SESSION_ID = S.SID AND S.PADDR = P.ADDR AND S.SQL_ADDRESS = SQ.ADDRESS; 

杀死像

 alter system kill session 'SID,SERIAL#'; 

(例如, alter system kill session '13,36543' ;)

参考http://abeytom.blogspot.com/2012/08/finding-and-fixing-ora-00054-resource.html

这个问题有一个非常简单的解决方法。

如果你在会话中运行10046跟踪(谷歌这个…太多解释)。 在任何DDL操作之前,您将看到Oracle执行以下操作:

locking表'TABLE_NAME'没有等待

所以如果另一个会话有一个打开的事务,你会得到一个错误 所以解决方法是…请鼓。 在DDL之前发出自己的锁,并省略“无等待”。

特别提示:

如果你正在拆分分区oracle只是locking分区。 – 所以你可以locking分区子分区。

所以…下面的步骤解决了这个问题。

  1. locking表'表名'; – 你会“等待”(开发者把这个挂起来)。 直到与公开交易的会话提交。 这是一个队列。 所以可能会有几个会议在你之前。 但你不会错误的。
  2. 执行DDL。 您的DDL然后将运行一个没有等待的锁。 但是,你的会议已经locking了。 所以你很好。
  3. DDL自动提交。 这释放锁。

DML语句将会“等待”,或者当表被locking时,开发者称之为“挂起”。

我在从作业运行的代码中删除分区。 它工作正常。 它是在一个数据库不断插入数百插入/秒的速度。 没有错误。

如果你想知道。 在11g做这个。 以前我也是在10g之前完成的。

资源繁忙时发生此错误。 检查查询中是否有任何参照约束。 甚至在查询中提到的表格可能都很忙。 他们可能会从事其他工作,这些工作将在以下查询结果中明确列出:

 SELECT * FROM V$SESSION WHERE STATUS = 'ACTIVE' 

findSID,

 SELECT * FROM V$OPEN_CURSOR WHERE SID = --the id 

当用于更改表格的会话之外的会话由于DML(更新/删除/插入)而可能持有locking时,会发生这种情况。 如果您正在开发一个新系统,您或您的团队中的某个人很可能会发出更新声明,您可能会毫无后果地终止会话。 或者,一旦知道谁开放了会议,您可以从该会议提交。

如果您有权访问SQLpipe理系统,请使用它来查找违规会话。 也许杀了它。

你可以使用V $会议和V $锁等,但我build议你谷歌如何find该会话,然后如何杀死它。

在生产系统中,这取决于。 对于Oracle 10g及更高版本,您可以执行

 LOCK TABLE mytable in exclusive mode; alter table mytable modify mycolumn varchar2(5); 

在一个单独的会议,但有以下准备,以防需要太长时间。

 alter system kill session '.... 

这取决于你有什么系统,旧系统更可能不会每一次都提交。 这是一个问题,因为可能会有长期的锁。 所以你的锁会阻止任何新的锁,并等待谁知道什么时候会被释放的锁。 这就是为什么你有其他的说法准备好了。 或者你可以在那里寻找自动执行类似事情的PLSQL脚本。

在版本11g中,有一个新的环境variables设置了等待时间。 我认为这可能与我所描述的类似。 请注意,locking问题不会消失。

 ALTER SYSTEM SET ddl_lock_timeout=20; alter table mytable modify mycolumn varchar2(5); 

最后,最好等到系统中的用户很less做这种维护。

你的问题看起来像是在混合DML和DDL操作。 看到这个解释这个问题的URL:

http://www.orafaq.com/forum/t/54714/2/

就我而言,我确信这是我自己的一个会议阻止。 因此,做到以下几点是安全的:

  • 我发现违规的会议:

    SELECT * FROM V$SESSION WHERE OSUSER='my_local_username';

    会议不活动 ,但它仍然保持locking。 请注意,您可能需要使用其他WHERE条件(例如,尝试USERNAMEMACHINE字段)。

  • 使用上面获得的IDSERIAL#杀死了会话:

    alter system kill session '<id>, <serial#>';

只要检查进程举行会议和杀死它。 它恢复正常。

在SQL下面会find你的进程

 SELECT s.inst_id, s.sid, s.serial#, p.spid, s.username, s.program FROM gv$session s JOIN gv$process p ON p.addr = s.paddr AND p.inst_id = s.inst_id; 

然后杀了它

 ALTER SYSTEM KILL SESSION 'sid,serial#' 

要么

我在网上find的一些例子似乎需要实例ID以及改变系统杀死会议'130,620,@ 1';

简单地创build一个表时,我设法遇到了这个错误! 在一张尚不存在的表格上显然没有争用问题。 CREATE TABLE语句包含引用填充良好的表的CONSTRAINT fk_name FOREIGN KEY子句。 我不得不:

  • 从CREATE TABLE语句中删除FOREIGN KEY子句
  • 在FK列创build一个INDEX
  • 创buildFK

当我有两个脚本运行时,发生了这个错误。 我有:

  • 直接使用模式用户帐户(帐户#1)连接的SQL * Plus会话
  • 另一个使用不同架构用户帐户(帐户#2)连接的SQL * Plus会话,但连接数据库链接作为第一个帐户

我运行了一个表格,然后创build了表格#1。 我在帐号#2的会话中运行了一个表更新。 没有提交更改。 重新运行表格放置/创build脚本作为帐户#1。 在drop table x命令中出现错误。

我通过运行COMMIT;解决了它COMMIT; 在帐户#2的SQL * Plus会话中。

删除我的post,因为这是没有用的问题。 ORA-00054主要在执行DDL(ALTER,TRUNCATE等)时发生。

看到这个

我猜, SELECT FOR UPDATE是DML唯一的例外。

我也面临类似的问题。 程序员无需解决这个错误。 我通知我的Oracle DBA团队。 他们杀了会议,像一个魅力工作。

由Shashi的链接给出的解决scheme是最好的…没有必要联系dba或其他人

做一个备份

 create table xxxx_backup as select * from xxxx; 

删除所有行

 delete from xxxx; commit; 

插入您的备份。

 insert into xxxx (select * from xxxx_backup); commit; 
Interesting Posts