Відповіді:
Ваша таблиця вже заблокована запитом. Наприклад, ви, можливо, виконали "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 робить наступне:
ЗАКЛЮЧЕНИЙ СТОЛ "TABLE_NAME" НЕ ЗАЧЕКАЙТЕ
Отже, якщо інший сеанс має відкриту транзакцію, ви отримуєте помилку. Тож виправлення полягає в ... барабанному рулоні, будь ласка. Оформіть свій власний замок перед DDL та залиште «НЕ ЗАЧЕКАЙТЕ».
Спеціальна примітка:
якщо ви робите розбиття / випадання розділів, оракул просто блокує розділ. - так що ви можете просто заблокувати підрозділ розділу.
Отже ... Наступні кроки вирішують проблему.
Висловлювання DML будуть "чекати" або як розробники називають це "висіти", коли таблиця заблокована.
Я використовую це в коді, який працює від завдання для скидання розділів. Це чудово працює. Він знаходиться в базі даних, яка постійно вставляється зі швидкістю в кілька сотень вставок / секунду. Немає помилок.
якщо вам цікаво Роблячи це в 11г. Я робив це за 10 г раніше, як і раніше.
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 (оновлення / видалення / вставка). Якщо ви розробляєте нову систему, цілком ймовірно, що ви або хтось із вашої команди видає заяву оновлення, і ви можете вбити сеанс без особливих наслідків. Або ви можете взяти на себе зобов’язання з цього сеансу, як тільки дізнаєтесь, хто має сесію.
Якщо у вас є доступ до системи адміністратора SQL, використовуйте його для пошуку порушного сеансу. І, можливо, вбити.
Ви можете використовувати v $ session та v $ lock та інші, але я пропоную вам google як знайти цей сеанс, а потім як його вбити.
У виробничій системі це дійсно залежить. Для Oracle 10 г і більше ви можете виконати
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;
. Якщо ви навіть не можете опустити таблицю, ви не маєте дозволу змінювати будь-що, що спонукало б вас до цього питання.
Я також стикаюся з подібним випуском. Нічого програміст не повинен зробити, щоб усунути цю помилку. Я повідомив свою команду Oracle DBA. Вони вбивають сеанс і спрацьовують як зачарування.
Рішення, яке надається посиланням Шаші, є найкращим ... не потрібно контактувати з dba чи кимось іншим
зробити резервну копію
create table xxxx_backup as select * from xxxx;
видалити всі рядки
delete from xxxx;
commit;
вставити резервну копію.
insert into xxxx (select * from xxxx_backup);
commit;