2015-02-11 2 views
0

Я хочу создать сценарий, в котором сеансы оракула, которые вступают в тупик, автоматически уничтожаются. Можно узнать идентификатор сеанса для сеансов, которые входят в тупик. В настоящее время мне приходится отказываться базы данных, чтобы удалить тупик. Возможно ли решение этой проблемы?Тупики в Oracle

+2

Oracle [обнаруживает тупики автоматически] (http://docs.oracle.com/database/121/CNCPT/consist.htm#CNCPT1336), и выдает ORA-00060 на одну из сессий. Что именно вы видите и как вы создаете сценарий? –

ответ

6

Я хочу, чтобы сценарий, где оракул сессий, которые идут в тупик отстреливается автоматически

EDIT Разъяснения в лучшую сторону, исправлены несколько предложений, и добавил тестовый пример, чтобы продемонстрировать сценарий взаимоблокировки.

Почему вы хотите изобрести колесо? Oracle автоматически обнаруживает тупик, бросает ORA-00060: deadlock detected while waiting for resource и откатывает одну из транзакций, вовлеченных в тупик, которые Oracle решил в качестве жертвы. Предыдущие успешные транзакции не откатываются. Даже после ошибки тупика, если вы совершили фиксацию, будет выполнена предыдущая успешная транзакция. В это время транзакция другого сеанса также будет успешной, и вы можете выполнить фиксацию. Нет ничего, что вам нужно явно здесь сделать. Тупики автоматически очищаются - вам никогда не нужно ясно их.

Обычно Oracle занимает секунду или два, чтобы обнаружить тупик и выдает ошибку.

Вы можете попробовать с помощью простого теста, как показано здесь: Understanding Oracle Deadlock

Давайте посмотрим на тестовый пример -

SQL> CREATE TABLE t_test(col_1 NUMBER, col_2 NUMBER); 

Table created 
SQL> INSERT INTO t_test VALUES(1,2); 

1 row inserted 
SQL> INSERT INTO t_test VALUES(3,4); 

1 row inserted 

SQL> COMMIT; 

Commit complete 

SQL> SELECT * FROM t_test; 

    COL_1  COL_2 
---------- ---------- 
     1   2 
     3   4 

Примечание время каждой операции, я установить время от времени на для лучшее понимание.

СЕССИЯ: 1

12:16:06 SQL> UPDATE t_test SET col_1 = 5 WHERE col_2=2; 

1 row updated. 

Elapsed: 00:00:00.00 

СЕССИЯ: 2

12:16:04 SQL> UPDATE t_test SET col_1 = 6 WHERE col_2=4; 

1 row updated. 

Elapsed: 00:00:00.00 
12:16:31 SQL> UPDATE t_test SET col_1 = 7 WHERE col_2=2; 

На данный момент СЕССИЯ 2 держит ждет.

СЕССИЯ: 1

12:16:15 SQL> UPDATE t_test SET col_1 = 8 WHERE col_2=4; 

На данный момент СЕССИЯ 2 является жертвой взаимоблокировки, СЕССИЯ 1 все еще ждет.

Давайте посмотрим на детали сессии от СЕССИИ 2 -

12:22:15 SQL> select sid,status,program,sql_id, state, wait_class, blocking_session_status, event from v$session where schemaname='LALIT' and program='sqlplus.exe'; 

     SID STATUS PROGRAM   SQL_ID  STATE    WAIT_CLASS  BLOCKING_SE EVENT 
---------- -------- --------------- ------------- ------------------- --------------- ----------- ---------------------------------------------------------------- 
     14 ACTIVE sqlplus.exe  60qmqpmbmyhxn WAITED SHORT TIME Network   NOT IN WAIT SQL*Net message to client 
     134 ACTIVE sqlplus.exe  5x0zg4qwus29v WAITING    Application  VALID  enq: TX - row lock contention 

Elapsed: 00:00:00.00 
12:22:18 SQL> 

Таким образом, v$session детали при просмотре в СЕССИИ 2, т.е. SID 14, говорит, что статус ACTIVE.

Давайте рассмотрим детали сессии с другого сеанса, позвоним на это СЕССИЯ 3 ради. Помните, СЕССИЯ 1 все еще ждет.

SQL> set time on timing on 
12:24:41 SQL> select sid,status,program,sql_id, state, wait_class, blocking_session_status, event from v$session where schemaname='LALIT' and program='sqlplus.exe' 

     SID STATUS PROGRAM   SQL_ID  STATE    WAIT_CLASS BLOCKING_SE EVENT 
---------- -------- --------------- ------------- ------------------- ---------- ----------- ------------------------------ 
     13 ACTIVE sqlplus.exe  60qmqpmbmyhxn WAITED SHORT TIME Network NOT IN WAIT SQL*Net message to client 
     14 INACTIVE sqlplus.exe     WAITING    Idle  NO HOLDER SQL*Net message from client 
     134 ACTIVE sqlplus.exe  5x0zg4qwus29v WAITING    Applicatio VALID  enq: TX - row lock contention 
                     n 


Elapsed: 00:00:00.01 
12:24:44 SQL> 

Таким образом, для других сеансов, СЕССИЯ 2, т.е. SID 14, является НЕАКТИВНО. ЗАСЕДАНИЕ 1 по-прежнему ОЖИДАНИЕ с событием enq: TX - row lock contention.

Давайте совершать СЕССИЯ 2 -

12:22:18 SQL> commit; 

Commit complete. 

Elapsed: 00:00:00.01 
12:25:43 SQL> 

На данный момент, блокировка снимается для СЕССИИ1, давайте совершать сессии 1, а -

12:16:15 SQL> UPDATE t_test SET col_1 = 8 WHERE col_2=4; 

1 row updated. 

Elapsed: 00:08:27.29 
12:25:43 SQL> commit; 

Commit complete. 

Elapsed: 00:00:00.00 
12:26:26 SQL> 

Elapsed: 00:08:27.29 показывает SESSION 1 ждал, что до ЗАСЕДАНИЕ 2 было совершено ,

Резюмируя, здесь вся история сессии 1 -

12:16:06 SQL> UPDATE t_test SET col_1 = 5 WHERE col_2=2; 

1 row updated. 

Elapsed: 00:00:00.00 
12:16:15 SQL> UPDATE t_test SET col_1 = 8 WHERE col_2=4; 

1 row updated. 

Elapsed: 00:08:27.29 
12:25:43 SQL> commit; 

Commit complete. 

Elapsed: 00:00:00.00 
12:26:26 SQL> 

Резюмируя, здесь вся история сессии 2 -

12:16:04 SQL> UPDATE t_test SET col_1 = 6 WHERE col_2=4; 

1 row updated. 

Elapsed: 00:00:00.00 
12:16:31 SQL> UPDATE t_test SET col_1 = 7 WHERE col_2=2; 
UPDATE t_test SET col_1 = 7 WHERE col_2=2 
            * 
ERROR at line 1: 
ORA-00060: deadlock detected while waiting for resource 


Elapsed: 00:00:24.47 
12:22:15 SQL> select sid,status,program,sql_id, state, wait_class, blocking_session_status, event from v$session where schemaname='LALIT' and program='sqlplus.exe'; 

     SID STATUS PROGRAM   SQL_ID  STATE    WAIT_CLASS  BLOCKING_SE EVENT 
---------- -------- --------------- ------------- ------------------- --------------- ----------- ---------------------------------------------------------------- 
     14 ACTIVE sqlplus.exe  60qmqpmbmyhxn WAITED SHORT TIME Network   NOT IN WAIT SQL*Net message to client 
     134 ACTIVE sqlplus.exe  5x0zg4qwus29v WAITING    Application  VALID  enq: TX - row lock contention 

Elapsed: 00:00:00.00 
12:22:18 SQL> commit; 

Commit complete. 

Elapsed: 00:00:00.01 
12:25:43 SQL> 

Теперь давайте посмотрим , какая сделка фактически была отклонена и которая была совершена -

12:25:43 SQL> select * from t_test; 

    COL_1  COL_2 
---------- ---------- 
     5   2 
     8   4 

Elapsed: 00:00:00.00 
12:30:36 SQL> 

Заключение

На мой взгляд, лучший способ узнать сеансовые детали тупика войти детали настолько говорящими, насколько это возможно. Кроме того, для администратора базы данных является кошмаром для расследования без регистрации надлежащей информации. В этом случае даже разработчик обнаружил бы, что это была задача herculean, чтобы исправить и исправить фактический недостаток дизайна, если детали ошибки взаимоблокировки не задокументированы подробно. И в заключение с одним заявлением на линейку, «Тупик» вызван ошибкой дизайна, Oracle - это просто жертва, и приложение является виновником. Тупики страшны, но они указывают на недостатки дизайна, которые рано или поздно должны быть исправлены.

+2

Пятно на. Существует различие между тупиком и блокировкой сессии, и Oracle очистит взаимоблокировки (обычно) в течение примерно 3 секунд или около того. – mmmmmpie

+0

:-) Я видел столько тупиков столько раз, сколько заработал много старых приложений. В конце дня мы могли только перестроить журналы ошибок и попытаться повторно запустить убитый сеанс. Мы никогда не могли обнаружить тупик перед Oracle, он обнаруживается и обрабатывается гораздо быстрее. Если бы мне пришлось сделать что-то существенное, я бы сначала исправил дизайн приложения. Тупики страшны, но они указывают на недостатки дизайна. –

+0

Правильно. В этом случае унция профилактики стоит фунта лечения. – mmmmmpie

0

пользователя 1

update table_c set id = 200 where id = 13; 
BEGIN 
DBMS_LOCK.sleep(14); 
END; 
/
update table_c set id = 200 where id = 15; 

пользователя 2

update table_c set id = 2000 where id = 15; 

BEGIN 
DBMS_LOCK.sleep(14); 
END; 
/

update table_c set id = 1000 where id = 13; 
Смежные вопросы