sql >> Database >  >> RDS >> Oracle

Impasses in Oracle

Ik wil een script maken waarbij de orakelsessies die in een impasse raken automatisch worden afgebroken

BEWERKEN Op een betere manier uitgelegd, enkele zinnen gecorrigeerd en een testcase toegevoegd om een ​​impassescenario te demonstreren.

Waarom wil je het wiel opnieuw uitvinden? Oracle detecteert automatisch een deadlock, gooit ORA-00060: deadlock detected while waiting for resource , en draait een van de transacties terug die betrokken waren bij de impasse die Oracle als het slachtoffer besloot. De eerdere succesvolle transacties worden niet teruggedraaid. Zelfs na de deadlock-fout, als een commit wordt uitgegeven, wordt de vorige succesvolle transactie vastgelegd. Op dit moment zal de transactie van de andere sessie ook slagen en kunt u een commit uitgeven. U hoeft hier niets expliciet te doen. Deadlocks worden automatisch opgeheven -- u hoeft nooit te wissen hen.

Gewoonlijk heeft Oracle een seconde of twee nodig om een ​​impasse te detecteren en de fout te veroorzaken.

U kunt het proberen met een eenvoudige testcase, zoals hier wordt gedemonstreerd:Oracle Deadlock begrijpen

Laten we eens naar een testcase kijken -

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

Noteer de tijd van elke transactie, ik heb de tijd op timing ingesteld voor een beter begrip.

SESSIE:1

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

1 row updated.

Elapsed: 00:00:00.00

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

Op dit moment blijft SESSIE 2 wachten .

SESSIE:1

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

Op dit moment, SESSIE 2 is het slachtoffer van een impasse, SESSIE 1 wacht nog steeds.

Laten we eens kijken naar de sessiedetails van SESSIE 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>

Dus, v$session details wanneer bekeken in SESSIE 2 , d.w.z. SID 14, zegt dat de status ACTIEF is .

Laten we eens kijken naar de sessiedetails van een andere sessie, laten we het SESSIE 3 noemen ter wille. Onthoud, SESSIE 1 wacht nog steeds.

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>

Dus, voor andere sessies, SESSIE 2 , d.w.z. SID 14, is INACTIEF . SESSIE 1 is nog WACHT met gebeurtenis enq: TX - row lock contention .

Laten we ons inzetten voor SESSIE 2 -

12:22:18 SQL> commit;

Commit complete.

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

Op dit punt wordt de vergrendeling vrijgegeven voor SESSIE 1 , laten we ook sessie 1 vastleggen -

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 toont SESSIE 1 wachtte zo lang op SESSIE 2 werd gepleegd.

Om samen te vatten, hier is het hele verhaal van sessie 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>

Om samen te vatten, hier is het hele verhaal van sessie 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>

Laten we nu eens kijken welke transactie daadwerkelijk is teruggedraaid en welke is vastgelegd -

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>

Conclusie

Naar mijn mening is de beste manier om de sessiedetails van een impasse te kennen, door de details zo uitgebreid mogelijk te loggen. Anders is het een nachtmerrie voor een DBA om te onderzoeken zonder dat de juiste informatie is vastgelegd. Trouwens, zelfs een ontwikkelaar zou het een enorme taak vinden om de eigenlijke ontwerpfout te corrigeren en op te lossen als de details van de impassefout niet uitgebreid worden vastgelegd. En om af te sluiten met een one-liner statement:een impasse is te wijten aan een ontwerpfout, Oracle is slechts het slachtoffer en de applicatie is de boosdoener. Deadlocks zijn eng, maar ze wijzen op de ontwerpfouten die vroeg of laat moeten worden verholpen.



  1. Oracle SQL:tijdstempels in waar-clausule

  2. Hoe ON CONFLICT werkt in SQLite

  3. Lopend totaal berekenen in roodverschuiving

  4. Oct2014CPU crasht ArcGIS Desktop