SMON功能(一):清理臨時段
溫故而知新 SMON功能(一)
SMON(system monitor process)系統監控后臺進程,有時候也被叫做system cleanup process,這么叫的原因是它負責完成很多清理(cleanup)任務。但凡學習過Oracle基礎知識的技術人員都會或多或少對該background process的功能有所了解。
曾幾何時對SMON功能的了解程度可以作為評判一位DBA理論知識的重要因素,至今仍有很多公司在DBA面試中會問到SMON有哪些功能這樣的問題。首先這是一道開放式的題目,并不會奢求面試者能夠答全(答全幾乎是不可能的,即便是在你閱讀本篇文章之后),答出多少可以作為知識廣度的評判依據(如果面試人特意為這題準備過,那么也很好,說明他已經能系統地考慮問題了),接著還可以就具體的某一個功能說開去,來了解面試者的知識深度,當然這扯遠了。
我們所熟知的SMON是個兢兢業業的家伙,它負責完成一些列系統級別的任務。與PMON(Process Monitor)后臺進程不同的是,SMON負責完成更多和整體系統相關的工作,這導致它會去做一些不知名的”累活”,當系統頻繁產生這些”垃圾任務”,則SMON可能忙不過來。因此在10g中SMON變得有一點懶惰了,如果它在短期內接收到過多的工作通知(SMON: system monitor process posted),那么它可能選擇消極怠工以便讓自己不要過于繁忙(SMON: Posted too frequently, trans recovery disabled),之后會詳細介紹。
SMON的主要作用包括:
1.清理臨時段(SMON cleanup temporary segments)
觸發場景
很多人錯誤地理解了這里所說的臨時段temporary segments,認為temporary segments是指temporary tablespace臨時表空間上的排序臨時段(sort segment)。事實上這里的臨時段主要指的是永久表空間(permanent tablespace)上的臨時段,當然臨時表空間上的temporary segments也是由SMON來清理(cleanup)的,但這種清理僅發生在數據庫實例啟動時(instance startup)。
永久表空間上同樣存在臨時段,譬如當我們在某個永久表空間上使用create table/index等DDL命令創建某個表/索引時,服務進程一開始會在指定的永久表空間上分配足夠多的區間(Extents),這些區間在命令結束之前都是臨時的(Temporary Extents),直到表/索引完全建成才將該temporary segment轉換為permanent segment。另外當使用drop命令刪除某個段時,也會先將該段率先轉換為temporary segment,之后再來清理該temporary segment(DROP object converts the segment to temporary and then cleans up the temporary segment)。 常規情況下清理工作遵循誰創建temporary segment,誰負責清理的原則。換句話說,因服務進程rebuild index所產生的temporary segment在rebuild完成后應由服務進程自行負責清理。一旦服務進程在成功清理temporary segment之前就意外終止了,亦或者服務進程在工作過程中遇到了某些ORA-錯誤導致語句失敗,那么SMON都會被要求(posted)負責完成temporary segment的清理工作。
對于永久表空間上的temporary segment,SMON會三分鐘清理一次(前提是接到post),如果SMON過于繁忙那么可能temporary segment長期不被清理。temporary segment長期不被清理可能造成一個典型的問題是:在rebuild index online失敗后,后續執行的rebuild index命令要求之前產生的temporary segment已被cleanup,如果cleanup沒有完成那么就需要一直等下去。在10gR2中我們可以使用dbms_repair.online_index_clean來手動清理online index rebuild的遺留問題:
The dbms_repair.online_index_clean function has been created to cleanup online index rebuilds. Use the dbms_repair.online_index_clean function to resolve the issue. Please note if you are unable to run the dbms_repair.online_index_clean function it is due to the fact that you have not installed the patch for Bug 3805539 or are not running on a release that includes this fix. The fix for this bug is a new function in the dbms_repair package called dbms_repair.online_index_clean, which has been created to cleanup online index [[sub]partition] [re]builds. New functionality is not allowed in patchsets; therefore, this is not available in a patchset but is available in 10gR2. Check your patch list to verify the database is patched for Bug 3805539 using the following command and patch for the bug if it is not listed: opatch lsinventory -detail Cleanup after a failed online index [re]build can be slow to occurpreventing subsequent such operations until the cleanup has occured.
接著我們通過實踐來看一下smon是如何清理永久表空間上的temporary segment的:
設置10500事件以跟蹤smon進程,這個診斷事件后面會介紹 SQL> alter system set events '10500 trace name context forever,level 10'; System altered. 在第一個會話中執行create table命令,這將產生一定量的Temorary Extents SQL> create table smon as select * from ymon; 在另一個會話中執行對DBA_EXTENTS視圖的查詢,可以發現產生了多少臨時區間 SQL> SELECT COUNT(*) FROM DBA_EXTENTS WHERE SEGMENT_TYPE='TEMPORARY'; COUNT(*) ---------- 117 終止以上create table的session,等待一段時間后觀察smon后臺進程的trc可以發現以下信息: *** 2011-06-07 21:18:39.817 SMON: system monitor process posted msgflag:0x0200 (-/-/-/-/TMPSDROP/-/-) *** 2011-06-07 21:18:39.818 SMON: Posted, but not for trans recovery, so skip it. *** 2011-06-07 21:18:39.818 SMON: clean up temp segments in slave SQL> SELECT COUNT(*) FROM DBA_EXTENTS WHERE SEGMENT_TYPE='TEMPORARY'; COUNT(*) ---------- 0 可以看到smon通過slave進程完成了對temporary segment的清理
與永久表空間上的臨時段不同,出于性能的考慮臨時表空間上的Extents并不在操作(operations)完成后立即被釋放和歸還。相反,這些Temporary Extents會被標記為可用,以便用于下一次的排序操作。SMON仍會清理這些Temporary segments,但這種清理僅發生在實例啟動時(instance startup):
For performance issues, extents in TEMPORARY tablespaces are not released ordeallocated once the operation is complete.Instead, the extent is simply marked as available for the next sort operation. SMON cleans up the segments at startup. A sort segment is created by the first statement that used a TEMPORARY tablespacefor sorting, after startup. A sort segment created in a TEMPOARY tablespace is only released at shutdown. The large number of EXTENTS is caused when the STORAGE clause has been incorrectly calculated
現象
可以通過以下查詢了解數據庫中Temporary Extent的總數,在一定時間內比較其總數,若有所減少那么說明SMON正在清理Temporary segment
SELECT COUNT(*) FROM DBA_EXTENTS WHERE SEGMENT_TYPE='TEMPORARY';
也可以通過v$sysstat視圖中的”SMON posted for dropping temp segment”事件統計信息來了解SMON收到清理要求的情況:
SQL> select name,value from v$sysstat where name like '%SMON%'; NAME VALUE ---------------------------------------------------------------- ---------- total number of times SMON posted 8 SMON posted for undo segment recovery 0 SMON posted for txn recovery for other instances 0 SMON posted for instance recovery 0 SMON posted for undo segment shrink 0 SMON posted for dropping temp segment 1
另外在清理過程中SMON會長期持有Space Transacton(ST)隊列鎖,其他會話可能因為得不到ST鎖而等待超時出現ORA-01575錯誤:
警告日志: 01575, 00000, "timeout waiting for space management resource" // *Cause: failed to acquire necessary resource to do space management. // *Action: Retry the operation.
如何禁止SMON清理臨時段
可以通過設置診斷事件event=’10061 trace name context forever, level 10′禁用SMON清理臨時段(disable SMON from cleaning temp segments)。
alter system set events '10061 trace name context forever, level 10';
相關診斷事件
除去10061事件外還可以用10500事件來跟蹤smon的post信息,具體的事件設置方法見EVENT: 10500 "turn on traces for SMON"
Error: ORA 10500 Text: turn on traces for SMON ------------------------------------------------------------------------------- Cause: Action: Level: <=5 trace instance recovery > 5 trace posting of SMON To set event 10500: For the instance: a. Shutdown database b. Edit the initialisation parameter file and add: event="10500 trace name context forever, level <value>" c. restart the database For the SMON session: Post the SMON process using oradbx (Oracle 7) or oradebug (Oracle 8). For oradebug from server manager issue: oradebug setospid <OS PID> oradebug event 10500 trace name context forever, level <value> For further information about oradebug Note 29786.1 oradbx Note 28863.1 <value> is 'Level' as per above
轉自大劉的blog
http://www.oracledatabase12g.com/archives/smon-cleanup-temporary-segment.html

浙公網安備 33010602011771號