Odpowiedzi:
Twoja tabela jest już zablokowana przez jakieś zapytanie. Na przykład możliwe, że wykonałeś polecenie „wybierz do aktualizacji” i jeszcze nie zatwierdziłeś / wycofałeś i uruchomiłeś inne zapytanie wyboru. Wykonaj zatwierdzenie / wycofanie przed wykonaniem zapytania.
stąd ORA-00054: zasoby zajęte i pozyskiwanie ze wskazanym NOWAIT
Możesz także sprawdzić dane SQL, nazwę użytkownika, komputer, port i przejść do faktycznego procesu, który utrzymuje połączenie
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;
Proszę zabić Oracle Session
Użyj poniższego zapytania, aby sprawdzić informacje o aktywnej sesji
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;
zabij jak
alter system kill session 'SID,SERIAL#';
(Na przykład alter system kill session '13,36543'
;)
Odniesienie http://abeytom.blogspot.com/2012/08/finding-and-fixing-ora-00054-resource.html
CONNECT
iRESOURCE
, ale nie cokolwiek tego potrzebuje, z kontem, które mam i mówi ORA-00942: table or view does not exist
. Nie wszyscy czytający ten wątek będą mieli SYS
konto.
alter system kill session '13,36543'
upłynie limit czasu i sesja nie umrze. W takim przypadku patrz: stackoverflow.com/a/24306610/587365
connection object
in python
wystąpił błąd. Następnie python script
zamknie się bez prawidłowego zamknięcia connection object
. Teraz pojawia się błąd „LOCKWAIT”, gdy próbuję upuścić tabelę w innej sesji. Kiedy próbuję, kill session
nie mam wystarczających uprawnień. Co jeszcze można zrobić, aby się tego pozbyć?
Rozwiązanie tego problemu jest bardzo łatwe.
Jeśli w sesji uruchomisz śledzenie 10046 (google to ... za dużo, by to wyjaśnić). Zobaczysz, że przed każdą operacją DDL Oracle wykonuje następujące czynności:
ZABLOKUJ TABELĘ „TABLE_NAME” BEZ CZEKAJ
Więc jeśli inna sesja ma otwartą transakcję, pojawi się błąd. Więc poprawka polega na ... bębnie, proszę. Wydaj własną blokadę przed DDL i pomiń „BRAK OCZEKIWANIA”.
Specjalna notatka:
jeśli wykonujesz dzielenie / upuszczanie partycji, Oracle blokuje partycję. - więc możesz po prostu zablokować partycję partycji.
Więc ... Poniższe kroki rozwiązują problem.
Instrukcje DML będą „czekać” lub, jak programiści nazywają to „zawieszeniem”, gdy tabela jest zablokowana.
Używam tego w kodzie, który uruchamia się z zadania, aby usunąć partycje. To działa dobrze. Znajduje się w bazie danych, która ciągle wstawia w tempie kilkuset wstawień na sekundę. Bez błędów.
jeśli się zastanawiasz. Robi to w 11g. Zrobiłem to już wcześniej w 10 g.
KILL SESSION
jest właściwą odpowiedzią dla tych ludzi.
set_ddl_timeout
i jaka powinna być?
Ten błąd występuje, gdy zasób jest zajęty. Sprawdź, czy w zapytaniu występują ograniczenia referencyjne. Lub nawet tabele wymienione w zapytaniu mogą być zajęte. Mogą być zaangażowani w jakieś inne zadanie, które zostanie zdecydowanie wymienione w następujących wynikach zapytania:
SELECT * FROM V$SESSION WHERE STATUS = 'ACTIVE'
Znajdź SID,
SELECT * FROM V$OPEN_CURSOR WHERE SID = --the id
ORA-00942: table or view does not exist
.
Dzieje się tak, gdy sesja inna niż ta używana do zmiany tabeli trzyma blokadę prawdopodobnie z powodu DML (aktualizacja / usuwanie / wstawianie). Jeśli opracowujesz nowy system, prawdopodobne jest, że ty lub ktoś z twojego zespołu wyda instrukcję aktualizacji i możesz zakończyć sesję bez większych konsekwencji. Lub możesz zatwierdzić z tej sesji, gdy wiesz, kto ma otwartą sesję.
Jeśli masz dostęp do systemu administracyjnego SQL, użyj go do znalezienia obraźliwej sesji. I może to zabijesz.
Możesz użyć sesji v $ i blokady v $ i innych, ale sugeruję, aby google znaleźć tę sesję, a następnie ją zabić.
W systemie produkcyjnym to naprawdę zależy. Dla wyroczni 10g i starszych możesz wykonać
LOCK TABLE mytable in exclusive mode;
alter table mytable modify mycolumn varchar2(5);
W osobnej sesji, ale przygotuj następujące na wypadek, gdyby trwało to zbyt długo.
alter system kill session '....
Zależy to od posiadanego systemu, starsze systemy częściej nie zatwierdzają się za każdym razem. Jest to problem, ponieważ mogą istnieć długo stojące zamki. Twoja blokada zapobiegnie nowym blokadom i zaczeka na blokadę, która wie, kiedy zostanie zwolniona. Dlatego masz przygotowane inne oświadczenie. Możesz też poszukać skryptów PLSQL, które automatycznie robią podobne rzeczy.
W wersji 11g dostępna jest nowa zmienna środowiskowa, która ustawia czas oczekiwania. Myślę, że prawdopodobnie robi coś podobnego do tego, co opisałem. Pamiętaj, że problemy z blokowaniem nie znikają.
ALTER SYSTEM SET ddl_lock_timeout=20;
alter table mytable modify mycolumn varchar2(5);
Wreszcie najlepiej może poczekać, aż w systemie będzie niewielu użytkowników wykonujących tego rodzaju czynności konserwacyjne.
alter system kill session '....
jeśli nie masz dostępu do widoków zarządzania?
W moim przypadku byłem całkiem pewien, że to jedna z moich sesji, która blokowała. Dlatego bezpieczne było wykonanie następujących czynności:
Znalazłem obraźliwą sesję z:
SELECT * FROM V$SESSION WHERE OSUSER='my_local_username';
Sesja była nieaktywna , ale nadal jakoś utrzymywała blokadę. Pamiętaj, że w twoim przypadku może być konieczne zastosowanie innego warunku GDZIE (np. Try USERNAME
lub MACHINE
pola).
Zabił sesję przy użyciu ID
i SERIAL#
nabytych powyżej:
alter system kill session '<id>, <serial#>';
Edytowane przez @thermz: Jeśli żadne z poprzednich zapytań otwartych sesji nie działa, spróbuj tego. To zapytanie może pomóc uniknąć błędów składniowych podczas zabijania sesji:
SELECT 'ALTER SYSTEM KILL SESSION '''||SID||','||SERIAL#||''' immediate;' FROM V$SESSION WHERE OSUSER='my_local_username_on_OS'
Po prostu sprawdź proces wstrzymujący sesję i zabij ją. Wrócił do normy.
Poniżej SQL znajdziesz swój proces
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;
Więc zabij to
ALTER SYSTEM KILL SESSION 'sid,serial#'
LUB
jakiś przykład, który znalazłem online, wydaje się, że potrzebuje identyfikatora instancji, a także zmienia sesję zabijania systemu „130,620, @ 1”;
Twój problem wygląda na mieszanie operacji DML i DDL. Zobacz ten adres URL, który wyjaśnia ten problem:
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#';
Udało mi się trafić w ten błąd po prostu tworząc tabelę! Oczywiście na stole, który jeszcze nie istniał, nie było problemu z rywalizacją. CREATE TABLE
Oświadczenie zawierało CONSTRAINT fk_name FOREIGN KEY
klauzulę przedstawieniu dobrze zaludnionych tabeli. Musiałem:
novalidate
klauzulę do alter table add constraint
. To w jakiś sposób pozwala mu działać, ale blokuje się. Potem spojrzałem na blokady sesji, aby dowiedzieć się, na której sesji blokuje. A potem zabiłem tę sesję.
Miałem ten błąd, gdy miałem 2 uruchomione skrypty. Miałem:
Uruchomiłem zrzut tabeli, a następnie utworzenie tabeli jako konto nr 1. Przeprowadziłem aktualizację tabeli na sesji konta nr 2. Nie zatwierdził zmian. Ponownie uruchom skrypt upuszczania / tworzenia tabeli jako konto nr 1. Wystąpił błąd wdrop table x
polecenia.
Rozwiązałem go, uruchamiając COMMIT;
sesję SQL * Plus konta nr 2.
COMMIT;
. Jeśli nie możesz nawet upuścić stołu, nie masz uprawnień do zmiany czegokolwiek, co doprowadziłoby Cię do tego problemu.
Mam również podobny problem. Nic nie musi robić programista, aby rozwiązać ten błąd. Poinformowałem mój zespół Oracle DBA. Zabijają sesję i działają jak urok.
Rozwiązanie podane przez link Shashi jest najlepsze ... nie trzeba kontaktować się z dba lub kimś innym
zrób kopię zapasową
create table xxxx_backup as select * from xxxx;
usuń wszystkie wiersze
delete from xxxx;
commit;
włóż kopię zapasową.
insert into xxxx (select * from xxxx_backup);
commit;