系統觸發器的應用順序(四)

yangtingkun發表於2009-07-05

在寫一個AFTER SUSPEND觸發器的時候碰到了一個很有趣的現象。

透過TRACE檢查問題的原因。

系統觸發器的應用順序(一):http://yangtingkun.itpub.net/post/468/486884

系統觸發器的應用順序(二):http://yangtingkun.itpub.net/post/468/486915

系統觸發器的應用順序(三):http://yangtingkun.itpub.net/post/468/486959

 

 

根據前面文章的測試,可以發現,是由於使用者引發的SUSPEND事件導致一個存在編譯錯誤的觸發器執行,從這個觸發器執行以後,當前會話不在嘗試呼叫觸發器。

下面透過TRACE來比較三種不同的情況:

SQL> DROP TABLE T_TRIGGER;

表已刪除。

SQL> CREATE TABLE T_TRIGGER (INFO VARCHAR2(20));

表已建立。

SQL> CONN / AS SYSDBA
已連線。
SQL> DROP TRIGGER TRI_SUSPEND;

觸發器已刪除。

SQL> CREATE OR REPLACE TRIGGER TRI_SUSPEND
  2  AFTER SUSPEND ON DATABASE
  3  DECLARE
  4   PRAGMA AUTONOMOUS_TRANSACTION;
  5  BEGIN
  6   INSERT INTO YANGTK.T_TRIGGER VALUES ('SYS TRIGGER');
  7   COMMIT;
  8  END;
  9  /

觸發器已建立

SQL> CONN YANGTK/YANGTK
已連線。
SQL> DROP TRIGGER TRI_SUSPEND;

觸發器已刪除。

SQL> CREATE OR REPLACE TRIGGER TRI_SUSPEND
  2  AFTER SUSPEND ON DATABASE
  3  DECLARE
  4   PRAGMA AUTONOMOUS_TRANSACTION;
  5  BEGIN
  6   INSERT INTO T_TRIGGER VALUES ('YANGTK TRIGGER');
  7   COMMIT;
  8  END;
  9  /

觸發器已建立

SQL> ALTER SESSION ENABLE RESUMABLE TIMEOUT 300;

會話已更改。

SQL> ALTER SESSION SET EVENTS '10046 TRACE NAME CONTEXT FOREVER, LEVEL 12';

會話已更改。

SQL> CREATE TABLE T_BIG (ID NUMBER)
  2  TABLESPACE YANGTK
  3  STORAGE (INITIAL 250M);
CREATE TABLE T_BIG (ID NUMBER)
*
1 行出現錯誤:
ORA-30032:
掛起的 (可恢復) 語句已超時
ORA-01659:
無法分配超出 27 MINEXTENTS (在表空間 YANGTK )


SQL> ALTER SESSION SET EVENTS '10046 TRACE NAME CONTEXT OFF';

會話已更改。

首先記錄正常情況下的TRACE資訊,隨後是出錯時的TRACE資訊,為了方便對比結果,這裡重新連線,好得到新的TRACE檔案:

SQL> CONN YANGTK/YANGTK
已連線。
SQL> TRUNCATE TABLE T_TRIGGER;

表被截斷。

SQL> DROP TRIGGER TRI_SUSPEND;

觸發器已刪除。

SQL> CREATE OR REPLACE TRIGGER TRI_SUSPEND
  2  AFTER SUSPEND ON DATABASE
  3  DECLARE
  4   PRAGMA AUTONOMOUS_TRANSACTION;
  5   V_RESULT BOOLEAN;
  6   V_ERROR_TYPE VARCHAR2(32767);
  7   V_OBJECT_TYPE VARCHAR2(32767);
  8   V_OBJECT_OWNER VARCHAR2(30);
  9   V_TABLESPACE_NAME VARCHAR2(30);
 10   V_OBJECT_NAME VARCHAR2(128);
 11   V_SUB_OBJECT_NAME VARCHAR2(128);
 12  BEGIN
 13   V_RESULT := DBMS_RESUMABLE.SPACE_ERROR_INFO(
 14    V_ERROR_TYPE,
 15    V_OBJECT_TYPE,
 16    V_OBJECT_OWNER,
 17    V_TABLESPACE_NAME,
 18    V_OBJECT_NAME,
 19    V_SUB_OBJECT_NAME);
 20   INSERT INTO T_TRIGGER VALUES ('YANGTK TRIGGER');
 21   COMMIT;
 22  END;
 23  /

警告: 建立的觸發器帶有編譯錯誤。

SQL> ALTER SESSION ENABLE RESUMABLE TIMEOUT 300;

會話已更改。

SQL> ALTER SESSION SET EVENTS '10046 TRACE NAME CONTEXT FOREVER, LEVEL 12';

會話已更改。

SQL> CREATE TABLE T_BIG (ID NUMBER)
  2  TABLESPACE YANGTK
  3  STORAGE (INITIAL 250M);
CREATE TABLE T_BIG (ID NUMBER)
*
1 行出現錯誤:
ORA-04098:
觸發器 'YANGTK.TRI_SUSPEND' 無效且未透過重新驗證
ORA-01659:
無法分配超出 27 MINEXTENTS (在表空間 YANGTK )


SQL> ALTER SESSION SET EVENTS '10046 TRACE NAME CONTEXT OFF';

會話已更改。

下面刪掉錯誤的TRIGGER,然後再次生成TRACE,記錄發生錯誤後,Oracle在後臺做了哪些操作:

SQL> DROP TRIGGER TRI_SUSPEND;

觸發器已刪除。

SQL> ALTER SESSION SET EVENTS '10046 TRACE NAME CONTEXT FOREVER, LEVEL 12';

會話已更改。

SQL> CREATE TABLE T_BIG (ID NUMBER)
  2  TABLESPACE YANGTK
  3  STORAGE (INITIAL 250M);
CREATE TABLE T_BIG (ID NUMBER)
*
1 行出現錯誤:
ORA-01659:
無法分配超出 27 MINEXTENTS (在表空間 YANGTK )


SQL> ALTER SESSION SET EVENTS '10046 TRACE NAME CONTEXT OFF';

會話已更改。

對比三次操作生成的TRACE資訊,發現對於最後一次的呼叫,Oracle根本沒有去嘗試讀取任何觸發器相關的資訊。其實,不只是Oracle沒有讀取觸發器的資訊,Oracle實現上根本就沒有進入SUSPEND的狀態,換句話說,如果SUSPEND觸發器失效的時候被呼叫,不是簡單的阻止SUSPEND觸發器再次被呼叫,而是使得當前會話無法在進入SUSPEND狀態。

當前會話採用何種方式都無法在進入SUSPEND狀態,即使關閉RESUMABLE,再重新開啟:

SQL> ALTER SESSION DISABLE RESUMABLE;

會話已更改。

SQL> ALTER SESSION ENABLE RESUMABLE TIMEOUT 300;

會話已更改。

SQL> SELECT * FROM T_TRIGGER;

INFO
--------------------
SYS TRIGGER

SQL> CREATE TABLE T_BIG (ID NUMBER)
  2  TABLESPACE YANGTK
  3  STORAGE (INITIAL 250M);
CREATE TABLE T_BIG (ID NUMBER)
*
1 行出現錯誤:
ORA-01659:
無法分配超出 27 MINEXTENTS (在表空間 YANGTK )


SQL> SELECT * FROM T_TRIGGER;

INFO
--------------------
SYS TRIGGER

由於TRACE檔案太大,且絕大部分內容都與當前問題無關,這裡就不貼出結果了。不過發現一個有趣的現象,第一次操作由於進入了SUSPEND狀態,等待了5分鐘的時間,導致TRACE檔案最大,居然有70多萬行。根據TRACE的內容可以看到,Oracle處於SUSPEND的狀態下,並非只是簡單的等待,而是會不斷的重新檢查當前系統十分有足夠的空間來完全當前處於SUSPEND狀態的操作。

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-608352/,如需轉載,請註明出處,否則將追究法律責任。

相關文章