了解你所不知道的SMON功能(七):清理IND$字典基表
SMON的作用還包括清理IND$字典基表(cleanup ind$):
觸發場景
當我們在線創建或重建索引時(create or rebuild index online),服務進程會到IND$字典基表中將該索引對應的記錄的FLAGS字段修改為十進制的256或者512(見上圖0×100=256,0×200=512),如:
SQL> create index macleans_index on larges(owner,object_name) online; SQL> select obj# from obj$ where name='MACLEANS_INDEX'; OBJ# ---------- 1343842 SQL> select FLAGS from ind$ where obj#=1343842; FLAGS ---------- 256 ind_online$字典基表記錄了索引在線創建/重建的歷史 SQL> select * from ind_online$; OBJ# TYPE# FLAGS ---------- ---------- ---------- 1343839 1 256 1343842 1 256 create table ind_online$ ( obj# number not null, type# number not null, /* what kind of index is this? */ /* normal : 1 */ /* bitmap : 2 */ /* cluster : 3 */ /* iot - top : 4 */ /* iot - nested : 5 */ /* secondary : 6 */ /* ansi : 7 */ /* lob : 8 */ /* cooperative index method : 9 */ flags number not null /* index is being online built : 0x100 */ /* index is being online rebuilt : 0x200 */ )
原則上online create/rebuild index的的清理工作由實際操作的服務進程負責完成,這種清理在DDL語句成功的情況下包括一系列數據字典的維護,在該DDL語句失敗的情形中包括 對臨時段的清理 和數據字典的維護,無論如何都需要drop在線日志中間表 SYS_JOURNAL_nnnnn(nnnn為該索引的obj#) 。數據字典的維護工作就包含對IND$基表中相應索引記錄的FLAGS標志位的恢復,但是如果服務進程在語句執行過程中意外終止的話,那么短時間內FLAGS標志位字段就無法得到恢復,這將導致對該索引的后續操作因ORA-8104錯誤而無法繼續:
SQL> drop index macleans_index; drop index macleans_index * ERROR at line 1: ORA-08104: this index object 1343842 is being online built or rebuilt 08104, 00000, "this index object %s is being online built or rebuilt" // *Cause: the index is being created or rebuild or waited for recovering // from the online (re)build // *Action: wait the online index build or recovery to complete
SMON負責在啟動后(startup)的每小時執行一次對IND$基表中因在線創建/重建索引失敗所留下記錄的清理,這種清理工作由kdicclean函數驅動(kdicclean is run by smon every 1 hour,called from SMON to find if there is any online builder death and cleanup our ind$ and obj$ and drop the journal table, stop journaling)。
這種清理工作典型的調用堆棧stack call如下:
ksbrdp -> ktmSmonMain ktmmon -> kdicclean -> kdic_cleanup -> ktssdrp_segment
注意因為SMON進程的清理工作每小時才執行一次,而且在工作負載很高的情況下可能實際很久都不會得到清理,在這種情景中我們總是希望能盡快完成對索引的在線創建或重建,在10gr2以后的版本中我們可以直接使用dbms_repair.online_index_clean來手動清理online index rebuild的遺留問題:
SQL> drop index macleans_index; drop index macleans_index * ERROR at line 1: ORA-08104: this index object 1343842 is being online built or rebuilt DECLARE isClean BOOLEAN; BEGIN isClean := FALSE; WHILE isClean=FALSE LOOP isClean := dbms_repair.online_index_clean( dbms_repair.all_index_id, dbms_repair.lock_wait); dbms_lock.sleep(10); END LOOP; END; / SQL> drop index macleans_index; drop index macleans_index * ERROR at line 1: ORA-01418: specified index does not exist 成功清理
但是如果在9i中的話就比較麻煩,可以嘗試用以下方法(不是很推薦,除非你已經等了很久):
1.首先手工刪除在線日志表,通過以下手段找出這個中間表的名字 select object_name from dba_objects where object_name like (select '%' || object_id || '%' from dba_objects where object_name = '&INDEX_NAME') / Enter value for index_name: MACLEANS_INDEX old 6: where object_name = '&INDEX_NAME') new 6: where object_name = 'MACLEANS_INDEX') OBJECT_NAME -------------------------------------------------------------------------------- SYS_JOURNAL_1343845 SQL> drop table SYS_JOURNAL_1343845; Table dropped. 2.第二步要手動修改IND$字典基表 !!!!!! 注意!手動修改數據字典要足夠小心!! select flags from ind$ where obj#=&INDEX_OBJECT_ID; Enter value for index_object_id: 1343845 old 1: select flags from ind$ where obj#=&INDEX_OBJECT_ID new 1: select flags from ind$ where obj#=1343845 FLAGS ---------- 256 a) 針對online create index,手動刪除對應的記錄 delete from IND$ where obj#=&INDEX_OBJECT_ID b) 針對online rebuild index,手動恢復對應記錄的FLAGS標志位 update IND$ set FLAGS=FLAGS-512 where obj#=&INDEX_OBJECT_ID
接下來我們實際觀察一下清理工作的細節:
SQL> select obj# from obj$ where name='MACLEANS_INDEX'; OBJ# ---------- 1343854 SQL> select FLAGS from ind$ where obj#=1343854; FLAGS ---------- 256 SQL> oradebug setmypid; Statement processed. SQL> oradebug event 10046 trace name context forever,level 8; Statement processed. SQL> DECLARE 2 isClean BOOLEAN; 3 BEGIN 4 isClean := FALSE; 5 WHILE isClean=FALSE 6 LOOP 7 isClean := dbms_repair.online_index_clean( 8 dbms_repair.all_index_id, dbms_repair.lock_wait); 9 10 dbms_lock.sleep(10); 11 END LOOP; 12 END; 13 / PL/SQL procedure successfully completed. ===============================10046 trace============================= select i.obj#, i.flags, u.name, o.name, o.type# from sys.obj$ o, sys.user$ u, sys.ind_online$ i where (bitand(i.flags, 256) = 256 or bitand(i.flags, 512) = 512) and (not ((i.type# = 9) and bitand(i.flags, 8) = 8)) and o.obj# = i.obj# and o.owner# = u.user# select u.name, o.name, o.namespace, o.type#, decode(bitand(i.property, 1024), 0, 0, 1) from ind$ i, obj$ o, user$ u where i.obj# = :1 and o.obj# = i.bo# and o.owner# = u.user# delete from object_usage where obj# in (select a.obj# from object_usage a, ind$ b where a.obj# = b.obj# and b.bo# = :1) drop table "SYS"."SYS_JOURNAL_1343854" purge delete from icoldep$ where obj# in (select obj# from ind$ where bo#=:1) delete from ind$ where bo#=:1 delete from ind$ where obj#=:1
我們可以利用以下語句找出系統中可能需要恢復的IND$記錄,注意不要看到查詢有結果就認為這是操作失敗的征兆,很可能是有人在線創建或重建索引:
select i.obj#, i.flags, u.name, o.name, o.type# from sys.obj$ o, sys.user$ u, sys.ind_online$ i where (bitand(i.flags, 256) = 256 or bitand(i.flags, 512) = 512) and (not ((i.type# = 9) and bitand(i.flags, 8) = 8)) and o.obj# = i.obj# and o.owner# = u.user# /
相關診斷事件
可以通過設置診斷事件event=’8105 trace name context forever’
來禁止SMON清理IND$(Oracle event to turn off smon cleanup for online index build)
alter system set events '8105 trace name context forever';
了解你所不知道的SMON功能(八):Transaction Recover
SMON的作用還包括啟動(startup)時的Transaction Recover:
SMON: enabling cache recovery Archived Log entry 87 added for thread 1 sequence 58 ID 0xa044e7d dest 1: [15190] Successfully onlined Undo Tablespace 2. Undo initialization finished serial:0 start:421305354 end:421305534 diff:180 (1 seconds) Verifying file header compatibility for 11g tablespace encryption.. Verifying 11g file header compatibility for tablespace encryption completed SMON: enabling tx recovery
在 <了解你所不知道的SMON功能(五):Recover Dead transaction> 中我們介紹了SMON清理死事務的功能,數據庫打開時由SMON所啟動的TX recovery與Recover Dead transaction所作的工作是類似的,fast_start_parallel_rollback參數決定了SMON在回滾事務時使用的并行度(詳見原帖)。
但是請注意,實際startup時的TX recovery要比普通的Dead transaction recover復雜的多。其大致步驟如下:
1.在SYSTEM回滾段(Undo Segment Number為o)中的Active Transaction將被第一時間優先回滾
2.在其他回滾段中的Active Transaction將被標記為’DEAD’
3.之后SMON將掃描非SYSTEM的回滾段并實施對死事務的回滾,其典型的調用堆棧stack call如下:
kturec <- kturax <- ktprbeg <- ktmmon <- ktmSmonMain4.SMON仍將掃描_OFFLINE_ROLLBACK_SEGMENTS所列出的回滾段,但對其上的Active Transaction不做回滾,若發現corrupted則只報錯
5.SMON將忽略_CORRUPTED_ROLLBACK_SEGMENTS所列出的回滾段,甚至在啟動時不做掃描,所有指向這類回滾段地事務都被認為已經提交了。
具體SMON在對ktuini的函數調用中啟動Transaction Recover,該function的經典stack call如下:
adbdrv -> ktuini -> ktuiup -> kturec -> kturrt or adbdrv -> ktuini -> ktuiof -> ktunti -> kqrpre -> kqrpre1 -> ktuscr其中由ktuiof函數判斷_OFFLINE_ROLLBACK_SEGMENTS和_CORRUPTED_ROLLBACK_SEGMENTS的值,并將這些重要的回滾段信息轉存到fixed array。
注意SYSTEM回滾段是bootstrap的重要對象,所以我們不能指定system rollback segment為offline或者corrupted。SMON執行Transaction Recover時的大致步驟如下:
調用ktuiof保存_OFFLINE_ROLLBACK_SEGMENTS和_CORRUPTED_ROLLBACK_SEGMENTS所列出的回滾段
調用ktuiup函數,開始恢復回滾段上的死事務
第一優先級地恢復USN=0的SYSTEM回滾段上的事務,由kturec函數控制
對undo$字典基表上的記錄循環:
FOR usn in undo$ loop
IF usn==0恢復SYSTEM回滾段上在第一輪中未完成的事務,同樣由kturec控制;
ELSE
將任何活動事務標記為DEAD,由kturec控制;
USN++
end loop
相關診斷事件
與Transaction Recover密切相關的診斷事件有不少,其中最為重要的是event 10013和10015;10015事件對于普通的dead transaction rollback也有效,之所以把該事件列在<Transaction Recover>功能內,是因為我們經常在非正常手段打開數據庫時會遇到一些ORA-600[4xxx]的內部錯誤,可以通過10015事件了解相關的usn,然后以_SYSSMU(USN#)$的形式加入到_CORRUPTED_ROLLBACK_SEGMENTS以繞過內部錯誤(注意在11g中不能這樣做了):
Event 10013:Monitor transaction recovery during startup SQL> alter system set event='10013 trace name context forever,level 10' scope=spfile; Event 10015:Dump undo segment headers before and after transaction recovery SQL> alter system set event='10015 trace name context forever,level 10' scope=spfile; System altered. ======================10015 sample trace=========================== UNDO SEG (BEFORE RECOVERY): usn = 0 Extent Control Header ----------------------------------------------------------------- Extent Header:: spare1: 0 spare2: 0 #extents: 6 #blocks: 47 last map 0x00000000 #maps: 0 offset: 4128 Highwater:: 0x0040000b ext#: 0 blk#: 1 ext size: 7 #blocks in seg. hdr's freelists: 0 #blocks below: 0 mapblk 0x00000000 offset: 0 Unlocked Map Header:: next 0x00000000 #extents: 6 obj#: 0 flag: 0x40000000 Extent Map ----------------------------------------------------------------- 0x0040000a length: 7 0x00400011 length: 8 0x00400181 length: 8 0x00400189 length: 8 0x00400191 length: 8 0x00400199 length: 8 TRN CTL:: seq: 0x012c chd: 0x0033 ctl: 0x0026 inc: 0x00000000 nfb: 0x0001 mgc: 0x8002 xts: 0x0068 flg: 0x0001 opt: 2147483646 (0x7ffffffe) uba: 0x0040000b.012c.1b scn: 0x0000.021fa595 Version: 0x01 FREE BLOCK POOL:: uba: 0x0040000b.012c.1b ext: 0x0 spc: 0x4a0 uba: 0x00000000.005c.07 ext: 0x2 spc: 0x1adc uba: 0x00000000.0034.37 ext: 0x4 spc: 0x550 uba: 0x00000000.0000.00 ext: 0x0 spc: 0x0 uba: 0x00000000.0000.00 ext: 0x0 spc: 0x0 TRN TBL:: index state cflags wrap# uel scn dba parent-xid nub stmt_num ------------------------------------------------------------------------------------------------ 0x00 9 0x00 0x025d 0x002b 0x0000.02215c0b 0x0040000b 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x01 9 0x00 0x025d 0x0006 0x0000.0220a58c 0x0040000a 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x02 9 0x00 0x025d 0x000e 0x0000.0220a58a 0x0040000a 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x03 9 0x00 0x025d 0x000f 0x0000.02215be4 0x0040000b 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x04 9 0x00 0x025d 0x0008 0x0000.0220a57a 0x0040000a 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x05 9 0x00 0x025d 0x0056 0x0000.0220a583 0x0040000a 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x06 9 0x00 0x025d 0x0017 0x0000.0220a58d 0x0040000a 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x07 9 0x00 0x025d 0x0050 0x0000.0220a57f 0x0040000a 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x08 9 0x00 0x025d 0x0061 0x0000.0220a57c 0x0040000a 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x09 9 0x00 0x025d 0x0013 0x0000.02215c01 0x0040000b 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x0a 9 0x00 0x025d 0x0022 0x0000.02215bf7 0x0040000b 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x0b 9 0x00 0x025d 0x0014 0x0000.02215bdd 0x0040000a 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x0c 9 0x00 0x025c 0x003a 0x0000.021ff3fa 0x004001a0 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x0d 9 0x00 0x025d 0x0010 0x0000.02215c05 0x0040000b 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x0e 9 0x00 0x025d 0x0001 0x0000.0220a58b 0x0040000a 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x0f 9 0x00 0x025d 0x001c 0x0000.02215be6 0x0040000b 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x10 9 0x00 0x025d 0x002a 0x0000.02215c07 0x0040000b 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x11 9 0x00 0x025d 0x0025 0x0000.02215bf2 0x0040000b 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x12 9 0x00 0x025d 0x0018 0x0000.02215bee 0x0040000b 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x13 9 0x00 0x025d 0x000d 0x0000.02215c03 0x0040000b 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x14 9 0x00 0x025d 0x005a 0x0000.02215bdf 0x0040000a 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x15 9 0x00 0x025d 0x0058 0x0000.0220a587 0x0040000a 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x16 9 0x00 0x025d 0x000a 0x0000.02215bf6 0x0040000b 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x17 9 0x00 0x025d 0x000b 0x0000.0220a58e 0x0040000a 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x18 9 0x00 0x025d 0x0011 0x0000.02215bf0 0x0040000b 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x19 9 0x00 0x025c 0x0044 0x0000.021ff410 0x004001a0 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x1a 9 0x00 0x025d 0x005c 0x0000.02215bea 0x0040000b 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x1b 9 0x00 0x025d 0x001d 0x0000.02215bfd 0x0040000b 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x1c 9 0x00 0x025d 0x001a 0x0000.02215be8 0x0040000b 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x1d 9 0x00 0x025d 0x0009 0x0000.02215bff 0x0040000b 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x1e 9 0x00 0x025d 0x005f 0x0000.02215bfa 0x0040000b 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x1f 9 0x00 0x025c 0x0032 0x0000.021fa59b 0x0040019f 0x0000.000.00000000 0x00000001 0x00000000 0x0000 0x20 9 0x00 0x025c 0x0038 0x0000.021fa599 0x0040019f 0x0000.000.00000000 0x00000001 0x00000000 0x0000 可用以下命令分析smon的10015 trace,并列出相關回滾段名 [oracle@rh2 bdump]$ cat g10r2_smon_18738.trc|grep "usn ="|grep -v "usn = 0" |awk '{print "_SYSSMU"$7"$"}'|sort -u _SYSSMU1$ _SYSSMU10$ _SYSSMU2$ _SYSSMU3$ _SYSSMU4$ _SYSSMU5$ _SYSSMU6$ _SYSSMU7$ _SYSSMU8$ _SYSSMU9$了解你所不知道的SMON功能(九):維護MON_MODS$字典基表
SMON后臺進程的作用還包括維護MON_MODS$基表,當初始化參數STATISTICS_LEVEL被設置為TYPICAL或ALL時默認會啟用Oracle中表監控的特性,Oracle會默認監控表上的自上一次分析以后(Last analyzed)發生的INSERT,UPDATE,DELETE以及表是否被TRUNCATE截斷,并將這些操作數量的近似值記錄到數據字典基表MON_MODS$中,我們常用的一個DML視圖dba_tab_modifications的數據實際來源于另一個數據字典基表MON_MODS_ALL$,SMON定期會將MON_MODS$中符合要求的數據MERGE到MON_MODS_ALL$中。
Rem DML monitoring create table mon_mods$ ( obj# number, /* object number */ inserts number, /* approx. number of inserts since last analyze */ updates number, /* approx. number of updates since last analyze */ deletes number, /* approx. number of deletes since last analyze */ timestamp date, /* timestamp of last time this row was changed */ flags number, /* flags */ /* 0x01 object has been truncated */ drop_segments number /* number of segemnt in part/subpartition table */ ) storage (initial 200K next 100k maxextents unlimited pctincrease 0) / create unique index i_mon_mods$_obj on mon_mods$(obj#) storage (maxextents unlimited) / Rem DML monitoring, has info aggregated to global level for paritioned objects create table mon_mods_all$ ( obj# number, /* object number */ inserts number, /* approx. number of inserts since last analyze */ updates number, /* approx. number of updates since last analyze */ deletes number, /* approx. number of deletes since last analyze */ timestamp date, /* timestamp of last time this row was changed */ flags number, /* flags */ /* 0x01 object has been truncated */ drop_segments number /* number of segemnt in part/subpartition table */ ) storage (initial 200K next 100k maxextents unlimited pctincrease 0) / create unique index i_mon_mods_all$_obj on mon_mods_all$(obj#) storage (maxextents unlimited) / Rem ========================================================================= Rem End Usage monitoring tables Rem ========================================================================= VIEW DBA_TAB_MODIFICATIONS select u.name, o.name, null, null, m.inserts, m.updates, m.deletes, m.timestamp, decode(bitand(m.flags,1),1,'YES','NO'), m.drop_segments from sys.mon_mods_all$ m, sys.obj$ o, sys.tab$ t, sys.user$ u where o.obj# = m.obj# and o.obj# = t.obj# and o.owner# = u.user# union all select u.name, o.name, o.subname, null, m.inserts, m.updates, m.deletes, m.timestamp, decode(bitand(m.flags,1),1,'YES','NO'), m.drop_segments from sys.mon_mods_all$ m, sys.obj$ o, sys.user$ u where o.owner# = u.user# and o.obj# = m.obj# and o.type#=19 union all select u.name, o.name, o2.subname, o.subname, m.inserts, m.updates, m.deletes, m.timestamp, decode(bitand(m.flags,1),1,'YES','NO'), m.drop_segments from sys.mon_mods_all$ m, sys.obj$ o, sys.tabsubpart$ tsp, sys.obj$ o2, sys.user$ u where o.obj# = m.obj# and o.owner# = u.user# and o.obj# = tsp.obj# and o2.obj# = tsp.pobj#現象:
SMON后臺進程會每15分鐘將SGA中的DML統計信息刷新到SYS.MON_MODS$基表中(SMON flush every 15 minutes to SYS.MON_MODS$),
同時會將SYS.MON_MODS$中符合要求的數據MERGE合并到MON_MODS_ALL$中,并清空原MON_MODS$中的數據。
MON_MODS_ALL$作為dba_tab_modifications視圖的數據來源,起到輔助統計信息收集的作用,詳見拙作 <Does GATHER_STATS_JOB gather all objects’ stats every time?> 。SMON具體將DML統計數據刷新到SYS.MON_MODS$、合并到MON_MODS_ALL$、并清除數據的操作如下:
SQL> select * from v$version; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production PL/SQL Release 11.2.0.2.0 - Production CORE 11.2.0.2.0 Production TNS for Linux: Version 11.2.0.2.0 - Production NLSRTL Version 11.2.0.2.0 - Production SQL> select * from global_name; GLOBAL_NAME -------------------------------------------------------------------------------- www.oracledatabase12g.com /* 填充mon_mods$字典基表 */ lock table sys.mon_mods$ in exclusive mode nowait insert into sys.mon_mods$ (obj#, inserts, updates, deletes, timestamp, flags, drop_segments) values (:1, :2, :3, :4, :5, :6, :7) update sys.mon_mods$ set inserts = inserts + :ins, updates = updates + :upd, deletes = deletes + :del, flags = (decode(bitand(flags, :flag), :flag, flags, flags + :flag)), drop_segments = drop_segments + :dropseg, timestamp = :time where obj# = :objn lock table sys.mon_mods_all$ in exclusive mode /* 以下merge命令會將mon_mods$中的記錄合并到mon_mods_all$, 若有匹配的記錄,則在原記錄的基礎上增加inserts、updates、deletes總數, 否則插入新的記錄 */ merge /*+ dynamic_sampling(mm 4) dynamic_sampling_est_cdn(mm) dynamic_sampling(m 4) dynamic_sampling_est_cdn(m) */ into sys.mon_mods_all$ mm using (select m.obj# obj#, m.inserts inserts, m.updates updates, m.deletes deletes, m.flags flags, m.timestamp timestamp, m.drop_segments drop_segments fr om sys.mon_mods$ m, tab$ t where m.obj# = t.obj#) v on (mm.ob j# = v.obj#) when matched then update set mm.inserts = mm.inserts + v.inserts, mm.updates = mm.updates + v.updates, mm.deletes = mm.deletes + v.deletes, mm.flags = mm.flags + v.flags - bitand(mm.flags, v.flags) /* bitor(mm.flags,v.flags) */, mm.timestamp = v.timestamp, mm.drop_segments = mm.drop_segments + v.drop_segments when NOT matched then insert (obj#, inserts, updates, deletes, timestamp, flags, drop_segments) values (v.obj#, v.inserts, v.updates, v.deletes, sysdate, v.flags, v.drop_segments) / all merge /*+ dynamic_sampling(mm 4) dynamic_sampling_est_cdn(mm) dynamic_sampling(m 4) dynamic_sampling_est_cdn(m) */ into sys.mon_mods_all$ mm using (select m.obj# obj#, m.inserts inserts, m.updates updates, m.deletes deletes, m.flags flags, m.timestamp timestamp, m.drop_segments drop_segments fr om sys.mon_mods$ m, tab$ t where m.obj# = t.obj#) v on (mm.ob j# = v.obj#) when matched then update set mm.inserts = mm.inserts + v.inserts, mm.updates = mm.updates + v.updates, mm.deletes = mm.deletes + v.deletes, mm.flags = mm.flags + v.flags - bitand(mm.flags, v.flags) /* bitor(mm.flags,v.flags) */, mm.timestamp = v.timestamp, mm.drop_segments = mm.drop_segments + v.drop_segments when NOT matched then insert (obj#, inserts, updates, deletes, timestamp, flags, drop_segments) values (v.obj#, v.inserts, v.updates, v.deletes, sysdate, v.flags, v.drop_segments) /* 最后刪除sys.mon_mods$上的相關記錄 */ delete /*+ dynamic_sampling(m 4) dynamic_sampling_est_cdn(m) */ from sys.mon_mods$ m where exists (select /*+ unnest */ * from sys.tab$ t where t.obj# = m. obj#) select obj# from sys.mon_mods$ where obj# not in (select obj# from sys.obj$) Used to have a FULL TABLE SCAN on obj$ associated with monitoring information extracted in conjunction with mon_mods$ executed by SMON periodically.因為當SMON或用戶采用”DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO”存儲過程將DML數據刷新到mon_mods$或mon_mods_all$中時會要求持有表上的排它鎖,所以在RAC環境中可能出現死鎖問題。
另外在早期版本中SMON可能因維護監控表而造成shutdown immediate緩慢或系統性能下降的問題,詳見:
<Shutdown immediate hangs if table monitoring enabled on [ID 263217.1]>
<Bug 2806297 – SMON can cause bad system performance if TABLE MONITORING enabled on lots of tables [ID 2806297.8]>SMON維護MON_MODS$時相關的Stack CALL
kglpnal <- kglpin <- kxsGetRuntimeLock <- kksfbc <- kkspsc0 <- kksParseCursor <- opiosq0 <- opiall0 <- opikpr <- opiodr <- PGOSF175_rpidrus <- skgmstack <- rpiswu2 <- kprball <- kprbbnd0 <- kprbbnd <- ksxmfmel <- ksxmfm <- ksxmfchk <- ksxmftim <- ktmmon <- ktmSmonMain <- ksbrdp <- opirip <- opidrv <- sou2o <- opimai_real <- ssthrdmain <- main <- libc_start_main <- start如何禁止SMON維護MON_MODS$
注意在缺省參數環境中創建的表總是啟用table monitoring的:
SQL> select * from v$version; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production PL/SQL Release 11.2.0.2.0 - Production CORE 11.2.0.2.0 Production TNS for Linux: Version 11.2.0.2.0 - Production NLSRTL Version 11.2.0.2.0 - Production SQL> select * from v$version; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production PL/SQL Release 11.2.0.2.0 - Production CORE 11.2.0.2.0 Production TNS for Linux: Version 11.2.0.2.0 - Production NLSRTL Version 11.2.0.2.0 - Production SQL> create table maclean1 (t1 int); Table created. /* 在10g以后nomonitoring或monitoring選項不再有效 */ SQL> create table maclean2 (t1 int) nomonitoring; Table created. SQL> select table_name,monitoring from dba_tables where table_name like 'MACLEAN%'; TABLE_NAME MON ------------------------------ --- MACLEAN1 YES MACLEAN2 YES通常來說我們不需要禁止SMON維護MON_MODS$,除非是在SMON維護過程中遭遇shutdown過慢、性能降低或者異常情況恢復SMON隨機terminate實例的問題。
在10g以前可以使用MONITORING和NOMONITORING這2個選項來控制表級別的監控是否被開啟,此外我們還可以通過dbms_stats.ALTER_SCHEMA_TAB_MONITORING(‘maclean’,false)存儲過程在schema級別的monitoring是否被開啟,但是在10g以后這些方法不再有效,MONITORING和NOMONITORING選項被廢棄(In 10g the MONITORING and NOMONITORING keywords are deprecated and will be ignored.),其原有功能被STATISTICS_LEVEL參數所覆蓋。
Table-monitoring特性現在完全由STATISTICS_LEVEL參數所控制:
當STATISTICS_LEVEL設置為BASIC時,Table-monitoring將被禁用
當STATISTICS_LEVEL設置為TYPICAL或ALL時,Table-monitoring將啟用換而言之我們可以通過設置STATISTICS_LEVEL為BASIC達到禁止SMON后臺進程該種功能的作用,具體修改該參數的命令如下:
show parameter statistics_level alter system set statistics_level = basic;但是請注意如果你正在使用AMM或ASMM自動內存管理特性的話,那么STATISTICS_LEVEL參數是不能設置為BASIC的,因為Auto-Memory或Auto-Sga特性都依賴于STATISTICS_LEVEL所控制的性能統計信息。若一定要這樣做那么首先要diable AMM&ASMM:
#diable 11g AMM ,have to bounce instance #alter system set memory_target =0 scope=spfile; #diable 10g ASMM alter system set sga_target=0; alter system set statistics_level = basic;了解你所不知道的SMON功能(十):維護SMON_SCN_TIME字典基表
SMON后臺進程的作用還包括維護SMON_SCN_TIME基表。
SMON_SCN_TIME基表用于記錄過去時間段中SCN(system change number)與具體的時間戳(timestamp)之間的映射關系,因為是采樣記錄這種映射關系,所以SMON_SCN_TIME可以較為較為粗糙地(不精確地)定位某個SCN的時間信息。實際的SMON_SCN_TIME是一張cluster table簇表。
SMON_SCN_TIME時間映射表最大的用途是為閃回類型的查詢(flashback type queries)提供一種將時間映射為SCN的途徑(The SMON time mapping is mainly for flashback type queries to map a time to an SCN)。
Metalink文檔<Error ORA-01466 while executing a flashback query. [ID 281510.1]>介紹了SMON更新SMON_SCN_TIME的規律:
- 在版本10g中SMON_SCN_TIME每6秒鐘被更新一次(In Oracle Database 10g, smon_scn_time is updated every 6 seconds hence that is the minimum time that the flashback query time needs to be behind the timestamp of the first change to the table.)
- 在版本9.2中SMON_SCN_TIME每5分鐘被更新一次(In Oracle Database 9.2, smon_scn_time is updated every 5 minutes hence the required delay between the flashback time and table properties change is at least 5 minutes.)
另外從10g開始SMON也會清理SMON_SCN_TIME中的記錄了,SMON后臺進程會每5分鐘被喚醒一次,檢查SMON_SCN_TIME在磁盤上的映射記錄總數,若總數超過144000條,則會使用以下語句刪除最老的一條記錄(time_mp最小):
delete from smon_scn_time where thread = 0 and time_mp = (select min(time_mp) from smon_scn_time where thread = 0)
若僅僅刪除一條記錄不足以獲得足夠的空間,那么SMON會反復多次執行以上DELETE語句。
觸發場景
雖然Metalink文檔<Error ORA-01466 while executing a flashback query. [ID 281510.1]>指出了在10g中SMON會以每6秒一次的頻率更新SMON_SCN_TIME基表,但是實際觀測可以發現更新頻率與SCN的增長速率相關,在較為繁忙的實例中SCN的上升極快時SMON可能會以6秒一次的最短間隔頻率更新 , 但是在空閑的實例中SCN增長較慢,則仍會以每5或10分鐘一次頻率更新,例如:
[oracle@vrh8 ~]$ ps -ef|grep smon|grep -v grep oracle 3484 1 0 Nov12 ? 00:00:02 ora_smon_G10R21 SQL> select * from v$version; BANNER ---------------------------------------------------------------- Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bi PL/SQL Release 10.2.0.1.0 - Production CORE 10.2.0.1.0 Production TNS for Linux: Version 10.2.0.1.0 - Production NLSRTL Version 10.2.0.1.0 - Production SQL> select * from global_name; GLOBAL_NAME -------------------------------------------------------------------------------- www.oracledatabase12g.com & www.askmaclean.com SQL> oradebug setospid 3484; Oracle pid: 8, Unix process pid: 3484, image: oracle@vrh8.oracle.com (SMON) SQL> oradebug event 10500 trace name context forever,level 10 : 10046 trace name context forever,level 12; Statement processed. SQL> SQL> oradebug tracefile_name; /s01/admin/G10R21/bdump/g10r21_smon_3484.trc /* 等待一定時間 */
找出SMON trace文件中insert數據到SMON_SCN_TIME的記錄:
grep -A20 "insert into smon_scn_time" /s01/admin/G10R21/bdump/g10r21_smon_3484.trc insert into smon_scn_time (thread, time_mp, time_dp, scn, scn_wrp, scn_bas, num_mappings, tim_scn_map) values (0, :1, :2, :3, :4, :5, :6, :7) END OF STMT PARSE #4:c=0,e=43,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=1290280848899596 BINDS #4: kkscoacd Bind#0 oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00 oacflg=00 fl2=0001 frm=00 csi=00 siz=24 off=0 kxsbbbfp=7fb29844edb8 bln=22 avl=06 flg=05 value=767145793 Bind#1 oacdty=12 mxl=07(07) mxlc=00 mal=00 scl=00 pre=00 oacflg=10 fl2=0001 frm=00 csi=00 siz=8 off=0 kxsbbbfp=7fff023ae780 bln=07 avl=07 flg=09 value="11/14/2011 0:3:13" Bind#2 oacdty=02 mxl=22(04) mxlc=00 mal=00 scl=00 pre=00 oacflg=10 fl2=0001 frm=00 csi=00 siz=24 off=0 kxsbbbfp=7fff023ae70c bln=22 avl=04 flg=09 value=954389 Bind#3 -- insert into smon_scn_time (thread, time_mp, time_dp, scn, scn_wrp, scn_bas, num_mappings, tim_scn_map) values (0, :1, :2, :3, :4, :5, :6, :7) END OF STMT PARSE #1:c=0,e=21,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=1290281434933390 BINDS #1: kkscoacd Bind#0 oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00 oacflg=00 fl2=0001 frm=00 csi=00 siz=24 off=0 kxsbbbfp=7fb29844edb8 bln=22 avl=06 flg=05 value=767146393 Bind#1 oacdty=12 mxl=07(07) mxlc=00 mal=00 scl=00 pre=00 oacflg=10 fl2=0001 frm=00 csi=00 siz=8 off=0 kxsbbbfp=7fff023ae780 bln=07 avl=07 flg=09 value="11/14/2011 0:13:13" Bind#2 oacdty=02 mxl=22(04) mxlc=00 mal=00 scl=00 pre=00 oacflg=10 fl2=0001 frm=00 csi=00 siz=24 off=0 kxsbbbfp=7fff023ae70c bln=22 avl=04 flg=09 value=954720 Bind#3 -- insert into smon_scn_time (thread, time_mp, time_dp, scn, scn_wrp, scn_bas, num_mappings, tim_scn_map) values (0, :1, :2, :3, :4, :5, :6, :7) END OF STMT PARSE #3:c=0,e=20,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=1290281727955249 BINDS #3: kkscoacd Bind#0 oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00 oacflg=00 fl2=0001 frm=00 csi=00 siz=24 off=0 kxsbbbfp=7fb29844e960 bln=22 avl=06 flg=05 value=767146993 Bind#1 oacdty=12 mxl=07(07) mxlc=00 mal=00 scl=00 pre=00 oacflg=10 fl2=0001 frm=00 csi=00 siz=8 off=0 kxsbbbfp=7fff023ae780 bln=07 avl=07 flg=09 value="11/14/2011 0:23:13" Bind#2 oacdty=02 mxl=22(04) mxlc=00 mal=00 scl=00 pre=00 oacflg=10 fl2=0001 frm=00 csi=00 siz=24 off=0 kxsbbbfp=7fff023ae70c bln=22 avl=04 flg=09 value=954926 Bind#3 insert into smon_scn_time (thread, time_mp, time_dp, scn, scn_wrp, scn_bas, num_mappings, tim_scn_map) values (0, :1, :2, :3, :4, :5, :6, :7) END OF STMT PARSE #4:c=0,e=30,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=1290282313990553 BINDS #4: kkscoacd Bind#0 oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00 oacflg=00 fl2=0001 frm=00 csi=00 siz=24 off=0 kxsbbbfp=7fb29844edb8 bln=22 avl=06 flg=05 value=767147294 Bind#1 oacdty=12 mxl=07(07) mxlc=00 mal=00 scl=00 pre=00 oacflg=10 fl2=0001 frm=00 csi=00 siz=8 off=0 kxsbbbfp=7fff023ae780 bln=07 avl=07 flg=09 value="11/14/2011 0:28:14" Bind#2 oacdty=02 mxl=22(04) mxlc=00 mal=00 scl=00 pre=00 oacflg=10 fl2=0001 frm=00 csi=00 siz=24 off=0 kxsbbbfp=7fff023ae70c bln=22 avl=04 flg=09 value=955036 Bind#3
可以通過以上INSERT語句的TIME_DP綁定變量值中發現其更新SMON_SCN_TIME的時間規律,一般為5或10分鐘一次。這說明SMON_SCN_TIME的更細頻率與數據庫實例的負載有關,其最短的間隔是每6秒一次,最長的間隔為10分鐘一次。
由于SMON_SCN_TIME的更新頻率問題可能引起ORA-01466錯誤,詳見:
Error ORA-01466 while executing a flashback query. [ID 281510.1]
由于SMON_SCN_TIME的數據不一致可能引起ORA-00600[6711]或頻繁地執行”delete from smon_scn_time”刪除語句,詳見:
ORA-00600[6711]錯誤一例
High Executions Of Statement “delete from smon_scn_time…” [ID 375401.1]
SMON維護SMON_SCN_TIME時相關的Stack CALL,ktf_scn_time是更新SMON_SCN_TIME的主要函數:
ksedst ksedmp ssexhd kghlkremf kghalo kghgex kghalf kksLoadChild kxsGetRuntimeLock kksfbc kkspsc0 kksParseCursor opiosq0 opiall0 opikpr opiodr rpidrus skgmstack rpidru rpiswu2 kprball ktf_scn_time ktmmon ktmSmonMain ksbrdp opirip opidrv sou2o opimai_real main main_opd_entry
SMON 還可能使用以下SQL語句維護SMON_SCN_TIME字典基表:
select smontabv.cnt, smontab.time_mp, smontab.scn, smontab.num_mappings, smontab.tim_scn_map, smontab.orig_thread from smon_scn_time smontab, (select max(scn) scnmax, count(*) + sum(NVL2(TIM_SCN_MAP, NUM_MAPPINGS, 0)) cnt from smon_scn_time where thread = 0) smontabv where smontab.scn = smontabv.scnmax and thread = 0 insert into smon_scn_time (thread, time_mp, time_dp, scn, scn_wrp, scn_bas, num_mappings, tim_scn_map) values (0, :1, :2, :3, :4, :5, :6, :7) update smon_scn_time set orig_thread = 0, time_mp = :1, time_dp = :2, scn = :3, scn_wrp = :4, scn_bas = :5, num_mappings = :6, tim_scn_map = :7 where thread = 0 and scn = (select min(scn) from smon_scn_time where thread = 0) delete from smon_scn_time where thread = 0 and scn = (select min(scn) from smon_scn_time where thread = 0)
如何禁止SMON更新SMON_SCN_TIME基表
可以通過設置診斷事件event=’12500 trace name context forever, level 10′來禁止SMON更新SMON_SCN_TIME基表(Setting the 12500 event at system level should stop SMON from updating the SMON_SCN_TIME table.):
SQL> alter system set events '12500 trace name context forever, level 10'; System altered.
一般我們不推薦禁止SMON更新SMON_SCN_TIME基表,因為這樣會影響flashback Query閃回查詢的正常使用,但是在某些異常恢復的場景中SMON_SCN_TIME數據訛誤可能導致實例的Crash,那么可以利用以上12500事件做到不觸發SMON_SCN_TIME被更新。
如何手動清除SMON_SCN_TIME的數據
因為SMON_SCN_TIME不是bootstrap自舉核心對象,所以我們可以手動更新該表上的數據、及重建其索引。
如我在 <ORA-00600[6711]錯誤一例> 中介紹了因為SMON_SCN_TIME與其索引的數據不一致時,可以通過重建索引來解決問題:
connect / as sysdba drop index smon_scn_time_scn_idx; drop index smon_scn_time_tim_idx; create unique index smon_scn_time_scn_idx on smon_scn_time(scn); create unique index smon_scn_time_tim_idx on smon_scn_time(time_mp); analyze table smon_scn_time validate structure cascade;
可以在設置了12500事件后手動刪除SMON_SCN_TIME上的記錄,重啟實例后SMON會繼續正常更新SMON_SCN_TIME。除非是因為SMON_SCN_TIME表上的記錄與索引smon_scn_time_tim_idx或smon_scn_time_scn_idx上的不一致造成DELETE語句無法有效刪除該表上的記錄:文檔 <LOCK ON SYS.SMON_SCN_TIME [ID 747745.1]> 說明了該問題,否則我們沒有必要手動去清除SMON_SCN_TIME上的數據。
具體方法如下:
SQL> conn / as sysdba /* Set the event at system level */ SQL> alter system set events '12500 trace name context forever, level 10'; /* Delete the records from SMON_SCN_TIME */ SQL> delete from smon_scn_time; SQL> commit; SQL> alter system set events '12500 trace name context off'; 完成以上步驟后重啟實例restart instance shutdown immediate; startup;了解你所不知道的SMON功能(十一):OFFLINE UNDO SEGMENT
SMON這個老牌的后臺關鍵進程的作用還包括對UNDO/ROLLBACK SEGMENT的維護, 這種維護主要體現在2個方面: OFFLINE和SHRINK UNDO/ROLLBACK SEGMENT, 今天我們主要介紹OFFLINE ROLLBACK SEGMENT。
你肯定要問,Oracle為什么OFFLINE UNDO/ROLLBACK SEGMENT?
最主要的目的是減輕高并發事務環境中對UDNO SPACE撤銷空間使用的壓力。
觸發場景
在10g之前的9i中每12個小時SMON會根據V$UNDOSTAT中記錄來決定在現有基礎上要OFFLINE多少個UNDO SEGMENT,又要保留多少個UNDO SEGMENT; 在9i中被OFFLINED UNDO SEGMENT 還會被SMON DROP掉,以進一步回收空間。
具體保留多少個UNDO SEGMENT,取決于過去12個小時內的V$UNDOSTAT動態視圖記錄的最大并發事務數量在加上1,具體公式可以參考下面的SQL:
SQL> select max(MAXCONCURRENCY)+1 from v$undostat where begin_time> (sysdate-1/2); MAX(MAXCONCURRENCY)+1 --------------------- 4
若你在alert.log中發現類似以下的信息則說明OFFLINE UNDO SEGS已經在你的系統中發生過了:
SMON offlining US=13 Freeing IMU pool for usn 13 SMON offlining US=14 SMON offlining US=15 SMON offlining US=16 SMON offlining US=17
9i中SMON通過ktusmofd函數實現對UDNO SEGMENT的OFFLINE,ktusmofd的含義為[K]ernel [T]ransaction [U]ndo [S]ystem [M]anaged OFFLINE & DROP
通過ktsmgfru函數返回必要保留的ONLINE UNDO SEGMENT, 其詳細的算法如下:
SMON調用ktusmofd ,并發現instance啟動未超過12個小時并且_smu_debug_mode未設置KTU_DEBUG_SMU_SMON_SHRINK標志位 (_smu_debug_mode是SYSTEM MANAGED UNDO內部參數,KTU_DEBUG_SMU_SMON_SHRINK標志位控制是否強制SMON做SHRINK) YES - SMON不OFFLINE任何東西直接返回 NO - 調用ktsmgfru 獲得過去12小時的最大并發事務數 設置keep_online變量為ktsmgfru 返回值加上1 嘗試hold TA ENQUEUE(該隊列鎖控制UNDO TABLESPACE的串行操作),該操作的超時限制為30s 若無法獲得該ENQUEUE則說明正在切換UNDO TABLESPACE,ktusmofd將直接返回且不OFFLINE任何UNDO SEGMENTS 成功獲得該ENQUEUE鎖,進一步調用ktusmofxu并使用之前獲得的keep_online作為參數,開始OFFLINE 調用kslgpl函數獲得KTU LATCH 包括parent和所有的children LOOP 在現有的ONLINE UNDO SEGMENT之間循環 若發現該UNDO SEGMENT是SMU-SYSTEM MANAGED UNDO且其所在表空間是當前undo_tablespace指向的表空間的話 若keep_online >0 , 則keep_online-- 否則 釋放KTU latches 調用kturof1函數實際OFFLINE 該UNDO SEGMENT 重新get KTU latches END LOOP 釋放 KTU latches
SMON 調用ktusmofd維護OFFLINE UNDO SEGMENT的常見STACK CALL如下:
ktmmon->ktusmofd->ktusmdxu->ktcrcm->ktccpcmt->ktcccdel->ktadrpc->ktssdro_segment-> ktssdrbm_segment->ktsxbmdelext->kqrcmt->ktsscu xctrol ktcpoptx ktccpcmt ktcrcm ktusmdxu ktusmofd ktmmon ksedmp ksfdmp kgeasnmierr ktusmgmct ktusmdxu ktusmofd ktmmon ksbrdp opirip opidrv sou2o main
10g以前的UNDO OFFLINE算法仍不完善,這導致在實例重啟或切換UNDO TABLESPACE撤銷表空間時,生成一定數量ONLINE UNDO SEGMENT的系統預熱時間可能長達幾分鐘,對于高并發的環境來說這種延時是難以接受的。
從10g開始改進了SMON OFFLINE UNDO SEGMENT的算法,SMON會基于過去7天的(而非12個小時的)V$UNDOSTAT動態視圖信息或者AWR自動負載倉庫中的UNDO歷史快照使用信息來決定OFFLINE UNDO SEGMENT的數量, 且在10g中SMON 不再DROP掉多余的UNDO SEGS,而僅僅OFFLINE掉;作為一種SMU的改良算法這種做法被叫做”Fast Ramp-Up”。”Fast Ramp-Up”避免了早期版本中由SMON維護UNDO SEGS引起的等待或性能問題; 此外,未公開的BUG5079978可能在版本10.2.0.1中被觸發,該BUG的信息如下:
Unpublished
Bug 5079978 – APPST GSI 10G : – PRODUCTION INSTANCE UNUSABLE DUE TO US ENQUEUE WAITS
is fixed in 11.1 and patch set 10.2.0.4 and interim patches are available for several earlier versions.
Please refer to Note 5079978.8
可以通過后面要介紹的 10511 event來規避以上bug,Oracle官方也推薦在10g以前的版本中使用10511 event來避免SMON過度OFFLINE UNDO SEGS所引起的問題。
10g以后的具體算法如下:
判斷實例啟動是否超過7天? YES - 直接使用v$undostat中過去7天的最大并發事務數max(maxconcurrency) NO - 判斷是否是第一次調用OFFLINE UNDO SEGMENT的內核函數 YES - 檢查是否存在select_workload_repository function (SWRF)快照數據 NO - ONLINE 最小數目的UNDO SEGMENTS YES - 嘗試獲取AWR記錄表wrh$_undostat中過去7天的最大并發事務數max(maxconcurrency) 若無法獲得以上值,則嘗試讀取wrh$_rollstat中最近7天的最大rollback segs數量max(rbs cnt) 將返回值保存到內部變量中 NO - 直接使用內部變量中的值
如何禁止SMON OFFLINE UNDO SEGMENT?
可以通過設置診斷事件event=’10511trace name context forever, level 1′ 來禁用SMON OFFLINE UNDO SEGS; 但是10511事件不會跳過”Fast Ramp Up”,而僅會限制SMON對UNDO SEGS產生的工作負載。 一旦設置了10511 event, 則所有已生成的 UNDO SEGS會始終保持ONLINE狀態。
具體的設置方法:
SQL> select * from v$version; BANNER ---------------------------------------------------------------- Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi PL/SQL Release 10.2.0.5.0 - Production CORE 10.2.0.5.0 Production TNS for Linux: Version 10.2.0.5.0 - Production NLSRTL Version 10.2.0.5.0 - Production SQL> select * from global_name; GLOBAL_NAME -------------------------------------------------------------------------------- www.oracledatabase12g.com [oracle@vrh8 ~]$ oerr ora 10511 10511, 00000, "turn off SMON check to cleanup undo dictionary" // *Cause: // *Action: SQL> alter system set events '10511 trace name context forever,level 1'; System altered.
OFFLINE UNDO SEGS的相關BUG
以下列出了SMON OFFLINE UNDO SEGS的一些公開的BUG,這些BUG一般都存在于10.2.0.3之前; 若你真的遇到了,可以在考慮升級之余 采用10511 event workaround規避該問題:
Hdr: 2726601 9.2.0.2 RDBMS 9.2.0.2 TXN MGMT LOCAL PRODID-5 PORTID-46 ORA-600 3439552
Abstract: ORA-600 [4406] IN ROUTINE KTCRAB(); 4 NODE RAC CLUSTERHdr: 6878461 9.2.0.4.0 RDBMS 9.2.0.4.0 TXN MGMT LOCAL PRODID-5 PORTID-23 ORA-601 5079978
Abstract: ESSC: ORA-601 ORA-474 AFTER OFFLINING UNDO SEGMENTSHdr: 4253991 9.2.0.4.0 RDBMS 9.2.0.4.0 TXN MGMT LOCAL PRODID-5 PORTID-23 ORA-600 2660394
Abstract: ORA-600 [KTSXR_ADD-4] FOLLOWED BY ORA-600 [KTSISEGINFO1]Hdr: 2696314 9.2.0.2.0 RDBMS 9.2.0.2.0 TXN MGMT LOCAL PRODID-5 PORTID-46
Abstract: RECEIVING ORA-600: [KTUSMGMCT-01] AFTER APPLYING 92020 PATCH SETHdr: 3578807 9.2.0.4 RDBMS 9.2.0.4 TXN MGMT LOCAL PRODID-5 PORTID-23 ORA-600
Abstract: OERI 4042 RAISED INTERMITTENTLY
Hdr: 2727303 9.2.0.1.0 RDBMS 9.2.0.1.0 TXN MGMT LOCAL PRODID-5 PORTID-100 ORA-600
Abstract: [RAC] ORA-600: [KTUSMGMCT-01] ARE OCCURED IN HIGH LOAD
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
