調整歸檔時第一件需要確保的事是LGWR沒有等待ARCn完成歸檔一個日志文件
第二個需要考慮的是ARCn活動時的影響對前台進程最小化
而這兩個方面通常是剛好相對的
因此最好的目標就是調整ARCn使其足夠快
並在可以證明其影響了前台進程時降低其速度
主要包括以下原則
另外還包括歸檔可用的緩沖大小和數量的調整
以及歸檔進程的數量
緩沖的大小
ARCn每次從日志文件讀取 _log_archive_buffer_size(以塊為單位)並寫入歸檔目的地因此如果_log_archive_buffer_size設置為OS下最大的可能值那麼ARCn的性能將最大化並且其在I/O子系統上的負載將最小化如果該參數在OS上為UNLIMITED那麼設置為最大的物理I/O大小的幾倍效果將最好
緩沖的數量
如果_log_archive_buffers可用並且可以從日志文件異步讀取那麼ARCn將使用aio_read()系統調用並行讀取日志到多個緩沖如果多個日志成員可用將使用並行異步讀每個日志文件成員以擴展磁盤I/O負載如果使用了軟件/硬件鏡像進行日志文件傳播類似的負載平衡將會自動由軟件/硬件使用因此可以考慮使用並行歸檔讀使用與每個日志文件相同多的磁盤鏡像或者傳播然後配置_log_archive_buffers最多為
需要注意的是不能通過設置多個_arch_io_slaves來模麓尤罩疚募稍輩⑿幸觳蕉痢RCn通常自己執行該任何並僅使用I/O服務器來寫操作
為了在可能時進行異步歸檔寫至少需要設置兩個_log_archive_buffers以並行從日志文件讀取但是如果系統達到了cpu負載頸瓶並且歸檔期間前台進程受到了影響並且沒有歸檔聚集的威脅應該考慮減少緩沖數量分散cpu負載
進程數量
如果產生的重做持續過高或者需要歸檔到多個位置通常需要多個ARCn進程從Oraclei開始可以通過設置log_archive_max_processes參數也可以通過定期調度ALTER SYSTEM ARCHIVE LOG ALL如果沒有歸檔聚集該命令的影響是很小的但是如果有該命令會迅速產生額外的arcn幫助趕上聚集
為了防止LGWR趕上歸檔聚集運行多個ARCn是最大的保險但是為了使該策略有效恰當的配置在線日志和歸檔終點的磁盤是很重要的
因為也可以使用手工歸檔Oracle在歸檔期間將在任何在線日志文件上保留一個排斥的WL(等待日志)隊列鎖而忽略log_archive_max_processes的設置這些隊列上的操作由archive control latch保護歸檔活動可以從STATSPACK等報告中的該LARCHE上的gets列得到
影響歸檔進程性能的兩個威脅
在RAC環境下在實例沒有啟動時其線程是可用的如果一個關閉的啟用的線程的當前SCN落後於force scn那麼在那個線程上將發生強制的日志切換並且活動實例的ARCn為未活動的實例歸檔日志文件這使得arcn進程轉移到那個實例中工作而不是執行其自己的工作然而如果ARCn被其自己的lgwr喚醒歸檔其自己實例的日志那麼ARCn將會刮起這個歸檔這應該通過保持空閒實例啟動或者禁用其重做線程完全避免
歸檔在前項滾動期間將被完全禁用因此應該確保干淨的關閉保持重做產生最小化
通用的索引塊頭
header address =xcc
kdxcolev
KDXCOLEV Flags =
kdxcolok
kdxcoopc x: opcode=: iot flags= is converted=Y
kdxconco
kdxcosdc
kdxconro
kdxcofbo =x
kdxcofeo =x
kdxcoavs
kdxcolev索引級別(代表頁塊)
kdxcolok標示結構塊事塊是否發生
kdxcoopc內部操作碼
kdxconco索引列數量包括ROWID
kdxcosdc塊中索引結構改變的數量
kdxconro索引條目的數量不包括kdxbrlmc指針
kdxcofbo塊中空閒空間的開始位置
kdxcofeo塊中空閒空間的結束位置
kdxcoavs塊中的可用空間數量(kdxcofbokdxcofeo)
分支頭區域
kdxbrlmc =x
kdxbrsno
kdxbrbksz
kdxbrlmc如果索引值小於第一個值(row#)則為該索引值所在的塊地址
kdxbrsno最後更改的索引條目
kdxbrbksz可使用的塊空間
葉塊頭區域
kdxlespl
kdxlende
kdxlenxt =xb
kdxleprv =xd
kdxledsz
kdxlebksz
kdxlespl塊拆分時被清除的未提交數據的字節數
kdxlende被刪除的條目數
kdxlenxt下一個頁塊的RBA
kdxleprv上一個頁塊的RBA
kdxlebksz可使用的塊空間(默認小於分支的可用空間)
分支條目
row#[] dba: =x
col ; len ; (): c
col ; TERM
row#[] dba: =x
col ; len ; (): c
col ; TERM
行號[塊中的起始位置] dba
列號列長度列值
brach中的每個entry有個columns:
一個是child blocks中的最大值另一個是指向的下一層block的address
但是某些時候可能會有一些比較奇怪的結果
row#[] dba: =xc
col ; len ; ():
…
col ; len ; ():
end of branch block dump
葉條目
row#[] flag: S lock: len=
col ; len ; (): c
col ; len ; (): db a
row#[] flag: DS lock: len=
行號[在塊中的開始位置] 各種標記(鎖信息刪除信息)
索引列號長度值其中個字節的為ROWID號將其轉換為二進制算法結果為
前 bit代表了file_id
中 bit代表了block_id
後 bit代表了row_id
通過文件號和塊號算出的結果為創建該索引的表的塊
奇怪的是為什麼索引中的rowid不能直接找到obj_id?
因為索引段對應的數據段在 一開始就知道因為是先知道數據段才找到索引段然後
根據索引段內容去搜索數據段內容所以索引段中 rowid 不必包含 data_object_id 信息
如果索引是建立在非分區表上或者是分區表上的 LOCAL 索引使用的是 bytes的 Restricted ROWID如果索引是建立在分區表上的 GLOBAL index則使用 bytes 的 Extended ROWID這樣可以區分索引指向哪個分區表
更新/重用索引條目
當更新了索引條目後DUMP如下
kdxconco
kdxcosdc
kdxconro
kdxcofbo =x
kdxcofeo =xf
kdxcoavs
kdxlespl
kdxlende
kdxlenxt =x
kdxleprv =x
kdxledsz
kdxlebksz
row#[] flag: D lock: => deleted index entry
col ; len ; (): f
col ; len ; (): a
row#[] flag: lock:
col ; len ; (): a => new index entry
col ; len ; (): a
更新後將包含一個刪除的條目一個新的條目在隨後的插入中如果新插入的索引條目能夠放到被刪除的索引條目的位置上就會直接重用這個條目根據索引值來決定
所謂重用是對row 的重用而不是對row所在物理存儲(或說物理位置)的重用索引是按照indexed value對row進行排序的有新的row被插入首先按照value排序將他放在合適的row list中如果他的位置正好原來有個row被刪掉了則重用這個row在row list中的位置至於物理存儲上則可能根據版本不同會有不同在中我做的測試並沒有向下開辟空間
結論:
·到葉塊中的任何插入都將移除所有被刪除的條目
·刪除的空間在隨後的寫中被清除
·刪除的空間在延遲塊清除中被清除
·全空塊被放在空閒列表可以重用
索引統計
·dba_indexes
·dbms_stats
·index_stats
analyze index index_name validate structure;
分析資源鎖
·v$segment_statistics
statistics_level = typical (or all)
注意事項
blevel (dba_indexes) vs height (index_stats)
blocks allocated但未必使用
lf_rows_len包含行負載(單列索引個字節)
pct_used索引結構中當前使用的空間(used_space/btree_space)*
絕大多數索引統計包含刪除的條目
nondeleted rows = lf_rows – del_lf_rows
pct_used by nondeleted rows = ((used_space – del_lf_rows_len) / btree_space) *
From:http://tw.wingwit.com/Article/program/Oracle/201311/16904.html