Warum wird dieser Datenbankfehler angezeigt, wenn ich eine Tabelle aktualisiere?
FEHLER in Zeile 1: ORA-00054: Ressource belegt und mit NOWAIT angegeben oder Timeout abgelaufen
Warum wird dieser Datenbankfehler angezeigt, wenn ich eine Tabelle aktualisiere?
FEHLER in Zeile 1: ORA-00054: Ressource belegt und mit NOWAIT angegeben oder Timeout abgelaufen
Antworten:
Ihre Tabelle ist bereits durch eine Abfrage gesperrt. Beispielsweise haben Sie möglicherweise "Zur Aktualisierung auswählen" ausgeführt und noch keine Festschreibungsabfrage festgeschrieben / zurückgesetzt und ausgelöst. Führen Sie ein Commit / Rollback durch, bevor Sie Ihre Abfrage ausführen.
von hier ORA-00054: Ressource belegt und mit NOWAIT angegeben erwerben
Sie können auch die SQL-, Benutzernamen-, Computer- und Portinformationen nachschlagen und zum eigentlichen Prozess gelangen, der die Verbindung enthält
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;
Bitte beenden Sie die Oracle-Sitzung
Verwenden Sie die folgende Abfrage, um die aktiven Sitzungsinformationen zu überprüfen
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;
töte wie
alter system kill session 'SID,SERIAL#';
(Zum Beispiel alter system kill session '13,36543'
;)
Referenz http://abeytom.blogspot.com/2012/08/finding-and-fixing-ora-00054-resource.html
CONNECT
und RESOURCE
, aber nicht was auch immer dies braucht, mit dem Konto, das ich habe, und sagt ORA-00942: table or view does not exist
. Nicht jeder, der diesen Thread liest, hat den SYS
Account.
alter system kill session '13,36543'
eine Zeitüberschreitung auf und die Sitzung wird nicht beendet. In diesem Fall siehe: stackoverflow.com/a/24306610/587365
connection object
in habe python
ich einen Fehler erhalten. Dann wird das python script
geschlossen, ohne das richtig zu schließen connection object
. Jetzt erhalte ich den Fehler "LOCKWAIT", wenn ich versuche, die Tabelle in einer anderen Sitzung zu löschen. Wenn ich es versuche, habe kill session
ich nicht genug Privilegien. Was kann man noch tun, um dies loszuwerden?
Es gibt eine sehr einfache Lösung für dieses Problem.
Wenn Sie in Ihrer Sitzung einen 10046-Trace ausführen (googeln Sie dies ... zu viel, um es zu erklären). Sie werden sehen, dass Oracle vor jeder DDL-Operation Folgendes ausführt:
LOCK TABLE 'TABLE_NAME' KEINE WARTUNG
Wenn also eine andere Sitzung eine offene Transaktion hat, wird eine Fehlermeldung angezeigt. Das Problem ist also ... Trommelwirbel bitte. Stellen Sie Ihre eigene Sperre vor der DDL aus und lassen Sie das 'NO WAIT' weg.
Spezielle Notiz:
Wenn Sie Partitionen teilen / löschen, sperrt Oracle die Partition einfach. - Sie können also einfach die Partitionsunterpartition sperren.
Also ... Die folgenden Schritte beheben das Problem.
DML-Anweisungen warten, oder wie Entwickler sie als "hängen" bezeichnen, während die Tabelle gesperrt ist.
Ich verwende dies in Code, der von einem Job ausgeführt wird, um Partitionen zu löschen. Es funktioniert gut. Es befindet sich in einer Datenbank, die ständig mit einer Geschwindigkeit von mehreren hundert Einfügungen / Sekunde eingefügt wird. Keine Fehler.
wenn Sie sich fragen. Tun Sie dies in 11g. Ich habe dies auch schon in der Vergangenheit in 10 g gemacht.
KILL SESSION
ist die richtige Antwort für diese Leute.
set_ddl_timeout
und was soll sie sein?
Dieser Fehler tritt auf, wenn die Ressource ausgelastet ist. Überprüfen Sie, ob die Abfrage referenzielle Einschränkungen enthält. Oder sogar die Tabellen, die Sie in der Abfrage erwähnt haben, sind möglicherweise ausgelastet. Sie sind möglicherweise mit einem anderen Job beschäftigt, der in den folgenden Abfrageergebnissen definitiv aufgeführt wird:
SELECT * FROM V$SESSION WHERE STATUS = 'ACTIVE'
Finden Sie die SID,
SELECT * FROM V$OPEN_CURSOR WHERE SID = --the id
ORA-00942: table or view does not exist
.
Dies geschieht, wenn eine andere Sitzung als die zum Ändern einer Tabelle verwendete eine Sperre enthält, die wahrscheinlich auf eine DML zurückzuführen ist (Aktualisieren / Löschen / Einfügen). Wenn Sie ein neues System entwickeln, ist es wahrscheinlich, dass Sie oder jemand in Ihrem Team die Update-Anweisung herausgibt und Sie die Sitzung ohne große Konsequenzen beenden können. Oder Sie können sich aus dieser Sitzung verpflichten, sobald Sie wissen, wer die Sitzung geöffnet hat.
Wenn Sie Zugriff auf ein SQL-Administrationssystem haben, verwenden Sie es, um die fehlerhafte Sitzung zu finden. Und vielleicht töte es.
Sie könnten v $ session und v $ lock und andere verwenden, aber ich schlage vor, Sie googeln, wie Sie diese Sitzung finden und dann beenden.
In einem Produktionssystem kommt es wirklich darauf an. Für Oracle 10g und älter können Sie ausführen
LOCK TABLE mytable in exclusive mode;
alter table mytable modify mycolumn varchar2(5);
Halten Sie in einer separaten Sitzung Folgendes bereit, falls es zu lange dauert.
alter system kill session '....
Es hängt davon ab, über welches System Sie verfügen. Ältere Systeme werden mit größerer Wahrscheinlichkeit nicht jedes Mal festgeschrieben. Dies ist ein Problem, da möglicherweise lange Schlösser vorhanden sind. Ihr Schloss würde also neue Sperren verhindern und auf ein Schloss warten, das weiß, wann es freigegeben wird. Deshalb haben Sie die andere Aussage bereit. Oder Sie könnten nach PLSQL-Skripten suchen, die ähnliche Dinge automatisch ausführen.
In Version 11g gibt es eine neue Umgebungsvariable, die eine Wartezeit festlegt. Ich denke, es macht wahrscheinlich etwas Ähnliches wie das, was ich beschrieben habe. Wohlgemerkt, dass Sperrprobleme nicht verschwinden.
ALTER SYSTEM SET ddl_lock_timeout=20;
alter table mytable modify mycolumn varchar2(5);
Schließlich kann es am besten sein, zu warten, bis sich nur noch wenige Benutzer im System befinden, um diese Art der Wartung durchzuführen.
alter system kill session '....
wenn Sie keinen Zugriff auf die Verwaltungsansichten haben?
In meinem Fall war ich mir ziemlich sicher, dass es eine meiner eigenen Sitzungen war, die blockierte. Daher war es sicher, Folgendes zu tun:
Ich fand die beleidigende Sitzung mit:
SELECT * FROM V$SESSION WHERE OSUSER='my_local_username';
Die Sitzung war inaktiv , hielt aber irgendwie die Sperre. Beachten Sie, dass Sie in Ihrem Fall möglicherweise eine andere WHERE- Bedingung verwenden müssen (z. B. try USERNAME
oder MACHINE
Felder).
Tötete die Sitzung mit dem ID
und SERIAL#
erworben oben:
alter system kill session '<id>, <serial#>';
Bearbeitet von @thermz: Wenn keine der vorherigen Open-Session-Abfragen funktioniert, versuchen Sie diese. Diese Abfrage kann Ihnen helfen, Syntaxfehler beim Beenden von Sitzungen zu vermeiden:
SELECT 'ALTER SYSTEM KILL SESSION '''||SID||','||SERIAL#||''' immediate;' FROM V$SESSION WHERE OSUSER='my_local_username_on_OS'
Überprüfen Sie einfach, ob die Sitzung gehalten wird, und beenden Sie sie. Es ist wieder normal.
Unter SQL finden Sie Ihren Prozess
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;
Dann töte es
ALTER SYSTEM KILL SESSION 'sid,serial#'
ODER
Ein Beispiel, das ich online gefunden habe, scheint auch die Instanz-ID zu benötigen, um die System-Kill-Sitzung '130,620, @ 1' zu ändern.
Ihr Problem scheint, als würden Sie DML- und DDL-Operationen mischen. Siehe diese URL, die dieses Problem erklärt:
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#';
Ich habe diesen Fehler beim einfachen Erstellen einer Tabelle festgestellt! Es gab offensichtlich kein Konfliktproblem auf einem Tisch, der noch nicht existierte. Die CREATE TABLE
Anweisung enthielt eine CONSTRAINT fk_name FOREIGN KEY
Klausel, die auf eine gut ausgefüllte Tabelle verweist. Ich musste:
novalidate
Klausel hinzugefügt alter table add constraint
. Das lässt es irgendwie laufen, aber es sperrt. Dann habe ich mir die Sitzungssperren angesehen, um herauszufinden, für welche Sitzung sie gesperrt sind. Und dann habe ich diese Sitzung beendet.
Ich hatte diesen Fehler, als ich 2 Skripte hatte, die ich ausführte. Ich hatte:
Ich habe eine Tabellenablage ausgeführt und dann die Tabellenerstellung als Konto Nr. 1. Ich habe ein Tabellen-Update für die Sitzung von Konto 2 ausgeführt. Keine Änderungen vorgenommen. Skript zum Löschen / Erstellen von Tabellen als Konto Nr. 1 erneut ausgeführt. Fehler beim drop table x
Befehl.
Ich habe es gelöst, indem ich COMMIT;
in der SQL * Plus-Sitzung von Konto 2 ausgeführt habe.
COMMIT;
. Wenn Sie nicht einmal eine Tabelle löschen können, haben Sie nicht die Berechtigung, etwas zu ändern, das Sie überhaupt in dieses Problem bringen würde.
Ich stehe auch vor dem ähnlichen Problem. Der Programmierer muss nichts tun, um diesen Fehler zu beheben. Ich informierte mein Orakel-DBA-Team. Sie haben die Sitzung beendet und wie ein Zauber gearbeitet.
Die von Shashis Link gegebene Lösung ist die beste ... Sie müssen sich nicht an dba oder eine andere Person wenden
Erstelle eine Sicherung
create table xxxx_backup as select * from xxxx;
Alle Zeilen löschen
delete from xxxx;
commit;
Fügen Sie Ihr Backup ein.
insert into xxxx (select * from xxxx_backup);
commit;