Ogólnie pomaga, jeśli opublikujesz oświadczenie, które prowadzi do błędu
Gary Myers
Odpowiedzi:
222
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.
Dodałbym do tego „w innej sesji”. Jednym z typowych scenariuszy jest przetestowanie aktualizacji w narzędziu, na przykład SQL Developer lub Toad, a następnie próba uruchomienia jej w innym miejscu, podczas gdy pierwsza sesja nadal trzyma blokadę. Musisz więc zatwierdzić / przywrócić drugą sesję, zanim będziesz mógł ponownie uruchomić aktualizację.
Alex Poole,
1
Najprawdopodobniej DML (wstaw / usuń / aktualizuj) zamiast zapytania. I w innej sesji. Tylko dlatego, że facet, który zapytał, wydaje się być nowicjuszem, odpowiedź może być poprawna. Ale NIE MOŻESZ zatwierdzić w imieniu innych użytkowników w systemie produkcyjnym.
Arturo Hernandez
4
Cóż, to, co sprawiło, że miałem ten problem, było w Toad: kolega był w tej samej tabeli, co ja, kiedy chciałem usunąć wiersz, więc nie mogłem go usunąć. Kiedy przeszedł do innej tabeli, mogłem usunąć wiersze. Może pomóc komuś tam. Ale dzieje się tak tylko wtedy, gdy pracujesz z Toadem wewnątrz tabel, a nie dla zapytań.
DatRid
ostatnio wystąpił na naszym serwerze pomostowym (aplikacja Spring na WebSphere). Rozwiązaniem było podzielenie „monolitycznego” skryptu aktualizacji bazy danych na mniejsze części poprzez przeniesienie powodujących błędy instrukcji do oddzielnej usługi aktualizacji, która korzysta z oddzielnej transakcji: @Transactional (propagation = Propagation.REQUIRES_NEW)
Musiałem usunąć s.port z zapytania, ale pozwoliło mi to znaleźć winowajcę
Sibster
zamki są przejściowe. więc jeśli wstawka jest dostarczana, natychmiast zatwierdzasz. nie pojawi się w tym zapytaniu. nadal możesz otrzymać błąd, jeśli wydasz „DDL”. podczas gdy transakcja jest otwarta. zobacz mój post poniżej. To jest naprawdę łatwe do obejścia.
Bob
4
Mam ten sam problem co OP, ale nie widzę żadnej z wymienionych tabel (wybierz * z V $ LOCKED_OBJECT, na przykład zwraca ORA-00942: tabela lub widok nie istnieje). Jakieś pomysły?
random_forest_fanatic
3
Możesz nie mieć wystarczających uprawnień do przeglądania widoków zarządzania.
njplumridge
Działania następcze w związku z S.Portproblemem: dokumenty 11.2 wspominają Portjako pole w V$Session, ale dla mnie używanie 11.1 S.Portjest nieprawidłowe. Może został dodany do wersji 11.2?
64
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';)
Należy zastrzec tę odpowiedź z wymaganymi uprawnieniami. Mam CONNECTiRESOURCE , 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 SYSkonto.
vapcguy
Jeśli dodasz również wybraną kolumnę „S.OSUSER”, będziesz wiedział, który użytkownik uruchomił tę transakcję, i będzie to przydatne na wypadek, gdybyś chciał skontaktować się z użytkownikiem przed zabiciem sesji.
Narasimha,
Jeśli sesja zostanie zawieszona, alter system kill session '13,36543'upłynie limit czasu i sesja nie umrze. W takim przypadku patrz: stackoverflow.com/a/24306610/587365
Andrew Spencer
Podczas wstawiania danych do tabeli za pomocą connection objectin pythonwystąpił błąd. Następnie python scriptzamknie 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 sessionnie mam wystarczających uprawnień. Co jeszcze można zrobić, aby się tego pozbyć?
sjd
17
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.
BLOKADA TABELI „NAZWA TABELI”; - będziesz „czekać” (programiści nazywają to zawieszanie). aż do sesji z otwartą transakcją, zatwierdza. To jest kolejka. więc może być kilka sesji przed tobą. ale NIE popełnisz błędu.
Wykonaj DDL. Twój DDL uruchomi wtedy blokadę BEZ OCZEKIWANIA. Jednak twoja sesja uzyskała blokadę. Więc jesteś dobry
Automatyczne zatwierdzanie DDL. Uwalnia to zamki.
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.
ok, to jest złe w 11g użyj set_ddl_timeout, ta opcja jest dostępna tylko w 11g. oracle dokonuje zatwierdzenia przed wykonaniem DDL, więc zwalnia blokadę. W 11g możesz czekać na DDL. Robię to teraz. Działa w porządku.
Bob
3
w 11g powinieneś użyć LOCK TABLE nazwa_tabeli W TRYBIE WYŁĄCZNYM;
Kamil Roman
1
Jest to bardzo przydatne, jeśli otrzymujesz ORA-00054 z zadań wsadowych, ale podejrzewam, że większość osób lądujących tutaj (w tym OP i ja) robi pewne prace rozwojowe i pozostawiła otwartą sesję, robiąc wstawki na tym samym stole, który „ próbuję upuścić i odtworzyć. KILL SESSIONjest właściwą odpowiedzią dla tych ludzi.
Andrew Spencer,
@Bob Przykładowy kod zarówno dla 11g, jak i starego sposobu byłby miły. Jaka jest składnia set_ddl_timeouti jaka powinna być?
vapcguy
1
@vapcguy to działało dla mnie na 11g: ALTER SYSTEM SET ddl_lock_timeout=20;patrz dokumenty
rshdev
13
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:
Nie wszyscy będą mieli dostęp do tych widoków. I dostać ORA-00942: table or view does not exist.
vapcguy
W takich przypadkach administratorzy DB są odpowiedzialni za dostarczenie tych informacji.
Arunchunaivendan
Nie zawsze. Musiałem spróbować to rozszyfrować i obejść ten kod, i ani ja, ani moje konto usługi nie będą mieć tych praw.
vapcguy
7
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;altertable 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;altertable 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.
Jak znaleźć sesję, dla której chcesz zabić, alter system kill session '....jeśli nie masz dostępu do widoków zarządzania?
vapcguy
Tego nie wiem.
Arturo Hernandez
7
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 USERNAMElub MACHINEpola).
Zabił sesję przy użyciu IDi 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'
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 TABLEOświadczenie zawierało CONSTRAINT fk_name FOREIGN KEYklauzulę przedstawieniu dobrze zaludnionych tabeli. Musiałem:
Usuń klauzulę FOREIGN KEY z instrukcji CREATE TABLE
Właśnie miałem ten sam problem. Byłem w stanie utworzyć tabelę po usunięciu definicji fk z instrukcji ddl, ale nie mogę jej dodać nawet po utworzeniu indeksu w kolumnie.
vadipp,
Byłem w stanie to rozwiązać. Najpierw dodałem novalidateklauzulę 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ę.
vadipp,
3
Miałem ten błąd, gdy miałem 2 uruchomione skrypty. Miałem:
Sesja SQL * Plus połączona bezpośrednio przy użyciu konta użytkownika schematu (konto nr 1)
Kolejna sesja SQL * Plus połączona przy użyciu innego konta użytkownika schematu (konto nr 2), ale łączenie się przez łącze bazy danych jako pierwsze konto
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.
Jeśli nie masz uprawnień do upuszczenia tabeli, co będziesz robić? Zła odpowiedź
Shakeer Hussain
1
Shakeer, to był tylko przykład tego, co robiłem, kiedy mi się przydarzyło - nie rozwiązanie problemu - który był w mojej ostatniej linii - uruchomienie COMMIT;. Jeśli nie możesz nawet upuścić stołu, nie masz uprawnień do zmiany czegokolwiek, co doprowadziłoby Cię do tego problemu.
vapcguy
-2
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.
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.
źródło
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
źródło
S.Port
problemem: dokumenty 11.2 wspominająPort
jako pole wV$Session
, ale dla mnie używanie 11.1S.Port
jest nieprawidłowe. Może został dodany do wersji 11.2?Proszę zabić Oracle Session
Użyj poniższego zapytania, aby sprawdzić informacje o aktywnej sesji
zabij jak
(Na przykład
alter system kill session '13,36543'
;)Odniesienie http://abeytom.blogspot.com/2012/08/finding-and-fixing-ora-00054-resource.html
źródło
CONNECT
iRESOURCE
, ale nie cokolwiek tego potrzebuje, z kontem, które mam i mówiORA-00942: table or view does not exist
. Nie wszyscy czytający ten wątek będą mieliSYS
konto.alter system kill session '13,36543'
upłynie limit czasu i sesja nie umrze. W takim przypadku patrz: stackoverflow.com/a/24306610/587365connection object
inpython
wystąpił błąd. Następniepython script
zamknie się bez prawidłowego zamknięciaconnection 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.
źródło
KILL SESSION
jest właściwą odpowiedzią dla tych ludzi.set_ddl_timeout
i jaka powinna być?ALTER SYSTEM SET ddl_lock_timeout=20;
patrz dokumentyTen 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:
Znajdź SID,
źródło
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ć
W osobnej sesji, ale przygotuj następujące na wypadek, gdyby trwało to zbyt długo.
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ą.
Wreszcie najlepiej może poczekać, aż w systemie będzie niewielu użytkowników wykonujących tego rodzaju czynności konserwacyjne.
źródło
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
lubMACHINE
pola).Zabił sesję przy użyciu
ID
iSERIAL#
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'
źródło
Po prostu sprawdź proces wstrzymujący sesję i zabij ją. Wrócił do normy.
Poniżej SQL znajdziesz swój proces
Więc zabij to
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”;
źródło
Twój problem wygląda na mieszanie operacji DML i DDL. Zobacz ten adres URL, który wyjaśnia ten problem:
http://www.orafaq.com/forum/t/54714/2/
źródło
źródło
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łoCONSTRAINT fk_name FOREIGN KEY
klauzulę przedstawieniu dobrze zaludnionych tabeli. Musiałem:źródło
novalidate
klauzulę doalter 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 w
drop table x
polecenia.Rozwiązałem go, uruchamiając
COMMIT;
sesję SQL * Plus konta nr 2.źródło
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.
źródło
Rozwiązanie podane przez link Shashi jest najlepsze ... nie trzeba kontaktować się z dba lub kimś innym
zrób kopię zapasową
usuń wszystkie wiersze
włóż kopię zapasową.
źródło