Почему я получаю эту ошибку базы данных при обновлении таблицы?
ОШИБКА в строке 1: ORA-00054: ресурс занят и приобретается с указанным NOWAIT или истечением времени ожидания.
Ваша таблица уже заблокирована некоторым запросом. Например, вы выполнили "select for update" и еще не выполнили/откат и снова выпустили запрос выбора. Выполняйте фиксацию/откат перед выполнением запроса.
отсюда ORA-00054: ресурс занят и приобретается с указанным NOWAIT
Вы также можете найти информацию о sql, username, machine, port и перейти к фактическому процессу, который содержит соединение
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 Session
Используйте следующий запрос, чтобы проверить информацию активного сеанса
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
.
Для этой проблемы очень легко работать.
Если вы запустите трассировку 10046 на своем сеансе (Google слишком... чтобы объяснить). Вы увидите, что перед любой DDL-операцией Oracle делает следующее:
LOCK TABLE 'TABLE_NAME' NO WAIT
Итак, если другой сеанс имеет открытую транзакцию, вы получаете сообщение об ошибке. Так что исправить... барабан рулон пожалуйста. Выпустите свой собственный замок перед DDL и оставьте "NO WAIT".
Специальное примечание:
Если вы выполняете разделение/удаление разделов, oracle просто блокирует раздел. - так что вы можете просто заблокировать подразделение.
Итак... Следующие шаги устраняют проблему.
Операторы DML будут "ждать" или как разработчики называют это "зависанием", пока таблица заблокирована.
Я использую это в коде, который запускается из задания для удаления разделов. Он работает нормально. Он находится в базе данных, которая постоянно вставляется со скоростью в несколько сотен вставок в секунду. Нет ошибок.
если вам интересно. Делаю это в 11г. Я делал это в 10 г раньше, чем в прошлом.
Эта ошибка возникает, когда ресурс занят. Проверьте, есть ли в запросе какие-либо ссылочные ограничения. Или даже таблицы, которые вы упомянули в запросе, могут быть заняты. Они могут быть связаны с другим заданием, которое будет определенно указано в следующих результатах запроса:
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, как найти этот сеанс, а затем как его убить.
В производственной системе это действительно зависит. Для оракула 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 '....
сеанса уничтожения alter system kill session '....
если у вас нет доступа к представлениям управления?
Ваша проблема заключается в том, что вы смешиваете операции DML и DDL. См. Этот URL, который объясняет эту проблему:
В моем случае я был совершенно уверен, что это была одна из моих собственных сессий, которая блокировала. Поэтому было бы безопасно сделать следующее:
Я нашел оскорбительную сессию с:
SELECT * FROM V$SESSION WHERE OSUSER='my_local_username';
Сеанс был неактивным, но он все равно удерживал блокировку. Обратите внимание, что вам может потребоваться использовать другое условие WHERE в вашем случае (например, try USERNAME
или MACHINE
).
Убит сеанс с помощью полученных ID
и SERIAL#
сеансов:
alter system kill session '<id>, <serial#>';
Просто проверьте процесс проведения сессии и убейте его. Его обратно в норму.
Ниже 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#'
ИЛИ
Некоторый пример, который я нашел в Интернете, также нуждается в идентификаторе экземпляра alter system kill session '130,620, @1';
У меня была эта ошибка, когда у меня было 2 сценария, которые я запускал. У меня было:
Я запустил таблицу, а затем создал таблицу как учетную запись # 1.
Я провел обновление таблицы в сеансе # 2. Не совершал изменений.
Повторно запустите таблицу drop/creation script как учетную запись # 1. Получена ошибка в команде drop table x
.
Я решил это, запустив COMMIT;
в сеансе SQL * Plus учетной записи №2.
COMMIT;
, Если вы даже не можете удалить таблицу, у вас нет прав, чтобы изменить что-либо, что в первую очередь привело бы вас к этой проблеме.
Мне удалось ударить эту ошибку, просто создав таблицу! Там не было никаких проблем, очевидно, раздор на столе, который еще не существует. Оператор CREATE TABLE
содержал предложение CONSTRAINT fk_name FOREIGN KEY
, ссылающееся на хорошо заполненную таблицу. Мне пришлось:
novalidate
в alter table add constraint
. Это как-то позволяет ему работать, но оно блокируется. Затем я посмотрел на блокировки сеанса, чтобы выяснить, на каком сеансе он блокируется. А потом я убил эту сессию.
Удаление моего сообщения, поскольку оно не полезно в контексте вопроса. ORA-00054
происходит главным образом при выполнении DDL (ALTER, TRUNCATE и т.д.).
SELECT FOR UPDATE
является единственным исключением как DML, я думаю.
Я также сталкиваюсь с аналогичной проблемой. Для устранения этой ошибки ничего не требуется программисту. Я сообщил моей команде DBA оракула. Они убивают сеанс и работают как шарм.
Решение, данное ссылкой Shashi, является лучшим... не нужно связываться с dba или кем-то еще
сделать резервную копию
create table xxxx_backup as select * from xxxx;
удалить все строки
delete from xxxx;
commit;
вставьте резервную копию.
insert into xxxx (select * from xxxx_backup);
commit;