系統觸發器的應用順序(四)
在寫一個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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 順序表應用5:有序順序表歸併
- 順序表應用6:有序順序表查詢
- 51微控制器程式框架之帶順序的組合按鍵觸發框架
- 雲伺服器修改Linux系統核心的引導順序伺服器Linux
- 聊一下Button事件、命令、行為的觸發順序事件
- RocketMQ系列(四)順序消費MQ
- CentOS 7.0 系統更改核心啟動順序CentOS
- python描述器的訪問順序Python
- Android學習 —— 測試init.rc中的條件觸發的處理順序Android
- 雲伺服器CentOS 6.X 系統更改核心啟動順序伺服器CentOS
- 實驗二:順序表的基本操作實現及其應用
- CSS 選擇器的優先順序CSS
- 測試用例的優先順序
- java基礎(四) java運算順序的深入解析Java
- Windows 應用開發的系統要求Windows
- 開發Android系統應用Android
- 佇列順序性引發的思考佇列
- 聊聊如何讓springboot攔截器的執行順序按我們想要的順序執行Spring Boot
- 【效能測試策略】系統調優由易到難的順序
- ADF 第四篇:管道的執行和觸發器觸發器
- Modbus通訊協議中的四種位元組順序協議
- Vue 基礎篇(四):父子元件的生命週期順序Vue元件
- css 選擇器優先順序CSS
- 感測器,硬體,系統,驅動,應用軟體的發展
- Linux系統常見的日誌檔案及優先順序別!Linux
- [轉]androidstudio更改優先載入系統包framework.jar的順序AndroidFrameworkJAR
- 面向大規模佇列,百萬併發的多優先順序消費系統設計佇列
- python運算子及優先順序順序Python
- 順序表應用3:元素位置互換之移位演算法演算法
- 順序表應用7:最大子段和之分治遞迴法遞迴
- win10系統怎麼調整輸入法順序Win10
- macos_macpath系統路徑檔案載入順序_201216Mac
- 順序表
- Linux排程器:程序優先順序Linux
- 加推時序系統RTS實現原理及應用簡介
- CRM管理系統的應用場景——四大作用解析
- 四折幕投影系統的應用都具備哪些特點?
- 第2章 順序表及其順序儲存
- ERP系統開發 ERP系統詳解及應用