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.
- 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.
- 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.
- 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
USERNAME
ofMACHINE
). -
Heeft de sessie afgebroken met de
ID
enSERIAL#
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 TABLE
bevatte 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;