เหตุใดฉันจึงได้รับข้อผิดพลาดฐานข้อมูลนี้เมื่อฉันอัพเดตตาราง
ข้อผิดพลาดที่บรรทัดที่ 1: ORA-00054: ทรัพยากรไม่ว่างและได้รับพร้อมกับ NOWAIT ที่ระบุหรือหมดเวลาหมดอายุ
เหตุใดฉันจึงได้รับข้อผิดพลาดฐานข้อมูลนี้เมื่อฉันอัพเดตตาราง
ข้อผิดพลาดที่บรรทัดที่ 1: ORA-00054: ทรัพยากรไม่ว่างและได้รับพร้อมกับ NOWAIT ที่ระบุหรือหมดเวลาหมดอายุ
คำตอบ:
ตารางของคุณถูกล็อคโดยข้อความค้นหาบางส่วนแล้ว ตัวอย่างเช่นคุณอาจดำเนินการ "select for update" และยังไม่ได้ยืนยัน / ย้อนกลับและเรียกใช้คิวรีแบบเลือกอื่น ทำการคอมมิต / ย้อนกลับก่อนที่จะดำเนินการค้นหาของคุณ
จากที่นี่ORA-00054: ทรัพยากรไม่ว่างและได้รับโดยระบุ NOWAIT
นอกจากนี้คุณยังสามารถค้นหา sql, ชื่อผู้ใช้, เครื่อง, ข้อมูลพอร์ตและไปยังกระบวนการจริงที่เก็บการเชื่อมต่อ
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;
โปรดฆ่าเซสชัน Oracle
ใช้แบบสอบถามด้านล่างเพื่อตรวจสอบข้อมูลเซสชั่นที่ใช้งาน
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;
ฆ่าเหมือน
alter system kill session 'SID,SERIAL#';
(ตัวอย่างเช่นalter system kill session '13,36543'
;)
การอ้างอิงhttp://abeytom.blogspot.com/2012/08/finding-and-fixing-ora-00054-resource.htmlอ้างอิง
CONNECT
และแต่ไม่ได้สิ่งที่ต้องการนี้ด้วยบัญชีที่ฉันมีและกล่าวว่าRESOURCE
ORA-00942: table or view does not exist
ไม่ใช่ทุกคนที่อ่านหัวข้อนี้จะมีSYS
บัญชี
alter system kill session '13,36543'
จะหมดเวลาและเซสชั่นจะไม่ตาย ในกรณีดังกล่าวโปรดดู: stackoverflow.com/a/24306610/587365
connection object
ในpython
ฉันได้รับข้อผิดพลาดบางอย่าง จากนั้นจะปิดโดยไม่ต้องปิดpython script
connection object
ตอนนี้ฉันได้รับข้อผิดพลาด "LOCKWAIT" เมื่อฉันพยายามวางตารางในเซสชันอื่น เมื่อฉันลองkill session
ฉันไม่มีสิทธิ์เพียงพอ มีอะไรอีกบ้างที่สามารถกำจัดสิ่งนี้ได้?
มีวิธีแก้ไขปัญหานี้ได้ง่ายมาก
หากคุณเรียกใช้การติดตาม 10046 ในเซสชันของคุณ (google นี้ ... มากเกินไปที่จะอธิบาย) คุณจะเห็นว่าก่อนการดำเนินการ DDL ใด ๆ Oracle จะทำสิ่งต่อไปนี้:
LOCK TABLE 'TABLE_NAME' ไม่ต้องรอ
ดังนั้นหากเซสชันอื่นมีธุรกรรมเปิดคุณจะได้รับข้อผิดพลาด ดังนั้นการแก้ไขคือ ... กลองกลิ้งโปรด ออกการล็อคของคุณเองก่อน DDL และออกจาก 'ไม่รอ'
หมายเหตุพิเศษ:
ถ้าคุณกำลังแยกพาร์ติชั่น oracle พาร์ติชั่นออกมาเพียงแค่ล็อคพาร์ติชั่น. - ดังนั้นคุณสามารถล็อคพาร์ติชั่นย่อยได้
ดังนั้น ... ขั้นตอนต่อไปนี้สามารถแก้ไขปัญหาได้
คำสั่ง DML จะ 'รอ' หรือเป็นนักพัฒนาเรียกมันว่า 'แฮงค์' ในขณะที่ตารางถูกล็อค
ฉันใช้สิ่งนี้ในรหัสที่เรียกใช้จากงานเพื่อวางพาร์ติชัน มันใช้งานได้ดี มันอยู่ในฐานข้อมูลที่แทรกอย่างต่อเนื่องในอัตราหลายร้อยแทรก / วินาที ไม่มีข้อผิดพลาด
หากคุณสงสัย ทำสิ่งนี้ใน 11g ฉันได้ทำสิ่งนี้ใน 10g ก่อนหน้านี้เช่นกันในอดีต
KILL SESSION
เป็นคำตอบที่เหมาะสมสำหรับคนเหล่านี้
set_ddl_timeout
และควรเป็นอย่างไร
ข้อผิดพลาดนี้เกิดขึ้นเมื่อทรัพยากรไม่ว่าง ตรวจสอบว่าคุณมีข้อ จำกัด ในการอ้างอิงใด ๆ ในแบบสอบถาม หรือแม้แต่ตารางที่คุณพูดถึงในแบบสอบถามอาจไม่ว่าง พวกเขาอาจมีส่วนร่วมกับงานอื่น ๆ ซึ่งจะแสดงรายการอย่างแน่นอนในผลลัพธ์ของแบบสอบถามต่อไปนี้:
SELECT * FROM V$SESSION WHERE STATUS = 'ACTIVE'
ค้นหา SID
SELECT * FROM V$OPEN_CURSOR WHERE SID = --the id
ORA-00942: table or view does not exist
ฉันได้รับ
สิ่งนี้เกิดขึ้นเมื่อเซสชั่นอื่นนอกเหนือจากที่ใช้ในการเปลี่ยนตารางกำลังถือล็อคน่าจะเป็นเพราะ DML (update / delete / insert) หากคุณกำลังพัฒนาระบบใหม่เป็นไปได้ว่าคุณหรือใครบางคนในทีมของคุณออกคำสั่งการปรับปรุงและคุณสามารถฆ่าเซสชันโดยไม่ส่งผลกระทบมากนัก หรือคุณสามารถคอมมิชชันจากเซสชันนั้นเมื่อคุณรู้ว่าใครเปิดเซสชัน
หากคุณมีสิทธิ์เข้าถึงระบบผู้ดูแลระบบ SQL ให้ใช้เพื่อค้นหาเซสชันที่กระทำผิด และอาจจะฆ่ามัน
คุณสามารถใช้ v $ session และ v $ lock และอื่น ๆ ได้ แต่ฉันขอแนะนำให้คุณ google วิธีค้นหาเซสชันนั้นและวิธีฆ่ามัน
ในระบบการผลิตมันขึ้นอยู่กับ สำหรับ oracle 10g และเก่ากว่าคุณสามารถดำเนินการได้
LOCK TABLE mytable in exclusive mode;
alter table mytable modify mycolumn varchar2(5);
ในเซสชั่นแยกต่างหาก แต่มีสิ่งต่อไปนี้พร้อมในกรณีที่ใช้เวลานานเกินไป
alter system kill session '....
มันขึ้นอยู่กับว่าคุณมีระบบอะไรระบบที่มีอายุมากกว่ามีแนวโน้มที่จะไม่ส่งข้อมูลทุกครั้ง นั่นเป็นปัญหาเนื่องจากอาจมีการล็อคที่ยาวนาน ดังนั้นล็อคของคุณจะป้องกันการล็อคใหม่และรอการล็อคที่รู้ว่าเมื่อไหร่จะได้รับการปล่อยตัว นั่นคือเหตุผลที่คุณมีคำสั่งอื่น ๆ พร้อม หรือคุณอาจมองหาสคริปต์ PLSQL ที่ทำสิ่งเดียวกันโดยอัตโนมัติ
ในเวอร์ชั่น 11g มีตัวแปรสภาพแวดล้อมใหม่ที่กำหนดเวลารอ ฉันคิดว่ามันน่าจะทำสิ่งที่คล้ายกับที่ฉันอธิบาย โปรดทราบว่าปัญหาการล็อคจะไม่หายไป
ALTER SYSTEM SET ddl_lock_timeout=20;
alter table mytable modify mycolumn varchar2(5);
ในที่สุดอาจเป็นการดีที่สุดที่จะรอจนกว่าจะมีผู้ใช้ไม่กี่คนในระบบทำการบำรุงรักษาประเภทนี้
alter system kill session '....
อย่างไรหากคุณไม่มีสิทธิ์เข้าถึงมุมมองการจัดการ
ในกรณีของฉันฉันค่อนข้างแน่ใจว่าเป็นหนึ่งในเซสชันของฉันเองซึ่งกำลังบล็อก ดังนั้นจึงปลอดภัยที่จะทำสิ่งต่อไปนี้:
ฉันพบเซสชันที่ละเมิดด้วย:
SELECT * FROM V$SESSION WHERE OSUSER='my_local_username';
เซสชันไม่ได้ใช้งานแต่ยังคงล็อคอยู่ โปรดทราบว่าคุณอาจจำเป็นต้องใช้เงื่อนไขWHEREอื่น ๆในกรณีของคุณ (เช่นลองUSERNAME
หรือMACHINE
ฟิลด์)
ฆ่าเซสชันโดยใช้ID
และSERIAL#
ได้รับด้านบน:
alter system kill session '<id>, <serial#>';
แก้ไขโดย @thermz:หากไม่มีการสืบค้นเซสชันเปิดก่อนหน้านี้ให้ลองทำดู แบบสอบถามนี้สามารถช่วยคุณหลีกเลี่ยงข้อผิดพลาดทางไวยากรณ์ขณะที่กำลังฆ่าเซสชัน:
SELECT 'ALTER SYSTEM KILL SESSION '''||SID||','||SERIAL#||''' immediate;' FROM V$SESSION WHERE OSUSER='my_local_username_on_OS'
เพียงตรวจสอบกระบวนการที่ถือเซสชั่นและฆ่ามัน มันกลับมาเป็นปกติ
ด้านล่าง SQL จะค้นหากระบวนการของคุณ
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;
จากนั้นฆ่ามัน
ALTER SYSTEM KILL SESSION 'sid,serial#'
หรือ
ตัวอย่างบางส่วนที่ฉันพบทางออนไลน์ดูเหมือนว่าจะต้องใช้รหัสอินสแตนซ์และเปลี่ยนระบบการฆ่าเซสชัน '130,620, @ 1';
ปัญหาของคุณดูเหมือนว่าคุณกำลังผสมการทำงาน DML & DDL ดู URL นี้ซึ่งอธิบายถึงปัญหานี้:
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#';
ฉันจัดการกับข้อผิดพลาดนี้เมื่อสร้างตาราง! เห็นได้ชัดว่าไม่มีปัญหาการโต้แย้งในตารางที่ยังไม่มีอยู่ CREATE TABLE
คำสั่งบรรจุCONSTRAINT fk_name FOREIGN KEY
ข้ออ้างอิงตารางดีที่มีประชากรหนาแน่น ฉันต้อง:
novalidate
alter table add constraint
วิธีนี้จะช่วยให้มันทำงาน แต่มันล็อค จากนั้นฉันดูที่การล็อคเซสชันเพื่อค้นหาว่าการล็อคเซสชันใด จากนั้นฉันก็ฆ่าเซสชั่นนั้น
ฉันพบข้อผิดพลาดนี้เมื่อฉันมี 2 สคริปต์ที่ฉันใช้อยู่ ฉันมี:
ฉันวิ่งโต๊ะจากนั้นสร้างโต๊ะเป็นบัญชี # 1 ฉันทำการอัปเดตตารางในเซสชันของบัญชี # 2 ไม่ยอมรับการเปลี่ยนแปลง เรียกใช้สคริปต์วาง / สร้างตารางซ้ำอีกครั้งในบัญชี # 1 มีข้อผิดพลาดในdrop table x
คำสั่ง
ฉันแก้ไขได้ด้วยการทำงานCOMMIT;
ในเซสชัน SQL * Plus ของบัญชี # 2
COMMIT;
ทำงาน หากคุณไม่สามารถวางโต๊ะคุณไม่ได้รับอนุญาตให้แก้ไขสิ่งใดก็ตามที่จะนำคุณเข้าสู่ปัญหานี้ตั้งแต่แรก
ฉันยังเผชิญกับปัญหาที่คล้ายกัน โปรแกรมเมอร์ไม่ต้องทำเพื่อแก้ไขข้อผิดพลาดนี้ ฉันแจ้งทีมงาน DBA ของ Oracle พวกเขาฆ่าเซสชั่นและทำงานเหมือนมีเสน่ห์
ทางออกที่ได้จากลิงค์ของ Shashi นั้นดีที่สุด ... ไม่จำเป็นต้องติดต่อ dba หรือคนอื่น
ทำการสำรองข้อมูล
create table xxxx_backup as select * from xxxx;
ลบแถวทั้งหมด
delete from xxxx;
commit;
ใส่สำรองของคุณ
insert into xxxx (select * from xxxx_backup);
commit;