Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Bế tắc trong Oracle

Tôi muốn tạo một tập lệnh trong đó các phiên oracle gặp bế tắc sẽ tự động bị giết

CHỈNH SỬA Được giải thích theo cách tốt hơn, sửa một số câu và thêm một trường hợp thử nghiệm để chứng minh tình huống bế tắc.

Tại sao bạn muốn phát minh lại bánh xe? Oracle tự động phát hiện bế tắc, ném ORA-00060: deadlock detected while waiting for resource , và khôi phục một trong các giao dịch liên quan đến bế tắc mà Oracle đã quyết định là nạn nhân. Các giao dịch thành công trước đó không được quay trở lại. Ngay cả sau khi lỗi deadlock, nếu một cam kết được đưa ra, thì giao dịch thành công trước đó sẽ được cam kết. Tại thời điểm này, giao dịch của phiên khác cũng sẽ thành công và bạn có thể đưa ra cam kết. Không có gì mà bạn cần phải làm ở đây một cách rõ ràng. Các bế tắc tự động được xóa - bạn không bao giờ cần phải xóa họ.

Thông thường, Oracle mất một hoặc hai giây để phát hiện bế tắc và xử lý lỗi.

Bạn có thể thử với một trường hợp thử nghiệm đơn giản như được trình bày ở đây:Hiểu về Oracle Deadlock

Hãy xem xét một trường hợp thử nghiệm -

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

Lưu ý thời gian của mỗi giao dịch, tôi đã đặt thời gian về thời gian để hiểu rõ hơn.

PHẦN:1

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

1 row updated.

Elapsed: 00:00:00.00

PHẦ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;

Tại thời điểm này, PHẦN 2 tiếp tục chờ .

PHẦN:1

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

Tại thời điểm này, PHẦN 2 là nạn nhân của bế tắc, PHẦN 1 vẫn đang chờ đợi.

Hãy xem chi tiết phiên từ PHẦN 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ì vậy, v$session chi tiết khi được xem trong PHẦN 2 , tức là SID 14, cho biết trạng thái là HOẠT ĐỘNG .

Hãy xem chi tiết phiên từ một phiên khác, hãy gọi nó là PHIÊN 3 Vì lợi ích. Hãy nhớ rằng, PHẦN 1 vẫn đang đợi.

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>

Vì vậy, đối với các phiên khác, PHIÊN 2 , tức là SID 14, là KHÔNG TÁC ĐỘNG . PHẦN 1 vẫn đang CHỜ ĐỢI với sự kiện enq: TX - row lock contention .

Hãy cam kết PHẦN 2 -

12:22:18 SQL> commit;

Commit complete.

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

Tại thời điểm này, khóa được phát hành cho PHẦN 1 , hãy cùng cam kết phiên 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 hiển thị PHẦN 1 đã đợi lâu như vậy cho đến PHIÊN BẢN 2 đã được cam kết.

Tóm lại, đây là toàn bộ câu chuyện của phần 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>

Tóm lại, đây là toàn bộ câu chuyện của phầ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>

Bây giờ, hãy xem giao dịch nào thực sự được khôi phục và giao dịch nào đã được cam kết -

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>

Kết luận

Theo tôi, cách tốt nhất để biết chi tiết về phiên bế tắc là ghi lại chi tiết càng dài càng tốt. Mặt khác, thật là một cơn ác mộng đối với một DBA khi điều tra mà không có thông tin thích hợp được ghi lại. Đối với vấn đề đó, ngay cả một Nhà phát triển cũng sẽ thấy đó là một nhiệm vụ cực kỳ nghiêm trọng để khắc phục và sửa lỗi thiết kế thực tế nếu chi tiết lỗi bế tắc không được ghi lại một cách chi tiết. Và để kết thúc với một tuyên bố lót, Một bế tắc là do lỗi thiết kế, Oracle chỉ là nạn nhân và ứng dụng là thủ phạm. Bế tắc thật đáng sợ, nhưng chúng chỉ ra những sai sót trong thiết kế sớm hay muộn cũng phải được khắc phục.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Công cụ để làm việc với các thủ tục được lưu trữ trong Oracle, trong một nhóm?

  2. [01000] [unixODBC] [Trình quản lý trình điều khiển] Không thể mở lib '/usr/local/easysoft/oracle/InstantClient112/lib/libsqora.so':không tìm thấy tệp

  3. Có một pragma PL / SQL tương tự như DETERMINISTIC, nhưng cho phạm vi của một SQL SELECT duy nhất không?

  4. Phương pháp thu thập:Thủ tục EXTEND trong Cơ sở dữ liệu Oracle

  5. Làm cách nào để bạn chuyển một đối số tới một khối PL / SQL trong một tệp sql được gọi là sử dụng START trong sqlplus?