sql >> Database teknologi >  >> RDS >> Oracle

dødvande i Oracle

Jeg vil lave et script, hvor orakel-sessionerne, der går i dødvande, bliver dræbt automatisk

REDIGER Forklaret på en bedre måde, rettet nogle få sætninger og tilføjet en testcase for at demonstrere dødvandsscenarie.

Hvorfor vil du genopfinde hjulet? Oracle registrerer en dødlås automatisk, kaster ORA-00060: deadlock detected while waiting for resource , og ruller tilbage en af ​​de transaktioner, der var involveret i dødvandet, som Oracle besluttede som offer. De tidligere vellykkede transaktioner rulles ikke tilbage. Selv efter deadlock-fejlen, hvis en commit udstedes, vil den tidligere succesfulde transaktion blive begået. På dette tidspunkt vil den anden sessions transaktion også lykkes, og du kan udstede en commit. Der er ikke noget, du eksplicit skal gøre her. Deadlocks ryddes automatisk – du behøver aldrig rydde dem.

Normalt tager Oracle et sekund eller to på at opdage et dødvande og kaster fejlen.

Du kan prøve med en simpel testcase som vist her:Forstå Oracle Deadlock

Lad os se på en testcase -

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

Bemærk tidspunktet for hver transaktion, jeg har sat tid på timing til for en bedre forståelse.

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

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

På dette tidspunkt bliver SESSION 2 ved med at vente .

SESSION:1

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

På dette tidspunkt, SESSION 2 er offer for dødvande, SESSION 1 venter stadig.

Lad os se på sessionsdetaljerne fra SESSION 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 detaljer, når de ses i SESSION 2 , dvs. SID 14, siger, at status er AKTIV .

Lad os se på sessionsdetaljerne fra en anden session, lad os kalde det SESSION 3 af hensyn. Husk SESSION 1 venter stadig.

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>

Så for andre sessioner, SESSION 2 , dvs. SID 14, er INAKTIV . SESSION 1 er stadig VENTER med hændelse enq: TX - row lock contention .

Lad os begå SESSION 2 -

12:22:18 SQL> commit;

Commit complete.

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

På dette tidspunkt udløses låsen for SESSION 1 , lad os også begå session 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 viser SESSION 1 ventede så længe indtil SESSION 2 var begået.

For at opsummere, her er hele historien om 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
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>

For at opsummere, her er hele historien om session 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>

Lad os nu se hvilken transaktion der rent faktisk blev rullet tilbage, og hvilken der blev begået -

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>

Konklusion

Efter min mening er den bedste måde at kende sessionsdetaljerne for et dødvande ved at logge detaljerne så detaljeret som muligt. Ellers er det et mareridt for en DBA at efterforske uden ordentlige oplysninger logget. For den sags skyld ville selv en udvikler synes, at det er en uhyggelig opgave at rette op på og rette den faktiske designfejl, hvis detaljerne om deadlock-fejlen ikke logges detaljeret. Og for at afslutte med en enkelt erklæring:Et dødvande skyldes designfejl, Oracle er kun offeret, og applikationen er synderen. Deadlocks er skræmmende, men de påpeger de designfejl, der skal udbedres før eller siden.



  1. Er det muligt at tvinge rækkeniveaulåsning i SQL Server?

  2. Hvordan får man den næste værdi af SQL Server-sekvens i Entity Framework?

  3. Hvordan kan jeg inkludere null-værdier i en MIN eller MAX?

  4. Grunde til at forvandle Access Apps til webbaserede apps