Respostas:
Sua tabela já está bloqueada por alguma consulta. Por exemplo, você pode ter executado "selecionar para atualização" e ainda não confirmou / retrocedeu e disparou outra consulta de seleção. Faça uma confirmação / reversão antes de executar sua consulta.
daqui ORA-00054: recurso ocupado e adquirido com NOWAIT especificado
Você também pode procurar as informações sql, nome de usuário, máquina, porta e acessar o processo real que mantém a conexão
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;
Matar Sessão Oracle
Use a consulta abaixo para verificar as informações da sessão ativa
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;
mate como
alter system kill session 'SID,SERIAL#';
(Por exemplo alter system kill session '13,36543'
,;)
Referência http://abeytom.blogspot.com/2012/08/finding-and-fixing-ora-00054-resource.html
CONNECT
e RESOURCE
, mas não o que for necessário, com a conta que tenho e diz ORA-00942: table or view does not exist
. Nem todo mundo lendo este tópico terá a SYS
conta.
alter system kill session '13,36543'
o tempo limite será excedido e a sessão não terminará. Nesse caso, consulte: stackoverflow.com/a/24306610/587365
connection object
in, python
recebi algum erro. Então o python script
é fechado sem fechar corretamente o connection object
. Agora, estou recebendo o erro "LOCKWAIT" quando tento soltar a tabela em outra sessão. Quando tento, kill session
não tenho privilégio suficiente. O que mais pode ser feito para se livrar disso?
Existe uma solução muito fácil para esse problema.
Se você executar um rastreamento 10046 em sua sessão (pesquise no google isso ... demais para explicar). Você verá que, antes de qualquer operação DDL, a Oracle faz o seguinte:
LOCK TABLE 'TABLE_NAME' SEM ESPERA
Portanto, se outra sessão tiver uma transação aberta, você receberá um erro. Então a solução é ... rolar o tambor, por favor. Emita seu próprio bloqueio antes da DDL e deixe de fora o 'NO WAIT'.
Nota especial:
se você estiver dividindo / largando partições, o oracle apenas bloqueia a partição. - para que você possa bloquear a subpartição da partição.
Então ... As etapas a seguir corrigem o problema.
As instruções DML 'aguardam' ou como os desenvolvedores chamam de 'travar' enquanto a tabela está bloqueada.
Eu uso isso no código que é executado em um trabalho para descartar partições. Funciona bem. Ele está em um banco de dados que é constantemente inserido a uma taxa de várias centenas de inserções / segundo. Sem erros.
se você está se perguntando. Fazendo isso em 11g. Eu já fiz isso em 10g antes e no passado.
KILL SESSION
é a resposta certa para essas pessoas.
set_ddl_timeout
e qual deve ser?
Este erro ocorre quando o recurso está ocupado. Verifique se você tem alguma restrição referencial na consulta. Ou mesmo as tabelas que você mencionou na consulta podem estar ocupadas. Eles podem estar envolvidos com algum outro trabalho que será definitivamente listado nos seguintes resultados da consulta:
SELECT * FROM V$SESSION WHERE STATUS = 'ACTIVE'
Encontre o SID,
SELECT * FROM V$OPEN_CURSOR WHERE SID = --the id
ORA-00942: table or view does not exist
.
Isso acontece quando uma sessão diferente da usada para alterar uma tabela está mantendo um bloqueio devido a um DML (atualização / exclusão / inserção). Se você estiver desenvolvendo um novo sistema, é provável que você ou alguém da sua equipe emita a declaração de atualização e você poderá interromper a sessão sem muita consequência. Ou você pode confirmar a partir dessa sessão depois de saber quem está com a sessão aberta.
Se você tiver acesso a um sistema de administração SQL, use-o para encontrar a sessão incorreta. E talvez mate.
Você pode usar v $ session e v $ lock e outros, mas sugiro que você pesquise no google como encontrar essa sessão e depois como matá-la.
Em um sistema de produção, isso realmente depende. Para o Oracle 10g e mais antigo, você pode executar
LOCK TABLE mytable in exclusive mode;
alter table mytable modify mycolumn varchar2(5);
Em uma sessão separada, mas tenha o seguinte pronto, caso demore muito.
alter system kill session '....
Depende de qual sistema você possui; é mais provável que os sistemas mais antigos não sejam confirmados todas as vezes. Esse é um problema, pois pode haver bloqueios de longa data. Portanto, seu bloqueio impediria novos bloqueios e esperaria um bloqueio que sabe quando será liberado. É por isso que você tem a outra declaração pronta. Ou você pode procurar por scripts PLSQL por aí que fazem coisas semelhantes automaticamente.
Na versão 11g, há uma nova variável de ambiente que define um tempo de espera. Eu acho que provavelmente faz algo semelhante ao que eu descrevi. Lembre-se de que os problemas de bloqueio não desaparecem.
ALTER SYSTEM SET ddl_lock_timeout=20;
alter table mytable modify mycolumn varchar2(5);
Finalmente, pode ser melhor esperar até que haja poucos usuários no sistema para fazer esse tipo de manutenção.
alter system kill session '....
se não tem acesso às visualizações de gerenciamento?
No meu caso, eu tinha certeza de que era uma das minhas próprias sessões que estava bloqueando. Portanto, era seguro fazer o seguinte:
Encontrei a sessão ofensiva com:
SELECT * FROM V$SESSION WHERE OSUSER='my_local_username';
A sessão estava inativa , mas ainda mantinha a trava de alguma forma. Observe que você pode precisar usar alguma outra condição WHERE no seu caso (por exemplo, tentativa USERNAME
ou MACHINE
campos).
Matou a sessão usando o ID
e SERIAL#
adquirido acima:
alter system kill session '<id>, <serial#>';
Editado por @thermz: Se nenhuma das consultas de sessão aberta anteriores funcionar, tente esta. Esta consulta pode ajudar a evitar erros de sintaxe ao matar sessões:
SELECT 'ALTER SYSTEM KILL SESSION '''||SID||','||SERIAL#||''' immediate;' FROM V$SESSION WHERE OSUSER='my_local_username_on_OS'
Basta verificar o processo de realização da sessão e matá-lo. Está de volta ao normal.
Abaixo do SQL, você encontrará seu processo
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;
Então mate
ALTER SYSTEM KILL SESSION 'sid,serial#'
OU
algum exemplo que encontrei on-line parece precisar do ID da instância, bem como alterar a sessão de interrupção do sistema '130,620, @ 1';
Seu problema parece que você está misturando operações DML e DDL. Veja este URL que explica esse problema:
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#';
Consegui acertar esse erro ao simplesmente criar uma tabela! Obviamente, não havia nenhum problema de contenção em uma tabela que ainda não existia. A CREATE TABLE
declaração continha uma CONSTRAINT fk_name FOREIGN KEY
cláusula referenciando uma tabela bem preenchida. Eu precisei:
novalidate
cláusula ao arquivo alter table add constraint
. De alguma forma, isso funciona, mas bloqueia. Depois, observei os bloqueios da sessão para descobrir em qual sessão ele bloqueia. E então eu matei aquela sessão.
Eu tive esse erro acontecer quando eu tinha 2 scripts que eu estava executando. Eu tinha:
Executei uma queda da tabela e depois a criação da tabela como a conta nº 1. Fiz uma atualização de tabela na sessão da conta nº 2. Não efetuou alterações. Executei novamente o script de remoção / criação da tabela como a conta nº 1. Erro nodrop table x
comando.
Eu o resolvi executando COMMIT;
na sessão SQL * Plus da conta # 2.
COMMIT;
. Se você não consegue nem soltar uma tabela, não tem permissão para alterar nada que o levasse a esse problema em primeiro lugar.
Eu também enfrento o problema semelhante. Nada que o programador precise fazer para resolver esse erro. Eu informei à minha equipe de DBA da Oracle. Eles matam a sessão e funcionaram como um encanto.
A solução fornecida pelo link de Shashi é a melhor ... não é necessário entrar em contato com a dba ou com outra pessoa
faça um backup
create table xxxx_backup as select * from xxxx;
excluir todas as linhas
delete from xxxx;
commit;
insira seu backup.
insert into xxxx (select * from xxxx_backup);
commit;