Oracle
 sql >> база данни >  >> RDS >> Oracle

Застой в Oracle

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

РЕДАКТИРАНЕ Обяснено по по-добър начин, коригирано няколко изречения и добавен тестов случай, за да се демонстрира сценарий в безизходица.

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

Обикновено Oracle отнема секунда или две, за да открие застой и извежда грешката.

Можете да опитате с прост тестов случай, както е показано тук:Разбиране на 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, казва, че състоянието е АКТИВНО .

Нека разгледаме подробностите за сесията от друга сесия, нека я наречем СЕСИЯ 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 показва СЕСИЯ 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>

Заключение

Според мен най-добрият начин да разберете подробностите за сесията на задънена улица е да регистрирате подробностите възможно най-подробно. В противен случай е кошмар за DBA да разследва, без да е регистрирана подходяща информация. По този въпрос дори разработчикът би сметнал, че е хекулесова задача да коригира и поправи действителния дефект в дизайна, ако подробностите за грешката в застой не се регистрират многословно. И за да завършим с едно изявление, Застой се дължи на недостатък в дизайна, Oracle е само жертвата, а приложението е виновникът. Безизходиците са страшни, но посочват недостатъците в дизайна, които трябва да бъдат отстранени рано или късно.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Търсете, ако числото се съдържа в израз като:1-3,5,10-15,20

  2. Как се изпълнява изчакването на JDBC заявка на Oracle?

  3. Plsql, за да напишете номер (валута) в италианска валута без твърдо кодиран номер на превода

  4. Как да деинсталирате / напълно да премахнете Oracle 11g (клиент)?

  5. Как да намотавам към CSV форматиран файл с помощта на SQLPLUS?