Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Kebuntuan di Oracle

Saya ingin membuat skrip di mana sesi Oracle yang mengalami kebuntuan dimatikan secara otomatis

EDIT Dijelaskan dengan cara yang lebih baik, mengoreksi beberapa kalimat, dan menambahkan kasus uji untuk menunjukkan skenario kebuntuan.

Mengapa Anda ingin menemukan kembali roda? Oracle mendeteksi kebuntuan secara otomatis, melempar ORA-00060: deadlock detected while waiting for resource , dan memutar kembali salah satu transaksi yang terlibat dalam kebuntuan yang diputuskan Oracle sebagai korban. Transaksi sukses sebelumnya tidak dibatalkan. Bahkan setelah kesalahan kebuntuan, jika komit dikeluarkan, transaksi sukses sebelumnya akan dilakukan. Saat ini, transaksi sesi lain juga akan berhasil dan Anda dapat mengeluarkan komit. Tidak ada yang perlu Anda lakukan secara eksplisit di sini. Kebuntuan otomatis dihapus -- Anda tidak perlu menghapus mereka.

Biasanya, Oracle membutuhkan satu atau dua detik untuk mendeteksi kebuntuan dan melempar kesalahan.

Anda dapat mencoba dengan kasus uji sederhana seperti yang ditunjukkan di sini:Memahami Oracle Deadlock

Mari kita lihat kasus uji -

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

Catat waktu setiap transaksi, saya telah mengatur waktu untuk pemahaman yang lebih baik.

SESI :1

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

1 row updated.

Elapsed: 00:00:00.00

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

Pada titik ini, SESSION 2 terus menunggu .

SESI :1

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

Pada titik ini, SESI 2 adalah korban kebuntuan, SESI 1 masih menunggu.

Mari kita lihat detail sesi dari 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>

Jadi, v$session detail saat dilihat di SESI 2 , yaitu SID 14, menyatakan statusnya AKTIF .

Mari kita lihat detail sesi dari sesi lain, sebut saja SESSION 3 demi. Ingat, SESI 1 masih menunggu.

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>

Jadi, untuk sesi lainnya, SESI 2 , yaitu SID 14, INAKTIF . SESI 1 masih MENUNGGU dengan acara enq: TX - row lock contention .

Mari kita lakukan SESSION 2 -

12:22:18 SQL> commit;

Commit complete.

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

Pada titik ini, kunci dilepaskan untuk SESSION 1 , mari kita komit sesi 1 juga -

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 menunjukkan SESSION 1 menunggu selama itu sampai SESSION 2 dilakukan.

Untuk meringkasnya, inilah keseluruhan cerita sesi 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>

Untuk meringkas, inilah keseluruhan cerita sesi 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>

Sekarang, mari kita lihat transaksi mana yang benar-benar dibatalkan dan mana yang dikomit -

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>

Kesimpulan

Menurut pendapat saya, cara terbaik untuk mengetahui detail sesi dari kebuntuan adalah dengan mencatat detailnya sejelas mungkin. Jika tidak, adalah mimpi buruk bagi DBA untuk menyelidiki tanpa mencatat informasi yang tepat. Dalam hal ini, bahkan Pengembang akan menganggapnya sebagai tugas yang sangat berat untuk memperbaiki dan memperbaiki cacat desain yang sebenarnya jika detail kesalahan kebuntuan tidak dicatat secara verbose. Dan untuk menyimpulkan dengan pernyataan satu baris, Kebuntuan disebabkan oleh cacat desain, Oracle hanyalah korban dan aplikasi menjadi pelakunya. Deadlock memang menakutkan, tetapi menunjukkan kelemahan desain yang harus diperbaiki cepat atau lambat.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kesalahan SQL:ORA-02000:kata kunci SELALU hilang saat membuat tabel berbasis kolom identitas

  2. Rata-rata tanggal di Oracle sql

  3. Cara efisien untuk memperbarui semua baris dalam tabel

  4. Pisahkan nilai yang dipisahkan koma ke kolom di Oracle

  5. Oracle SQL:Perbarui tabel dengan data dari tabel lain