sql >> Databáze >  >> RDS >> Oracle

Zablokování v Oracle

Chci vytvořit skript, kde se relace orákula, která uvíznou na mrtvém bodě, automaticky zabijí

UPRAVIT Vysvětleno lepším způsobem, opraveno několik vět a přidán testovací případ, který demonstruje scénář uváznutí.

Proč chcete znovu vynalézat kolo? Oracle automaticky detekuje zablokování a vyvolá ORA-00060: deadlock detected while waiting for resource a vrátí zpět jednu z transakcí zapojených do patové situace, o které se Oracle rozhodl jako o oběti. Předchozí úspěšné transakce nebudou vráceny zpět. I po chybě uváznutí, pokud je vydáno potvrzení, bude předchozí úspěšná transakce potvrzena. V tomto okamžiku bude transakce druhé relace také úspěšná a můžete vydat potvrzení. Není zde nic, co byste museli výslovně dělat. Zablokování se automaticky odstraní – nikdy je nemusíte vymazat je.

Oracle obvykle trvá sekundu nebo dvě, než detekuje uváznutí a vyvolá chybu.

Můžete to zkusit pomocí jednoduchého testovacího případu, jak je ukázáno zde:Understanding Oracle Deadlock

Podívejme se na testovací případ -

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

Poznamenejte si čas každé transakce, pro lepší pochopení jsem nastavil čas na časování.

SESSION:1

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

1 row updated.

Elapsed: 00:00:00.00

REZACE: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;

V tuto chvíli SEKCE 2 stále čeká .

SESSION:1

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

V tuto chvíli REZACE 2 je obětí uváznutí, SESSION 1 stále čeká.

Podívejme se na podrobnosti relace z SEKCE 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>

Takže v$session podrobnosti při zobrazení v RELACI 2 , tj. SID 14, říká, že stav je AKTIVNÍ .

Podívejme se na detaily relace z jiné relace, nazvěme ji REZACE 3 V zájmu. Pamatujte, REZACE 1 stále čeká.

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>

Takže pro ostatní relace, REZACE 2 , tj. SID 14, je NEAKTIVNÍ . REZACE 1 stále ČEKÁ s událostí enq: TX - row lock contention .

Pojďme se zavázat k RELACI 2 -

12:22:18 SQL> commit;

Commit complete.

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

V tomto okamžiku je zámek uvolněn pro RELACI 1 , spusťme také relaci 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 ukazuje RELACI 1 čekal tak dlouho do REZE 2 byl spáchán.

Abychom to shrnuli, zde je celý příběh relace 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>

Abychom to shrnuli, zde je celý příběh ze zasedání 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>

Nyní se podívejme, která transakce byla skutečně odvolána a která byla potvrzena -

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>

Závěr

Podle mého názoru je nejlepším způsobem, jak zjistit podrobnosti relace o uváznutí, zaznamenat podrobnosti co nejpodrobněji. Jinak je pro DBA noční můra vyšetřovat bez řádných zaznamenaných informací. Pokud na to přijde, dokonce i vývojář by zjistil, že je to otřesný úkol opravit a opravit skutečnou chybu návrhu, pokud podrobnosti o chybě uváznutí nejsou zaznamenány podrobně. A na závěr prohlášením jednoho řádku:Zablokování je způsobeno chybou v designu, Oracle je pouze obětí a aplikace je viníkem. Zablokování je děsivé, ale upozorňuje na konstrukční nedostatky, které je třeba dříve nebo později napravit.



  1. Nelze předat hodnotu řetězce 1,2 jako vstup do dotazu Oracle

  2. Je možné předat název tabulky jako parametr v Oracle?

  3. Více řádků na jednu hodnotu oddělenou čárkami na serveru SQL Server

  4. Chyba při odesílání paketu QUERY