ORA-00054:资源繁忙并在指定NOWAIT或超时过期时获取

时间:2011-01-30 11:59:44

标签: oracle ora-00054

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

  

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

14 个答案:

答案 0 :(得分:187)

您的表已被某些查询锁定。例如,您可能已执行“select for update”并且尚未提交/回滚并触发另一个选择查询。在执行查询之前执行提交/回滚。

答案 1 :(得分:84)

从这里ORA-00054: resource busy and acquire with NOWAIT specified

您还可以查找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;

答案 2 :(得分:51)

请杀死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

答案 3 :(得分:16)

这个问题很容易解决。

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

LOCK TABLE' TABLE_NAME'没有等待

因此,如果另一个会话有一个打开的事务,则会出现错误。所以修复是...滚筒请。在DDL之前发出自己的锁,并省略“等待”#39;。

特别提示:

如果你正在拆分/删除分区oracle只是锁定分区。 - 所以你可以锁定分区子分区。

所以... 以下步骤解决了问题。

  1. LOCK TABLE' TABLE NAME&#39 ;; - 你会等待' (开发人员称之为悬挂)。直到与开放事务的会话,提交。这是一个队列。所以你可能会有几个会议。但你不会错。
  2. 执行DDL。然后,您的DDL将以NO WAIT运行锁定。但是,您的会话已获取锁定。所以你很好。
  3. DDL自动提交。这释放了锁。
  4. DML语句将等待'或者正如开发人员所说的那样“挂起来”。桌子被锁定了。

    我在从作业到删除分区的代码中使用它。它工作正常。它在数据库中以每秒几百次插入的速率不断插入。没有错误。

    如果你想知道。在11g这样做。我之前和以前一样都是以10g完成的。

答案 4 :(得分:9)

资源繁忙时会发生此错误。检查查询中是否有任何引用约束。或者甚至您在查询中提到的表可能很忙。他们可能会参与以下查询结果中明确列出的其他工作:

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

找到SID,

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

答案 5 :(得分:6)

当用于更改表的会话之外的会话由于DML(更新/删除/插入)而可能存在锁定时,会发生这种情况。如果您正在开发一个新系统,那么您或您团队中的某个人可能会发布更新语句,您可能会在没有太大后果的情况下终止会话。或者,一旦知道谁打开会话,您就可以从该会话中提交。

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

您可以使用v $ session和v $ lock等,但我建议您谷歌如何找到该会话,然后如何杀死它。

在生产系统中,它确实取决于。对于oracle 10g及更早版本,您可以执行

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

在单独的会话中,如果花费的时间太长,请准备好以下内容。

alter system kill session '....

这取决于您拥有的系统,旧系统更有可能不会每次都提交。这是一个问题,因为可能存在长时间锁定。所以你的锁会阻止任何新的锁并等待谁知道什么时候会被释放的锁。这就是你准备另一个声明的原因。或者你可以在那里寻找自动执行类似操作的PLSQL脚本。

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

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

最后,最好等到系统中的用户很少进行这种维护。

答案 6 :(得分:6)

在我的情况下,我确信这是阻止的我自己的会话之一。因此,可以安全地执行以下操作:

  • 我发现违规会话:

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

    会话无效,但它仍以某种方式保持锁定。请注意,您可能需要在案例中使用其他一些 WHERE 条件(例如,尝试USERNAMEMACHINE字段)。

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

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

由@thermz编辑:如果以前的开放式会话查询都不起作用,请尝试使用此方法。此查询可以帮助您在终止会话时避免语法错误:

  • SELECT 'ALTER SYSTEM KILL SESSION '''||SID||','||SERIAL#||''' immediate;' FROM V$SESSION WHERE OSUSER='my_local_username_on_OS'

答案 7 :(得分:5)

您的问题看起来像是在混合DML&amp; DDL操作。请参阅此URL解释此问题:

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

答案 8 :(得分:4)

只需检查持有会话的进程并将其杀死。它恢复正常。

在SQL下面会找到你的过程

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#'

OR

我在网上发现的一些例子似乎也需要实例ID alter system kill session'130,620,@ 1';

答案 9 :(得分:2)

我设法在创建表时遇到此错误!在一张尚不存在的表上显然没有争用问题。 CREATE TABLE语句包含引用填充良好的表的CONSTRAINT fk_name FOREIGN KEY子句。我必须:

  • 从CREATE TABLE语句中删除FOREIGN KEY子句
  • 在FK列上创建INDEX
  • 创建FK

答案 10 :(得分:2)

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

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

我运行了一个表删除,然后创建了表#1。 我在帐户#2的会话上运行了一个表更新。没有提交更改。 将帐户删除/创建脚本重新作为帐户#1重新运行。 drop table x命令出错。

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

答案 11 :(得分:1)

select
   c.owner,
   c.object_name,
   c.object_type,
   b.sid,
   b.serial#,
   b.status,
   b.osuser,
   b.machine
from
   v$locked_object a,
   v$session b,
   dba_objects c
where
   b.sid = a.session_id
and
   a.object_id = c.object_id;
   
   ALTER SYSTEM KILL SESSION 'sid,serial#';

答案 12 :(得分:-2)

我也面临类似的问题。程序员无需解决此错误。我告诉了我的oracle DBA团队。他们杀了这个会议并且像魅力一样工作。

答案 13 :(得分:-5)

Shashi提供的解决方案是最好的......不需要联系dba或其他人

进行备份

create table xxxx_backup as select * from xxxx;

删除所有行

delete from xxxx;
commit;

插入您的备份。

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