ORA-00054: ressource occupée et acquisition avec NOWAIT spécifié ou Délai expiré

Pourquoi est-ce que j'obtiens cette erreur de base de données quand je mets à jour une table?

erreur à la ligne 1: ORA-00054: resource busy et d'acquérir avec NOWAIT spécifié ou délai d'attente expiré

137
demandé sur Josep 2011-01-30 14:59:43

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.

162
répondu user258367 2011-01-30 12:02:20

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;
76
répondu Abey Tom 2017-05-23 12:10:40

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

43
répondu Chan Myae Thu 2015-10-26 17:10:57

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.

  1. 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.
  2. 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.
  3. 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é.

14
répondu Bob 2013-04-29 21:15:21

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
7
répondu Arunchunai vendan Pugalenthi 2017-10-20 18:54:22

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.

5
répondu Arturo Hernandez 2013-07-15 19:49:57

votre problème ressemble à un mélange d'opérations DML & DDL. Voir L'URL qui explique ce problème:

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

4
répondu Shashi 2011-05-05 12:37:43

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

3
répondu Mathavan John 2014-11-27 03:30:13

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 condition dans votre cas (par exemple, essayez les champs USERNAME ou MACHINE ).

  • tué la session en utilisant le ID et SERIAL# acquis ci-dessus:

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

2
répondu wrygiel 2013-09-03 10:27:07

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
1
répondu bwperrin 2015-11-19 15:05:58

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.

1
répondu vapcguy 2017-05-23 19:46:27

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.

-3
répondu Shakeer Hussain 2017-01-17 20:50:27
La Solution

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;
-5
répondu tafibo 2013-03-27 09:23:41