SMON的作用還包括清理obj$資料字典基表(cleanup obj$)
OBJ$字典基表是Oracle Bootstarp啟動自舉的重要對象之一:
觸發場景
OBJ$基表是一張低級資料字典表,該表幾乎對庫中的每個對象(表、索引、包、視圖等)都包含有一行記錄。很多情況下,這些條目所代表的對象是不存在的對象(non-existent),引起這種現象的一種可能的原因是對象本身已經被從資料庫中删除了,但是對象條目仍被保留下來以滿足消極依賴機制(negative dependency)。因為這些條目的存在會導緻OBJ$表不斷膨脹,這時就需要由SMON程序來删除這些不再需要的行。
SMON會在執行個體啟動(after startup of DB is started cleanup function again)時以及啟動後的每12個小時執行一次清理任務(the cleanup is scheduled to run after startup and then every 12 hours)。
我們可以通過以下示範來了解SMON清理obj$的過程:
現象
我們可以通過以下查詢來了解obj$基表中NON-EXISTENT對象的條目總數(type#=10),若這個總數在不斷減少說明smon正在執行清理工作

如何禁止SMON清理obj$基表:
我們可以通過設定診斷事件event=’10052 trace name context forever’來禁止SMON清理obj$基表,當我們需要避免SMON因cleanup obj$的相關代碼而意外終止或spin進而開展進一步的診斷時可以設定該診斷事件。在Oracle并行伺服器或RAC環境中,也可以設定該事件來保證隻有特定的某個節點來執行清理工作。
SMON的作用還包括維護col_usage$列監控統計資訊基表。
最早在9i中引入了col_usage$字典基表,其目的在于監控column在SQL語句作為predicate的情況,col_usage$的出現完善了CBO中柱狀圖自動收集的機制。
AUTO’意為由Oracle自動決定是否收集柱狀圖及柱狀圖的桶數,Oracle自行判斷的依據就來源于col_usage$字典基表,若表上的某一列曾在硬解析(hard parse)過的SQL語句中充當過predicate(謂語,通俗的說就是where後的condition(條件))的話,我們認為此列上有收集柱狀圖的必要,那麼col_usage$上就會被加入該列曾充當predicate的記錄。當DBMS_STATS.GATHER_TABLE_STATS存儲過程以’SIZE
AUTO’模式執行時,收集程序會檢查col_usage$基表以判斷哪些列之前曾充當過predicate,若充當過則說明該列有收集柱狀圖的價值。
SMON會每15分鐘将shared pool中的predicate columns的資料重新整理到col_usage$基表中(until periodically about every 15 minutes SMON flush the data into the data dictionary),另外當instance
shutdown時SMON會掃描col_usage$并找出已被drop表的相關predicate columns記錄,并删除這部分”orphaned”孤兒記錄。
我們來具體了解col_usage$的填充過程:
使用dbms_stats的’SIZE AUTO’模式收集表上的統計資訊會首先參考col_usage$中的predicate columns記錄:
根據Metalink Note<Database Shutdown Immediate Takes Forever, Can Only Do Shutdown Abort [ID 332177.1]>:
該文檔指出了在shutdown instance時SMON會着手清理col_usage$中已被drop表的相關predicate columns的”orphaned”(孤兒)記錄,如果在本次執行個體的生命周期中曾生成大量最後被drop的中間表,那麼col_usage$中已經堆積了衆多的”orphaned”記錄,SMON為了完成cleanup工作需要花費大量時間導緻shutdown變慢。這個文檔還指出定期執行DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO也可以清理col_usage$中的備援記錄。
我們來觀察一下SMON的清理工作:
如何禁止SMON維護col_usage$字典基表
1.設定隐藏參數_column_tracking_level(column usage tracking),該參數預設為1即啟用column使用情況跟蹤。設定該參數為0,将禁用column tracking,該參數可以在session和system級别動态修改:
2.關閉DML monitoring,可以通過設定隐藏參數_dml_monitoring_enabled(enable modification monitoring)為false實作,disable dml monitoring對CBO的影響較大,是以我們一般推薦上一種方式: