ORA-00054: ressource occupée et acquisition avec NOWAIT spécifié ou Délai expiré
13 réponses
votre table est déjà verrouillée par une requête. Comme vous avez exécuté "select for update" et n'avez pas encore engagé/rollback et de nouveau lancé select query. Faire un commit/rollback avant d'exécuter votre requête.
d'ici ORA-00054: ressource occupée et acquisition avec NOWAIT spécifié
vous pouvez également chercher le sql, le nom d'utilisateur, la machine, les informations de port et obtenir le processus réel qui détient la connexion
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;
S'Il Vous Plaît Tuer Oracle Session
utilisez la requête ci-dessous pour vérifier les informations de la session active
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;
tuer comme
alter system kill session 'SID,SERIAL#';
(par exemple, alter system kill session '13,36543'
;)
référence http://abeytom.blogspot.com/2012/08/finding-and-fixing-ora-00054-resource.html
il y a un travail très facile autour de ce problème.
si vous exécutez une trace 10046 sur votre session (google this... trop de choses à expliquer). Vous verrez qu'avant toute opération DDL Oracle fait ce qui suit:
VERROUILLER LA TABLE 'TABLE_NAME' NO WAIT
donc si une autre session a une transaction ouverte vous obtenez une erreur. Ainsi, le correctif est... roulement de tambour s'il vous plaît. Lancez votre propre serrure avant la DDL et laissez tomber le "NO WAIT".
Note Spéciale:
si vous faites le fractionnement/chute des partitions oracle verrouille juste la partition. -- pour verrouiller la sous-partie partition.
So... Les étapes suivantes résolvent le problème.
- VERROUILLER la TABLE 'NOM de la TABLE'; -- vous attendre (développeurs appel de cette suspension). jusqu'à la session avec la transaction ouverte, commits. C'est une file d'attente. donc il peut y avoir plusieurs sessions à venir de vous. mais vous n'aurez PAS d'erreur.
- exécuter DDL. Votre DSL lancera alors un verrou avec le non D'attente. Cependant, votre session a acquis la serrure. Si vous êtes bon.
- DDL auto-commits. Cela libère les serrures.
les déclarations DML 'attendront' ou comme les développeurs l'appellent 'hang' pendant que la table est verrouillée.
j'utilise ceci dans le code qui s'exécute à partir d'un travail pour laisser tomber des partitions. Il fonctionne très bien. C'est dans un base de données qui s'insère constamment à une vitesse de plusieurs centaines d'inserts/seconde. Pas d'erreurs.
si vous vous demandez. Faire ça en 11g. Je l'ai déjà fait en 10g, mais aussi dans le passé.
Cette erreur se produit lorsque la ressource est occupée. Vérifiez si vous avez des contraintes référentielles dans la requête. Ou même les tables que vous avez mentionnées dans la requête peuvent être occupées. Ils pourraient être engagés avec un autre emploi qui sera certainement énuméré dans les résultats de requête suivants:
SELECT * FROM V$SESSION WHERE STATUS = 'ACTIVE'
trouver le SID,
SELECT * FROM V$OPEN_CURSOR WHERE SID = --the id
cela se produit lorsqu'une session autre que celle utilisée pour modifier une table tient un verrou probablement à cause d'un DML (update/delete/insert). Si vous développez un nouveau système, il est probable que vous ou quelqu'un de votre équipe émette la déclaration de mise à jour et vous pourriez tuer la session sans trop de conséquences. Ou vous pouvez vous engager à partir de cette session une fois que vous savez qui a la session ouverte.
si vous avez accès à un système D'administration SQL utilisez-le pour trouver les session. Et peut-être le tuer.
vous pouvez utiliser V$session et V$lock et d'autres, mais je vous suggère google comment trouver cette session et ensuite comment la tuer.
dans un système de production, Cela dépend vraiment. Pour oracle 10g et plus, vous pouvez exécuter
LOCK TABLE mytable in exclusive mode;
alter table mytable modify mycolumn varchar2(5);
dans une session séparée mais avoir la suivante prête au cas où cela prendrait trop de temps.
alter system kill session '....
cela dépend du système que vous avez, les anciens systèmes sont plus susceptibles de ne pas commettre à chaque fois. C'est un problème car il peut y avoir des serrures de longue date. Ainsi, votre serrure empêcherait toute nouvelle serrure et attendrait une serrure qui ne sait quand sera libérée. C'est pourquoi vous avez préparé l'autre déclaration. Ou vous pouvez chercher des scripts PLSQL qui font des choses similaires automatiquement.
dans la version 11g il y a une nouvelle variable d'environnement qui fixe un temps d'attente. Je pense qu'il fait probablement quelque chose de similaire à ce que j'ai décrit. Attention, les problèmes de fermeture ne disparaissent pas.
ALTER SYSTEM SET ddl_lock_timeout=20;
alter table mytable modify mycolumn varchar2(5);
Enfin, il peut être préférable d'attendre jusqu'à il y a peu d'utilisateurs dans le système pour faire ce genre d'entretien.
votre problème ressemble à un mélange d'opérations DML & DDL. Voir L'URL qui explique ce problème:
il suffit de vérifier le processus de tenue de la session et de le tuer. Son retour à la normale.
ci-dessous SQL trouvera votre processus
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;
Puis la tuer
ALTER SYSTEM KILL SESSION 'sid,serial#'
ou
un exemple que j'ai trouvé en ligne semble avoir besoin de l'ID d'instance aussi bien modifier le système de tuer la session '130,620,@1';
dans mon cas, j'étais tout à fait sûr que c'était l'une des mes propres sessions qui bloquait. Par conséquent, il était sans danger de faire ce qui suit:
-
j'ai trouvé la session offensante avec:
SELECT * FROM V$SESSION WHERE OSUSER='my_local_username';
la session était inactive , mais elle tenait toujours la serrure en quelque sorte. Note, que vous pourriez avoir besoin d'utiliser un autre où condition dans votre cas (par exemple, essayez les champs
USERNAME
ouMACHINE
). -
tué la session en utilisant le
ID
etSERIAL#
acquis ci-dessus:alter system kill session '<id>, <serial#>';
j'ai réussi à frapper cette erreur en créant simplement une table! Il n'y avait évidemment aucun problème de conflit sur une table qui n'existait pas encore. L'énoncé CREATE TABLE
contenait une clause CONSTRAINT fk_name FOREIGN KEY
faisant référence à une table bien remplie. J'ai dû:
- supprimer la clause de clé étrangère de L'énoncé créer une TABLE
- créer un INDEX sur la colonne FK
- créer le FK
j'ai eu cette erreur quand j'ai eu 2 scripts que j'exécutais. J'ai eu:
- une session SQL * Plus connectée directement via un compte utilisateur schema (compte #1)
- une autre session SQL * Plus connectée en utilisant un compte utilisateur de schéma différent (compte n ° 2), mais en se connectant via un lien de base de données comme premier compte
j'ai lancé un drop de table, puis création de table comme compte #1.
J'ai couru un tableau de mise à jour sur le compte #2 la session. N'a pas de valider les modifications.
Relancez le drop de table / script de création comme le compte #1. Erreur sur la commande drop table x
.
Je l'ai résolu en exécutant COMMIT;
dans la session SQL*Plus du compte #2.
je suis également confronté à la même question. Rien de programmeur doit faire pour résoudre cette erreur. J'en ai informé mon équipe oracle DBA. Ils tuent la session et travaillent comme un charme.
donnée par le lien de Shashi est la meilleure... pas besoin de contacter dba ou quelqu'un d'autre
faire une sauvegarde
create table xxxx_backup as select * from xxxx;
supprimer toutes les lignes
delete from xxxx;
commit;
insérez votre sauvegarde.
insert into xxxx (select * from xxxx_backup);
commit;