En general, es útil si publica la declaración que conduce al error
Gary Myers
Respuestas:
222
Su tabla ya está bloqueada por alguna consulta. Por ejemplo, puede haber ejecutado "seleccionar para actualizar" y aún no haber confirmado / revertido y disparado otra consulta de selección. Haga un commit / rollback antes de ejecutar su consulta.
Agregaría 'en otra sesión' a eso. Un escenario común es que ha probado la actualización en una herramienta, por ejemplo, SQL Developer o Toad, y luego ha intentado ejecutarla en otro lugar mientras la primera sesión todavía mantiene el bloqueo. Por lo tanto, debe confirmar / revertir la otra sesión antes de poder ejecutar la actualización nuevamente.
Alex Poole
1
Lo más probable es DML (insertar / eliminar / actualizar) en lugar de una consulta. Y en otra sesión. Solo porque el chico que preguntó parece ser un novato, la respuesta puede ser correcta. Pero NO PUEDE comprometerse en nombre de otros usuarios en un sistema de producción.
Arturo Hernández
44
Bueno, lo que me hizo tener ese problema fue en Toad: un colega estaba en la misma tabla que yo cuando quería eliminar una fila, por lo que no pude eliminarla. Cuando cambió a otra tabla, pude eliminar filas. Tal vez ayude a alguien por ahí. Pero esto es solo si trabaja con Toad dentro de las tablas, y no para consultas.
DatRid
Ocurrió recientemente en nuestro servidor de ensayo (aplicación Spring en WebSphere). La solución fue separar el script de actualización de la base de datos "monolítico" en partes más pequeñas moviendo las declaraciones que causan errores a un servicio de actualización separado que usa una transacción separada: @Transactional (propagation = Propagation.REQUIRES_NEW)
Tuve que eliminar s.port de la consulta, pero me permitió encontrar al culpable
Sibster
Las cerraduras son transitorias. así que si viene el inserto, entonces se compromete de inmediato. no se mostrará en esta consulta. aún puede obtener el error si emite el 'DDL'. mientras la transacción está abierta. vea mi publicación a continuación. Esto es realmente fácil de solucionar.
Bob
44
Tengo el mismo problema que el OP, pero no puedo ver ninguna de las tablas que menciona (seleccione * de V $ LOCKED_OBJECT, por ejemplo, devuelve ORA-00942: la tabla o vista no existe). ¿Algunas ideas?
random_forest_fanatic
3
Es posible que no tenga los privilegios suficientes para mirar las vistas de administración.
njplumridge
Seguimiento del S.Portproblema: los documentos de 11.2 mencionan Portcomo un campo en V$Session, pero para mí, usar 11.1 S.Portno es válido. ¿Se agregó para 11.2, tal vez?
63
Por favor, mata la sesión de Oracle
Use la consulta a continuación para verificar la información de la sesión activa
Debería advertir esta respuesta con qué privilegios se requieren. Tengo CONNECTy RESOURCE, pero no lo que sea que esto necesite, con la cuenta que tengo, y dice ORA-00942: table or view does not exist. No todos los que lean este hilo tendrán la SYScuenta.
vapcguy
Si agrega la columna de selección 'S.OSUSER' también sabrá qué usuario estaba ejecutando esa transacción y será útil en caso de que desee consultar con el usuario antes de finalizar la sesión.
Narasimha
Si se cuelga la sesión, alter system kill session '13,36543'se agota el tiempo de espera y la sesión no morirá. En ese caso, consulte: stackoverflow.com/a/24306610/587365
Andrew Spencer el
Mientras que la inserción de datos en una tabla mediante una connection objecten pythonTengo algunos errores. Luego python scriptse cierra sin cerrar correctamente el connection object. Ahora recibo el error "LOCKWAIT" cuando intento dejar la tabla en otra sesión. Cuando lo intento kill sessionno tengo suficiente privilegio. ¿Qué más se puede hacer para deshacerse de esto?
sjd
17
Hay una solución muy fácil para este problema.
Si ejecuta una traza 10046 en su sesión (google esto ... demasiado para explicar). Verá que antes de cualquier operación DDL, Oracle hace lo siguiente:
LOCK TABLE 'TABLE_NAME' SIN ESPERA
Entonces, si otra sesión tiene una transacción abierta, obtendrá un error. Entonces la solución es ... tambor por favor. Emita su propio bloqueo antes del DDL y omita el 'NO ESPERE'.
Nota especial:
si está haciendo partición / caída de particiones, Oracle simplemente bloquea la partición. - para que puedas bloquear la subpartición de partición.
Entonces ... Los siguientes pasos solucionan el problema.
TABLA DE BLOQUEO 'NOMBRE DE LA TABLA'; - "Esperarás" (los desarrolladores llaman a esto colgar). hasta la sesión con la transacción abierta, confirma. Esta es una cola Por lo tanto, puede haber varias sesiones por delante. pero NO te equivocarás.
Ejecute DDL. Su DDL ejecutará un bloqueo con NO WAIT. Sin embargo, su sesión ha adquirido el bloqueo. Entonces eres bueno.
DDL auto-commits. Esto libera las cerraduras.
Las declaraciones DML 'esperarán' o como los desarrolladores lo llaman 'colgar' mientras la tabla está bloqueada.
Lo uso en el código que se ejecuta desde un trabajo para soltar particiones. Funciona bien. Está en una base de datos que se inserta constantemente a una velocidad de varios cientos de inserciones / segundo. Sin errores.
si te preguntas Haciendo esto en 11g. He hecho esto en 10 g antes también en el pasado.
Ok, esto está mal. en 11g, use set_ddl_timeout. Esto solo está disponible en 11g. Oracle realiza una confirmación antes de hacer DDL, por lo que libera el bloqueo. En 11g, puede hacer que su DDL espere. Estoy haciendo eso ahora. Funciona bien.
Bob
3
en 11g deberías usar LOCK TABLE table_name EN MODO EXCLUSIVO;
Kamil Roman
1
Esto es realmente útil si está obteniendo el ORA-00054 de trabajos por lotes, pero sospecho que la mayoría de las personas que aterrizan aquí (incluido el OP y yo) están desarrollando algo y han dejado una sesión abierta haciendo inserciones en la misma mesa que ' Estoy intentando soltar y recrear. KILL SESSIONes la respuesta correcta para estas personas.
Andrew Spencer
@Bob El código de ejemplo para 11g y para la forma anterior sería bueno. ¿Para qué es la sintaxis set_ddl_timeouty cuál debería ser?
vapcguy
1
@vapcguy esto funcionó para mí en 11g: ALTER SYSTEM SET ddl_lock_timeout=20;ver documentos
rshdev
13
Este error ocurre cuando el recurso está ocupado. Compruebe si tiene alguna restricción referencial en la consulta. O incluso las tablas que ha mencionado en la consulta pueden estar ocupadas. Es posible que se comprometan con algún otro trabajo que se enumerará definitivamente en los siguientes resultados de la consulta:
No todos tendrán acceso a estas vistas. Consigo ORA-00942: table or view does not exist.
vapcguy
En tales casos, los administradores de DB son responsables de proporcionar esa información.
Arunchunaivendan
No siempre. Tuve que intentar que el código resolviera esto y lo solucionara, y ni yo ni mi cuenta de servicio tendremos estos derechos.
vapcguy
7
Esto sucede cuando una sesión distinta a la utilizada para alterar una tabla mantiene un bloqueo probablemente debido a un DML (actualizar / eliminar / insertar). Si está desarrollando un nuevo sistema, es probable que usted o alguien de su equipo emita la declaración de actualización y podría matar la sesión sin muchas consecuencias. O puede comprometerse desde esa sesión una vez que sepa quién tiene la sesión abierta.
Si tiene acceso a un sistema de administración SQL, úselo para encontrar la sesión ofensiva. Y tal vez matarlo.
Puede usar v $ session y v $ lock y otros, pero le sugiero que busque en Google cómo encontrar esa sesión y luego cómo matarla.
En un sistema de producción, realmente depende. Para Oracle 10g y anteriores, puede ejecutar
LOCK TABLE mytable in exclusive mode;altertable mytable modify mycolumn varchar2(5);
En una sesión separada, pero tenga listo lo siguiente en caso de que tarde demasiado.
alter system kill session '....
Depende de qué sistema tenga, es más probable que los sistemas más antiguos no se comprometan cada vez. Eso es un problema ya que puede haber bloqueos de larga data. Por lo tanto, su bloqueo evitará cualquier bloqueo nuevo y esperará un bloqueo que quién sabe cuándo se liberará. Es por eso que tiene lista la otra declaración. O podría buscar scripts PLSQL que hagan cosas similares automáticamente.
En la versión 11g hay una nueva variable de entorno que establece un tiempo de espera. Creo que probablemente haga algo similar a lo que describí. Tenga en cuenta que los problemas de bloqueo no desaparecen.
ALTER SYSTEM SET ddl_lock_timeout=20;altertable mytable modify mycolumn varchar2(5);
Finalmente, puede ser mejor esperar hasta que haya pocos usuarios en el sistema para realizar este tipo de mantenimiento.
¿Y cómo descubre la sesión para matar alter system kill session '....si no tiene acceso a las vistas de administración?
vapcguy
Eso no lo se.
Arturo Hernández
7
En mi caso, estaba bastante seguro de que era una de mis sesiones que estaba bloqueando. Por lo tanto, era seguro hacer lo siguiente:
Encontré la sesión ofensiva con:
SELECT * FROM V$SESSION WHERE OSUSER='my_local_username';
La sesión estaba inactiva , pero aún mantenía el bloqueo de alguna manera. Tenga en cuenta que es posible que necesite usar alguna otra condición WHERE en su caso (por ejemplo, try USERNAMEo MACHINEfields).
Eliminó la sesión usando IDy SERIAL#adquirió lo anterior:
alter system kill session '<id>, <serial#>';
Editado por @thermz: si ninguna de las consultas anteriores de sesión abierta funciona, prueba esta. Esta consulta puede ayudarlo a evitar errores de sintaxis al matar sesiones:
SELECT 'ALTER SYSTEM KILL SESSION '''||SID||','||SERIAL#||''' immediate;' FROM V$SESSION WHERE OSUSER='my_local_username_on_OS'
Si ninguna de las consultas de sesión abierta anteriores funciona, pruebe esta.
thermz
5
Simplemente verifique el proceso de celebración de la sesión y elimínelo. Ha vuelto a la normalidad.
Debajo de SQL encontrará su proceso
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;
Entonces mátalo
ALTER SYSTEM KILL SESSION 'sid,serial#'
O
algún ejemplo que encontré en línea parece necesitar la identificación de la instancia, así como alterar la sesión de muerte del sistema '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#';
¡Me las arreglé para dar con este error cuando simplemente creé una tabla! Obviamente, no había ningún problema de contención en una tabla que aún no existía. La CREATE TABLEdeclaración contenía una CONSTRAINT fk_name FOREIGN KEYcláusula que hacía referencia a una tabla bien poblada. Tuve que:
Elimine la cláusula FOREIGN KEY de la instrucción CREATE TABLE
Acabo de tener el mismo problema. Pude crear la tabla después de eliminar la definición fk de la instrucción ddl, pero no puedo agregarla incluso después de crear el índice en la columna.
vadipp
Pude resolverlo. Primero, agregué una novalidatecláusula al alter table add constraint. Esto de alguna manera lo deja correr, pero se bloquea. Luego miré los bloqueos de sesión para averiguar en qué sesión se bloquea. Y luego maté esa sesión.
vadipp
3
Tuve este error cuando tuve 2 scripts que estaba ejecutando. Yo tenía:
Una sesión SQL * Plus conectada directamente usando una cuenta de usuario de esquema (cuenta # 1)
Otra sesión SQL * Plus conectada utilizando una cuenta de usuario de esquema diferente (cuenta # 2), pero conectando a través de un enlace de base de datos como la primera cuenta
Ejecuté una caída de la tabla, luego la creación de la tabla como cuenta # 1. Ejecuté una actualización de la tabla en la sesión de la cuenta # 2. No cometió cambios. Se volvió a ejecutar el script de creación / caída de la tabla como cuenta n. ° 1. Tengo un error en el drop table xcomando.
Lo resolví ejecutando COMMIT;en la sesión SQL * Plus de la cuenta # 2.
Si no tiene permisos para colocar una tabla, ¿qué hará? Mala respuesta
Shakeer Hussain
1
Shakeer, eso fue solo un ejemplo de lo que estaba haciendo cuando me sucedió a mí, no la solución al problema, que estaba en mi última línea: ejecutar a COMMIT;. Si ni siquiera puede soltar una tabla, no tiene los permisos para alterar nada que lo lleve a este problema en primer lugar.
vapcguy
-2
También me enfrento al problema similar. Nada programador tiene que hacer para resolver este error. Informé a mi equipo Oracle DBA. Matan la sesión y funcionan como un encanto.
eliminar / truncar no son intercambiables. realizar grandes cantidades de eliminaciones tiene implicaciones masivas de rendimiento. Esto es realmente malo
Respuestas:
Su tabla ya está bloqueada por alguna consulta. Por ejemplo, puede haber ejecutado "seleccionar para actualizar" y aún no haber confirmado / revertido y disparado otra consulta de selección. Haga un commit / rollback antes de ejecutar su consulta.
fuente
desde aquí ORA-00054: recurso ocupado y adquirir con NOWAIT especificado
También puede buscar la información de sql, nombre de usuario, máquina, puerto y acceder al proceso real que mantiene la conexión
fuente
S.Port
problema: los documentos de 11.2 mencionanPort
como un campo enV$Session
, pero para mí, usar 11.1S.Port
no es válido. ¿Se agregó para 11.2, tal vez?Por favor, mata la sesión de Oracle
Use la consulta a continuación para verificar la información de la sesión activa
matar como
(Por ejemplo
alter system kill session '13,36543'
,;)Referencia http://abeytom.blogspot.com/2012/08/finding-and-fixing-ora-00054-resource.html
fuente
CONNECT
yRESOURCE
, pero no lo que sea que esto necesite, con la cuenta que tengo, y diceORA-00942: table or view does not exist
. No todos los que lean este hilo tendrán laSYS
cuenta.alter system kill session '13,36543'
se agota el tiempo de espera y la sesión no morirá. En ese caso, consulte: stackoverflow.com/a/24306610/587365connection object
enpython
Tengo algunos errores. Luegopython script
se cierra sin cerrar correctamente elconnection object
. Ahora recibo el error "LOCKWAIT" cuando intento dejar la tabla en otra sesión. Cuando lo intentokill session
no tengo suficiente privilegio. ¿Qué más se puede hacer para deshacerse de esto?Hay una solución muy fácil para este problema.
Si ejecuta una traza 10046 en su sesión (google esto ... demasiado para explicar). Verá que antes de cualquier operación DDL, Oracle hace lo siguiente:
LOCK TABLE 'TABLE_NAME' SIN ESPERA
Entonces, si otra sesión tiene una transacción abierta, obtendrá un error. Entonces la solución es ... tambor por favor. Emita su propio bloqueo antes del DDL y omita el 'NO ESPERE'.
Nota especial:
si está haciendo partición / caída de particiones, Oracle simplemente bloquea la partición. - para que puedas bloquear la subpartición de partición.
Entonces ... Los siguientes pasos solucionan el problema.
Las declaraciones DML 'esperarán' o como los desarrolladores lo llaman 'colgar' mientras la tabla está bloqueada.
Lo uso en el código que se ejecuta desde un trabajo para soltar particiones. Funciona bien. Está en una base de datos que se inserta constantemente a una velocidad de varios cientos de inserciones / segundo. Sin errores.
si te preguntas Haciendo esto en 11g. He hecho esto en 10 g antes también en el pasado.
fuente
KILL SESSION
es la respuesta correcta para estas personas.set_ddl_timeout
y cuál debería ser?ALTER SYSTEM SET ddl_lock_timeout=20;
ver documentosEste error ocurre cuando el recurso está ocupado. Compruebe si tiene alguna restricción referencial en la consulta. O incluso las tablas que ha mencionado en la consulta pueden estar ocupadas. Es posible que se comprometan con algún otro trabajo que se enumerará definitivamente en los siguientes resultados de la consulta:
Encuentra el SID,
fuente
ORA-00942: table or view does not exist
.Esto sucede cuando una sesión distinta a la utilizada para alterar una tabla mantiene un bloqueo probablemente debido a un DML (actualizar / eliminar / insertar). Si está desarrollando un nuevo sistema, es probable que usted o alguien de su equipo emita la declaración de actualización y podría matar la sesión sin muchas consecuencias. O puede comprometerse desde esa sesión una vez que sepa quién tiene la sesión abierta.
Si tiene acceso a un sistema de administración SQL, úselo para encontrar la sesión ofensiva. Y tal vez matarlo.
Puede usar v $ session y v $ lock y otros, pero le sugiero que busque en Google cómo encontrar esa sesión y luego cómo matarla.
En un sistema de producción, realmente depende. Para Oracle 10g y anteriores, puede ejecutar
En una sesión separada, pero tenga listo lo siguiente en caso de que tarde demasiado.
Depende de qué sistema tenga, es más probable que los sistemas más antiguos no se comprometan cada vez. Eso es un problema ya que puede haber bloqueos de larga data. Por lo tanto, su bloqueo evitará cualquier bloqueo nuevo y esperará un bloqueo que quién sabe cuándo se liberará. Es por eso que tiene lista la otra declaración. O podría buscar scripts PLSQL que hagan cosas similares automáticamente.
En la versión 11g hay una nueva variable de entorno que establece un tiempo de espera. Creo que probablemente haga algo similar a lo que describí. Tenga en cuenta que los problemas de bloqueo no desaparecen.
Finalmente, puede ser mejor esperar hasta que haya pocos usuarios en el sistema para realizar este tipo de mantenimiento.
fuente
alter system kill session '....
si no tiene acceso a las vistas de administración?En mi caso, estaba bastante seguro de que era una de mis sesiones que estaba bloqueando. Por lo tanto, era seguro hacer lo siguiente:
Encontré la sesión ofensiva con:
SELECT * FROM V$SESSION WHERE OSUSER='my_local_username';
La sesión estaba inactiva , pero aún mantenía el bloqueo de alguna manera. Tenga en cuenta que es posible que necesite usar alguna otra condición WHERE en su caso (por ejemplo, try
USERNAME
oMACHINE
fields).Eliminó la sesión usando
ID
ySERIAL#
adquirió lo anterior:alter system kill session '<id>, <serial#>';
Editado por @thermz: si ninguna de las consultas anteriores de sesión abierta funciona, prueba esta. Esta consulta puede ayudarlo a evitar errores de sintaxis al matar sesiones:
SELECT 'ALTER SYSTEM KILL SESSION '''||SID||','||SERIAL#||''' immediate;' FROM V$SESSION WHERE OSUSER='my_local_username_on_OS'
fuente
Simplemente verifique el proceso de celebración de la sesión y elimínelo. Ha vuelto a la normalidad.
Debajo de SQL encontrará su proceso
Entonces mátalo
O
algún ejemplo que encontré en línea parece necesitar la identificación de la instancia, así como alterar la sesión de muerte del sistema '130,620, @ 1';
fuente
Parece que su problema está mezclando operaciones DML y DDL. Consulte esta URL que explica este problema:
http://www.orafaq.com/forum/t/54714/2/
fuente
fuente
¡Me las arreglé para dar con este error cuando simplemente creé una tabla! Obviamente, no había ningún problema de contención en una tabla que aún no existía. La
CREATE TABLE
declaración contenía unaCONSTRAINT fk_name FOREIGN KEY
cláusula que hacía referencia a una tabla bien poblada. Tuve que:fuente
novalidate
cláusula alalter table add constraint
. Esto de alguna manera lo deja correr, pero se bloquea. Luego miré los bloqueos de sesión para averiguar en qué sesión se bloquea. Y luego maté esa sesión.Tuve este error cuando tuve 2 scripts que estaba ejecutando. Yo tenía:
Ejecuté una caída de la tabla, luego la creación de la tabla como cuenta # 1. Ejecuté una actualización de la tabla en la sesión de la cuenta # 2. No cometió cambios. Se volvió a ejecutar el script de creación / caída de la tabla como cuenta n. ° 1. Tengo un error en el
drop table x
comando.Lo resolví ejecutando
COMMIT;
en la sesión SQL * Plus de la cuenta # 2.fuente
COMMIT;
. Si ni siquiera puede soltar una tabla, no tiene los permisos para alterar nada que lo lleve a este problema en primer lugar.También me enfrento al problema similar. Nada programador tiene que hacer para resolver este error. Informé a mi equipo Oracle DBA. Matan la sesión y funcionan como un encanto.
fuente
La solución dada por el enlace de Shashi es la mejor ... no es necesario contactar a dba u otra persona
hacer una copia de seguridad
eliminar todas las filas
inserte su copia de seguridad.
fuente