Yanıtlar:
Tablonuz zaten bir sorgu tarafından kilitlendi. Örneğin, "güncelleme için seç" i çalıştırmış ve henüz başka bir seçme sorgusu taahhüt etmemiş / geri almamış olabilirsiniz. Sorgunuzu çalıştırmadan önce bir taahhüt / geri alma işlemi yapın.
buradan ORA-00054: kaynak meşgul ve belirtilen NOWAIT ile edin
Ayrıca sql, kullanıcı adı, makine, port bilgilerini arayabilir ve bağlantıyı tutan gerçek işleme ulaşabilirsiniz
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;
Lütfen Oracle Oturumunu Öldürün
Etkin oturum bilgilerini kontrol etmek için aşağıdaki sorguyu kullanın
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;
gibi öldür
alter system kill session 'SID,SERIAL#';
(Örneğin alter system kill session '13,36543'
;;)
Referans http://abeytom.blogspot.com/2012/08/finding-and-fixing-ora-00054-resource.html
CONNECT
ve RESOURCE
ben var ve diyor hesapla, her neyse bu ihtiyaçları değil ORA-00942: table or view does not exist
. Bu konuyu okuyan herkesin SYS
hesabı olmayacak .
alter system kill session '13,36543'
aşımı olur ve oturum ölmez. Bu durumda bkz. Stackoverflow.com/a/24306610/587365
connection object
de python
i bazı hata var. Sonra python script
düzgün kapatılmadan kapatılır connection object
. Şimdi başka bir oturumda tablo bırakmaya çalıştığınızda "LOCKWAIT" hatası alıyorum. Denediğimde kill session
yeterince privilage yok. Bundan kurtulmak için başka neler yapılabilir?
Bu sorun için çok kolay bir çözüm var.
Oturumunuzda 10046'lık bir iz çalıştırıyorsanız (google bu ... açıklamak için çok fazla). Herhangi bir DDL işleminden önce Oracle'ın aşağıdakileri yaptığını göreceksiniz:
KİLİT TABLOSU 'TABLE_NAME' BEKLEMEZ
Başka bir oturumda açık bir işlem varsa, bir hata alırsınız. Yani düzeltme ... davul silindiri lütfen. DDL'den önce kendi kilidinizi düzenleyin ve 'BEKLEME YOK' seçeneğini bırakın.
Özel not:
bölme / bırakma bölümleri yapıyorsanız oracle sadece bölümü kilitler. - böylece bölüm alt bölümünü kilitleyebilirsiniz.
Yani ... Aşağıdaki adımlar sorunu çözer.
DML ifadeleri 'kilitlenir' veya geliştiriciler tablo kilitliyken buna "askıda kal" der.
Bu bölümleri bırakmak için bir işten çalışan kodda kullanın. İyi çalışıyor. Saniyede birkaç yüz ekleme hızında sürekli olarak eklenen bir veritabanındadır. Hata yok.
Eğer merak ediyorsanız. Bunu 11g'de yapıyoruz. Bunu daha önce de 10g'da yaptım.
KILL SESSION
bu insanlar için doğru cevaptır.
set_ddl_timeout
ve ne olmalı?
ALTER SYSTEM SET ddl_lock_timeout=20;
bkz. dokümanlar
Bu hata, kaynak meşgul olduğunda oluşur. Sorguda herhangi bir başvuru kısıtlaması olup olmadığını kontrol edin. Veya sorguda belirttiğiniz tablolar meşgul olabilir. Aşağıdaki sorgu sonuçlarında kesinlikle listelenecek başka bir iş ile meşgul olabilirler:
SELECT * FROM V$SESSION WHERE STATUS = 'ACTIVE'
SID'yi bulun,
SELECT * FROM V$OPEN_CURSOR WHERE SID = --the id
ORA-00942: table or view does not exist
.
Bu, bir tabloyu değiştirmek için kullanılan oturumdan farklı bir oturumun DML (güncelleme / silme / ekleme) nedeniyle bir kilit tutması durumunda olur. Yeni bir sistem geliştiriyorsanız, sizin veya ekibinizdeki birisinin güncelleme bildirimini yayınlaması muhtemeldir ve oturumu çok fazla sonuç vermeden öldürebilirsiniz. Veya oturumun kimin açık olduğunu öğrendikten sonra o oturumdan taahhütte bulunabilirsiniz.
Bir SQL yönetici sistemine erişiminiz varsa, rahatsız edici oturumu bulmak için kullanın. Ve belki de öldürün.
V $ oturumu ve v $ kilidi ve diğerlerini kullanabilirsiniz, ancak Google'a bu oturumu nasıl bulacağınızı ve sonra nasıl öldüreceğinizi öneririm.
Bir üretim sisteminde, bu gerçekten bağlıdır. 10 g ve üzeri kehanet için
LOCK TABLE mytable in exclusive mode;
alter table mytable modify mycolumn varchar2(5);
Ayrı bir oturumda ancak çok uzun sürmesi durumunda aşağıdakileri hazır bulundurun.
alter system kill session '....
Hangi sisteme sahip olduğunuza bağlıdır, eski sistemlerin her seferinde taahhütte bulunmama olasılığı daha yüksektir. Uzun süreli kilitler olabileceğinden bu bir problemdir. Böylece kilidiniz yeni kilitleri önler ve kimin ne zaman serbest bırakılacağını bilen bir kilit bekler. Bu yüzden başka bir ifadeye hazırsınız. Ya da benzer şeyleri otomatik olarak yapan PLSQL komut dosyalarını arayabilirsiniz.
11g sürümünde, bekleme süresini ayarlayan yeni bir ortam değişkeni vardır. Sanırım muhtemelen tarif ettiğim şeye benzer bir şey yapıyor. Kilitleme sorunlarının ortadan kalkmadığını unutmayın.
ALTER SYSTEM SET ddl_lock_timeout=20;
alter table mytable modify mycolumn varchar2(5);
Son olarak, bu tür bir bakım yapmak için sistemde çok az kullanıcı olana kadar beklemek en iyisi olabilir.
alter system kill session '....
Yönetim görünümlerine erişiminiz yoksa öldürülecek oturumu nasıl öğreneceksiniz ?
Benim durumumda, engelli olan kendi oturumlarımdan biri olduğundan emindim . Bu nedenle, aşağıdakileri yapmak güvenlidir:
Sorunlu oturumu şu şekilde buldum:
SELECT * FROM V$SESSION WHERE OSUSER='my_local_username';
Oturum etkin değildi , ama yine de bir şekilde kilidi tuttu. Durumunuzda başka bir WHERE koşulu kullanmanız gerekebileceğini unutmayın (örneğin, deneme USERNAME
veya MACHINE
alanlar).
Oturumu kullanarak yukarıda ID
ve sonra SERIAL#
edinilmiş:
alter system kill session '<id>, <serial#>';
@Thermz tarafından düzenlendi: Önceki açık oturum sorgularının hiçbiri işe yaramazsa bunu deneyin. Bu sorgu, oturumları öldürürken sözdizimi hatalarından kaçınmanıza yardımcı olabilir:
SELECT 'ALTER SYSTEM KILL SESSION '''||SID||','||SERIAL#||''' immediate;' FROM V$SESSION WHERE OSUSER='my_local_username_on_OS'
Sadece oturumu tutan süreci kontrol edin ve öldürün. Normale döndü.
SQL'in altında işleminizi bulacaksınız
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;
Öyleyse öldür
ALTER SYSTEM KILL SESSION 'sid,serial#'
VEYA
çevrimiçi bulduğum bazı örneklerin, örneğin 130,620, @ 1 'sistem öldürme oturumunu değiştirmesi için örnek kimliğine ihtiyacı olduğu görülüyor;
Sorununuz DML ve DDL işlemlerini karıştırıyor gibi görünüyor. Bu sorunu açıklayan bu URL'ye bakın:
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#';
Sadece bir tablo oluştururken bu hatayı vurmayı başardım! Tabii ki henüz var olmayan bir tabloda herhangi bir çekişme sorunu yoktu. CREATE TABLE
İfadesi bir içeriyordu CONSTRAINT fk_name FOREIGN KEY
iyi nüfuslu tabloya başvuran maddesini. Yapmak zorundaydım:
novalidate
madde ekledim alter table add constraint
. Bu bir şekilde çalışmasına izin verir, ancak kilitlenir. Sonra hangi oturumda kilitlendiğini öğrenmek için oturum kilitlerine baktım. Sonra o oturumu öldürdüm.
Çalıştığım 2 komut dosyası olduğunda bu hatayla karşılaştım. Sahiptim:
Bir tablo bırakma, sonra hesap oluşturma olarak tablo oluşturma # 1. Hesap # 2'nin oturumunda bir tablo güncellemesi yaptım. Değişiklik yapmadı. Tablo bırakma / oluşturma komut dosyasını hesap 1 olarak yeniden çalıştırdı. Komutta hata var drop table x
.
COMMIT;
Hesap 2'nin SQL * Plus oturumunda çalıştırarak çözdüm .
COMMIT;
. Bir tabloyu bile bırakamıyorsanız, öncelikle bu konuya girmenizi sağlayacak hiçbir şeyi değiştirme izniniz yoktur.
Ben de benzer bir sorunla karşı karşıyayım. Bu hatayı gidermek için hiçbir programcının yapması gerekmez. Kahin DBA ekibime haber verdim. Oturumu öldürüyorlar ve bir cazibe gibi çalıştılar.
Shashi'nin bağlantısıyla verilen çözüm en iyisidir ... dba veya başka biriyle iletişime geçmeye gerek yoktur
yedekleme yapmak
create table xxxx_backup as select * from xxxx;
tüm satırları sil
delete from xxxx;
commit;
yedeklemenizi ekleyin.
insert into xxxx (select * from xxxx_backup);
commit;