为什么我得到这个数据库错误时,我更新表?
第1行错误: ORA-00054:资源繁忙,指定NOWAIT或超时获取
为什么我得到这个数据库错误时,我更新表?
第1行错误: ORA-00054:资源繁忙,指定NOWAIT或超时获取
当前回答
我有这个错误发生时,我有2个脚本,我正在运行。我有:
SQL*Plus会话直接使用模式用户帐户(帐户#1)连接 另一个SQL*Plus会话使用不同的模式用户帐户(帐户#2)连接,但作为第一个帐户跨数据库链接连接
我运行了一个表删除,然后创建表作为帐户#1。 我对账号2的会话进行了表更新。没有提交更改。 以帐户#1的身份重新运行表删除/创建脚本。删除表x命令出错。
我通过运行COMMIT来解决这个问题;在账号#2的SQL*Plus会话中。
其他回答
Shashi的链接给出的解决方案是最好的…不需要联系dba或其他人
备份
create table xxxx_backup as select * from xxxx;
删除所有行
delete from xxxx;
commit;
插入备份。
insert into xxxx (select * from xxxx_backup);
commit;
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;
这个问题有一个很简单的解决办法。
如果你在会话上运行10046跟踪(谷歌this…太多了,无法解释)。在任何DDL操作之前,Oracle会执行以下操作:
锁定表“table_name”不等待
因此,如果另一个会话有一个打开的事务,就会得到一个错误。所以解决办法是……请击鼓。在DDL之前发出您自己的锁,并省略'NO WAIT'。
特别注意:
如果你正在分割/删除分区,oracle只是锁定分区。 你可以锁定分区子分区。
所以… 下面的步骤可以解决这个问题。
锁定表'表名';你会“等待”(开发者称之为挂起)。直到具有打开事务的会话提交为止。这是一个队列。所以在你之前可能会有几个疗程。但是你不会出错。 执行DDL。然后DDL将使用NO WAIT运行一个锁。但是,您的会话已经获得了锁。所以你很好。 DDL自动提交。这就释放了锁。
当表被锁定时,DML语句将“等待”或开发人员称之为“挂起”。
我在从作业运行以删除分区的代码中使用了这个功能。它工作得很好。它位于一个以每秒几百个插入的速度不断插入的数据库中。没有错误。
如果你想知道的话。用11g做这个。我以前也用10g做过这个。
只需检查持有会话的进程并杀死它。一切恢复正常。
在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 删除系统会话:
当用于修改表的会话以外的会话持有锁时,就会发生这种情况,可能是因为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);
最后,最好等到系统中用户较少时再进行这种维护。