Pourquoi est-ce que j'obtiens cette erreur de base de données lorsque je mets à jour une table?
ERREUR à la ligne 1: ORA-00054: ressource occupée et acquisition avec NOWAIT spécifié ou timeout expiré
Pourquoi est-ce que j'obtiens cette erreur de base de données lorsque je mets à jour une table?
ERREUR à la ligne 1: ORA-00054: ressource occupée et acquisition avec NOWAIT spécifié ou timeout expiré
Réponses:
Votre table est déjà verrouillée par une requête. Par exemple, vous pouvez avoir exécuté "select for update" et n'avez pas encore validé / annulé et déclenché une autre requête de sélection. Faites un commit / rollback avant d'exécuter votre requête.
à partir d'ici ORA-00054: ressource occupée et acquisition avec NOWAIT spécifié
Vous pouvez également rechercher le sql, le nom d'utilisateur, la machine, les informations de port et accéder au 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;
Veuillez tuer la session Oracle
Utilisez la requête ci-dessous pour vérifier les informations de 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
CONNECT
et RESOURCE
, mais pas ce dont il a besoin, avec le compte que j'ai, et dit ORA-00942: table or view does not exist
. Tout le monde ne lisant pas ce fil n'aura pas le SYS
compte.
alter system kill session '13,36543'
le délai expirera et la session ne mourra pas. Dans ce cas, voir: stackoverflow.com/a/24306610/587365
connection object
in, python
j'ai eu une erreur. Ensuite, le python script
est fermé sans fermer correctement le connection object
. Maintenant, j'obtiens l'erreur "LOCKWAIT" lorsque j'essaye de déposer la table dans une autre session. Quand j'essaye, kill session
je n'ai pas assez de privilèges. Que peut-on faire d'autre pour s'en débarrasser?
Il existe une solution très simple pour résoudre ce problème.
Si vous exécutez une trace 10046 sur votre session (google ceci ... trop d'explications). Vous verrez qu'avant toute opération DDL, Oracle effectue les opérations suivantes:
VERROUILLER LA TABLE "TABLE_NAME" PAS D'ATTENTE
Donc, si une autre session a une transaction ouverte, vous obtenez une erreur. Donc le correctif est ... roulement de tambour s'il vous plaît. Émettez votre propre verrou avant le DDL et laissez de côté le «PAS D'ATTENTE».
Note spéciale:
si vous divisez / supprimez des partitions, oracle verrouille simplement la partition. - pour que vous puissiez simplement verrouiller la sous-partition de partition.
Alors ... Les étapes suivantes résolvent le problème.
Les instructions DML «attendront» ou comme les développeurs l'appellent «se bloquer» pendant que la table est verrouillée.
J'utilise ceci dans le code qui fonctionne à partir d'un travail pour supprimer des partitions. Ça fonctionne bien. C'est dans une base de données qui s'insère constamment à un rythme de plusieurs centaines d'insertions / seconde. Aucune erreur.
si vous vous demandez. Faire cela en 11g. J'ai déjà fait cela en 10g dans le passé.
KILL SESSION
est la bonne réponse pour ces personnes.
set_ddl_timeout
et que devrait-elle être?
ALTER SYSTEM SET ddl_lock_timeout=20;
voir la documentation
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 peuvent être engagés dans un autre travail qui sera définitivement répertorié dans les résultats de requête suivants:
SELECT * FROM V$SESSION WHERE STATUS = 'ACTIVE'
Trouvez le SID,
SELECT * FROM V$OPEN_CURSOR WHERE SID = --the id
ORA-00942: table or view does not exist
.
Cela se produit lorsqu'une session autre que celle utilisée pour modifier une table détient un verrou probablement à cause d'un DML (mise à jour / suppression / insertion). Si vous développez un nouveau système, il est probable que vous ou quelqu'un de votre équipe émettiez 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 ouvert la session.
Si vous avez accès à un système d'administration SQL, utilisez-le pour rechercher la session incriminée. Et peut-être le tuer.
Vous pouvez utiliser v $ session et v $ lock et autres, mais je vous suggère sur Google comment trouver cette session et comment la tuer.
Dans un système de production, cela dépend vraiment. Pour oracle 10g et plus ancien, vous pouvez exécuter
LOCK TABLE mytable in exclusive mode;
alter table mytable modify mycolumn varchar2(5);
Dans une session séparée, mais préparez les éléments suivants au cas où cela prendrait trop de temps.
alter system kill session '....
Cela dépend du système dont vous disposez, les anciens systèmes sont plus susceptibles de ne pas s'engager à chaque fois. C'est un problème car il peut y avoir des serrures de longue date. Ainsi, votre verrou empêcherait tout nouveau verrou et attendrait un verrou qui, qui sait quand, sera libéré. C'est pourquoi vous avez prêt l'autre déclaration. Ou vous pouvez rechercher des scripts PLSQL qui font automatiquement des choses similaires.
Dans la version 11g, il existe une nouvelle variable d'environnement qui définit un temps d'attente. Je pense que cela fait probablement quelque chose de similaire à ce que j'ai décrit. N'oubliez pas que les problèmes de verrouillage 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 qu'il y ait peu d'utilisateurs dans le système pour effectuer ce type de maintenance.
alter system kill session '....
si vous n'avez pas accès aux vues de gestion?
Dans mon cas, j'étais tout à fait sûr que c'était l'une de mes propres sessions qui bloquait. Par conséquent, il était sûr 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 le verrou d'une manière ou d'une autre. Notez que vous devrez peut-être utiliser une autre condition WHERE dans votre cas (par exemple essayer USERNAME
ou des MACHINE
champs).
Vous avez tué la session en utilisant ID
et SERIAL#
acquis ci-dessus:
alter system kill session '<id>, <serial#>';
Edité par @thermz: si aucune des requêtes précédentes en session ouverte ne fonctionne, essayez celle-ci. Cette requête peut vous aider à éviter les erreurs de syntaxe lors de la suppression de sessions:
SELECT 'ALTER SYSTEM KILL SESSION '''||SID||','||SERIAL#||''' immediate;' FROM V$SESSION WHERE OSUSER='my_local_username_on_OS'
Vérifiez simplement le processus qui tient la session et tuez-le. Son retour à la normale.
Ci-dessous SQL trouverez 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;
Alors tuez-le
ALTER SYSTEM KILL SESSION 'sid,serial#'
OU
un exemple que j'ai trouvé en ligne semble avoir besoin de l'ID d'instance ainsi que de modifier la session d'arrêt du système '130,620, @ 1';
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#';
Votre problème semble que vous mélangez des opérations DML et DDL. Voir cette URL qui explique ce problème:
J'ai réussi à frapper cette erreur en créant simplement une table! Il n'y avait évidemment pas de problème de contention sur une table qui n'existait pas encore. L' CREATE TABLE
instruction contenait une CONSTRAINT fk_name FOREIGN KEY
clause faisant référence à une table bien remplie. J'ai dû:
novalidate
clause au alter table add constraint
. Cela permet en quelque sorte de fonctionner, mais il se verrouille. Ensuite, j'ai regardé les verrous de session pour savoir sur quelle session il verrouille. Et puis j'ai tué cette session.
J'ai eu cette erreur quand j'avais 2 scripts que j'exécutais. J'avais:
J'ai exécuté une table drop, puis la création de table en tant que compte n ° 1. J'ai exécuté une mise à jour de table sur la session du compte n ° 2. N'a pas validé les modifications. Script de suppression / création de table réexécuté en tant que compte n ° 1. Vous avez une erreur sur la drop table x
commande.
Je l'ai résolu en exécutant COMMIT;
la session SQL * Plus du compte n ° 2.
COMMIT;
. Si vous ne pouvez même pas supprimer une table, vous ne disposez pas des autorisations nécessaires pour modifier tout ce qui pourrait vous amener à résoudre ce problème en premier lieu.
Je suis également confronté au problème similaire. Rien à faire du programmeur pour résoudre cette erreur. J'ai informé mon équipe oracle DBA. Ils tuent la session et ont travaillé comme un charme.
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;