为什么在更新表时出现此数据库错误?
第1行的错误: ORA-00054:资源繁忙并在指定NOWAIT或超时过期时获取
答案 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只是锁定分区。 - 所以你可以锁定分区子分区。
所以... 以下步骤解决了问题。
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 条件(例如,尝试USERNAME
或MACHINE
字段)。
使用上面获得的ID
和SERIAL#
来杀死会话:
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解释此问题:
答案 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
子句。我必须:
答案 10 :(得分:2)
当我运行2个脚本时,我发生了这个错误。我有:
我运行了一个表删除,然后创建了表#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;