ORA-00054: resource bezig en ophalen met NOWAIT opgegeven of time-out verlopen

Waarom krijg ik deze databasefout wanneer ik een tabel bijwerk?

FOUT op regel 1:
ORA-00054: resource bezet en ophalen met NOWAIT opgegeven of time-out verlopen


Antwoord 1, autoriteit 100%

Uw tafel is al vergrendeld door een zoekopdracht. U hebt bijvoorbeeld “select for update” uitgevoerd en nog niet een commit/rollback uitgevoerd en een andere select-query gestart. Voer een commit/rollback uit voordat u uw zoekopdracht uitvoert.


Antwoord 2, autoriteit 45%

vanaf hier ORA-00054: resource bezig en verwerven met NOWAIT gespecificeerd

U kunt ook de sql,gebruikersnaam,machine,poortinformatie opzoeken en naar het eigenlijke proces gaan dat de verbinding bevat

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;

Antwoord 3, autoriteit 30%

Sluit Oracle-sessie af

Gebruik onderstaande zoekopdracht om actieve sessie-informatie te controleren

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;

doden zoals

alter system kill session 'SID,SERIAL#';

(Bijvoorbeeld, alter system kill session '13,36543'😉

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


Antwoord 4, autoriteit 7%

Er is een zeer eenvoudige oplossing voor dit probleem.

Als u een 10046-tracering uitvoert op uw sessie (google dit… teveel om uit te leggen). U zult zien dat Oracle vóór enige DDL-bewerking het volgende doet:

VERGRENDELTABEL ‘TABLE_NAME’ GEEN WACHT

Dus als een andere sessie een openstaande transactie heeft, krijg je een foutmelding. Dus de oplossing is… tromgeroffel alstublieft. Geef uw eigen slot uit voor de DDL en laat de ‘NO WAIT’ achterwege.

Speciale opmerking:

als je partities aan het splitsen/droppen bent, vergrendelt oracle de partitie gewoon.
— dus je kunt gewoon de partitie-subpartitie vergrendelen.

Dus…
De volgende stappen lossen het probleem op.

  1. SLOTTABEL ‘TABELNAAM’; — je zult ‘wachten’ (ontwikkelaars noemen dit hangen). tot de sessie met de open transactie, commit. Dit is een wachtrij. dus er kunnen meerdere sessies voor je liggen. maar je zult GEEN fouten maken.
  2. Voer DDL uit. Uw DDL zal dan een vergrendeling uitvoeren met de melding NO WAIT. Uw sessie heeft echter het slot gekregen. Dus je bent goed.
  3. DDL automatisch vastgelegd. Dit maakt de sloten vrij.

DML-statements zullen ‘wachten’ of, zoals ontwikkelaars het noemen, ‘hangen’ terwijl de tabel is vergrendeld.

Ik gebruik dit in code die vanuit een taak wordt uitgevoerd om partities te verwijderen. Het werkt goed. Het bevindt zich in een database die constant wordt ingevoegd met een snelheid van enkele honderden inserts/seconde. Geen fouten.

als je het je afvraagt. Doe dit in 11g. Ik heb dit in het verleden ook in 10g gedaan.


Antwoord 5, autoriteit 6%

Deze fout treedt op wanneer de bron bezet is. Controleer of je referentiële beperkingen hebt in de query. Of zelfs de tabellen die u in de query hebt genoemd, kunnen bezet zijn. Ze kunnen bezig zijn met een andere baan die zeker in de volgende zoekopdrachtresultaten zal worden vermeld:

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

Zoek de SID,

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

Antwoord 6, autoriteit 5%

In mijn geval was ik er vrij zeker van dat het een van mijn eigen sessieswas die blokkeerde. Daarom was het veilig om het volgende te doen:

  • Ik heb de gewraakte sessie gevonden met:

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

    De sessie was inactief, maar hield op de een of andere manier de vergrendeling vast. Houd er rekening mee dat u in uw geval mogelijk een andere WAAR-voorwaarde moet gebruiken (probeer bijvoorbeeld de velden USERNAMEof MACHINE).

  • Heeft de sessie afgebroken met de IDen SERIAL#die hierboven zijn verkregen:

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

Bewerkt door @thermz:Als geen van de vorige open-sessie-query’s werkt, probeer dan deze. Deze zoekopdracht kan u helpen om syntaxisfouten te voorkomen tijdens het beëindigen van sessies:

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

Antwoord 7, autoriteit 4%

Dit gebeurt wanneer een andere sessie dan de sessie die wordt gebruikt om een ​​tabel te wijzigen, vastloopt, waarschijnlijk vanwege een DML (update/delete/insert). Als u een nieuw systeem aan het ontwikkelen bent, is het waarschijnlijk dat u of iemand in uw team de update-verklaring afgeeft en dat u de sessie zou kunnen beëindigen zonder veel gevolgen. Of je kunt je committeren vanuit die sessie als je eenmaal weet wie de sessie open heeft staan.

Als je toegang hebt tot een SQL-beheersysteem, gebruik dit dan om de gewraakte sessie te vinden. En misschien doden.

Je zou v$session en v$lock en anderen kunnen gebruiken, maar ik raad je aan om te googlen hoe je die sessie kunt vinden en hoe je deze vervolgens kunt beëindigen.

In een productiesysteem hangt het er echt van af. Voor orakel 10g en ouder zou je

. kunnen uitvoeren

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

In een aparte sessie, maar houd het volgende bij de hand voor het geval het te lang duurt.

alter system kill session '....

Het hangt af van welk systeem je hebt, oudere systemen zullen waarschijnlijk niet elke keer committen. Dat is een probleem, omdat er mogelijk al lang bestaande sluizen zijn. Uw slot zou dus nieuwe sloten voorkomen en wachten op een slot dat wie weet wanneer het wordt vrijgegeven. Daarom heb je de andere verklaring klaar. Of je zou kunnen zoeken naar PLSQL-scripts die soortgelijke dingen automatisch doen.

In versie 11g is er een nieuwe omgevingsvariabele die een wachttijd instelt. Ik denk dat het waarschijnlijk iets doet wat lijkt op wat ik beschreef. Houd er rekening mee dat vergrendelingsproblemen niet verdwijnen.

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

Ten slotte is het misschien het beste om te wachten tot er weinig gebruikers in het systeem zijn om dit soort onderhoud uit te voeren.


Antwoord 8, autoriteit 3%

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

Antwoord 9, autoriteit 2%

Controleer gewoon op het proces dat de sessie vasthoudt en dood het. Het is weer normaal.

Onder SQL vindt u uw proces

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;

Dood het dan

ALTER SYSTEM KILL SESSION 'sid,serial#'

OF

een voorbeeld dat ik online heb gevonden, lijkt ook de instantie-ID nodig te hebben
verander systeem kill-sessie ‘130,620,@1’;


Antwoord 10, autoriteit 2%

Uw probleem lijkt erop dat u DML & DDL-activiteiten. Zie deze URL die dit probleem verklaart:

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


Antwoord 11

Het is me gelukt om deze fout te vinden bij het maken van een tabel! Er was duidelijk geen conflictprobleem op een tafel die nog niet bestond. De instructie CREATE TABLEbevatte een CONSTRAINT fk_name FOREIGN KEY-clausule die verwijst naar een goed gevulde tabel. Ik moest:

  • Verwijder de FOREIGN KEY-clausule uit de CREATE TABLE-instructie
  • Maak een INDEX op de FK-kolom
  • Maak de FK

Antwoord 12

Deze fout trad op toen ik 2 scripts had die ik uitvoerde. Ik had:

  • Een SQL*Plus-sessie die rechtstreeks is verbonden via een gebruikersaccount voor een schema (account #1)
  • Nog een SQL*Plus-sessie die is verbonden met een ander schemagebruikersaccount (account #2), maar verbinding maakt via een databaselink als het eerste account

Ik heb een table-drop uitgevoerd en vervolgens een table-creatie als account #1.
Ik heb een tabelupdate uitgevoerd voor de sessie van account #2. Geen wijzigingen doorgevoerd.
Voer het script voor het neerzetten/aanmaken van de tabel opnieuw uit als account #1. Er is een fout opgetreden bij de opdracht drop table x.

Ik heb het opgelost door COMMIT;uit te voeren in de SQL*Plus-sessie van account #2.


Antwoord 13

Ik heb ook te maken met hetzelfde probleem. De programmeur hoeft niets te doen om deze fout op te lossen. Ik informeerde mijn orakel DBA-team. Ze stopten de sessie en werkten als een zonnetje.


Antwoord 14

Oplossing gegeven door Shashi’s link is de beste… geen noodzaak om contact op te nemen met dba of iemand anders

maak een back-up

create table xxxx_backup as select * from xxxx;

alle rijen verwijderen

delete from xxxx;
commit;

voeg uw back-up in.

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

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes