1、rollback segments的作用:事務的rollback;transaction recovery(當事務尚未提交或rollback時instance fail,startup時會用rollback segment進行回滾恢復);讀一致性也需要rollback segment進行數據的還原。在新的版本中(我記得是從10g中)flashback技術也使用了rollback segment。這里先不介紹了,碰到時在說。
2、rollback segment的activity:
1)transaction以順序循環的方式使用rollback segment中的extents。一個transaction在rollback segment的當前位置寫入記錄,并將指針移動寫入記錄的大小的步長。寫入rollback segment的請求需要相應的undo data在database buffer cache中是可用的。這就要求有較大的buffer cache。
2)注意:多個transaction可以對一個rollback segment中的同一個extent進行寫操作。每個rollback segment block只會包含一個transaction的數據信息。
3)rollback segment header中包含了不同transaction各自的記錄:Oracle server在每個rollback segment header中保存一個transaction tables,從而控制改變rollback segments中data block的操作。
因為需要不斷修改,所以rollback segment header block被長期保存在data block buffer cache。而不斷的訪問rollback segment header block會增加命中率。這種影響對于某些有大量小型事務的OLTP的application影響較大。每個transaction都需要修改 transaction tables,所以必須有足夠大的rollback segment從而避免對transaction tables的沖突。低估rollback segment的需求,可能引起性能問題或errors。高估會浪費空間。可以使用自動undo表空間管理的方法管理undo segments。
4)rollback segments的增長:
當當前extent寫滿后,指針或是rollback segment的頭回移動到下一個extent。當最后一個extent作為當前寫入的extent,被寫滿后,如果此時第一個extent是free 的,則指針將指向第一個extent的開始。指針式不能跳過(skip over)extent,移動到后面的extent上的。所以如果第一個extent仍被使用,將會為此rollback segment分配一個新的extent。這被稱作extend。
在正常的運行期間,rollback segments不應該被extend。所以在之前應該分配足夠的rollback segment空間。應該盡量避免動態空間的管理。
2、調節手動管理的rollback segments
1)調節rollback segment的目標:
* 盡量使transaction不會為訪問rollback segment而等待:這需要有足夠的rollback segment
* 在運行期間,應避免rollback segment的extend:
需要每個segment有適當數量的extents
extents的四則應該正確
適當數量的rollback segment
盡量減少應用中對rollback的應用
* 應該沒有transaction把rollback space占用完:對此應該將較大transaction用多個transaction替代
* 數據查詢user應該總是能獲得讀一致的數據:這需要考慮設置適當數量的segments和適當的segments size。
2)診斷工具:常用的監控視圖有:
* V$ROLLNAME:顯示了在線rollback segments的名字和數量
* V$ROLLSTAT:顯示了每個在線rollback segment的統計信息。等待header transaction tables的數量,transaction寫數據的卷標等信息。
* V$WAITSTAT:顯示等待header blocks和rollback segments的blocks累計數量。undo header和undo block兩條記錄。
* V$SYSSTAT:顯示
select name, value from v$sysstat where name like ‘%undo%’;
* V$TRANSACTION:顯示當前transaction使用的rollback segment和require的空間的卷標。
在查詢時需要用視圖中的USN作為連接字段。
3)對手動管理的rollback segment header沖突的診斷
查看:v$rollstat中的waits字段;v$waitstat中的undo header行;
select event, total_waits, time_waited from v$system_event where event like ‘%undo%’;
select class, count from v$waitstat where class like ‘%undo%’;
select sum(value) from v$sysstat where name in (‘db block gets’, ‘consistent gets’);
select sum(waits)*100/sum(gets) “ratio”, sum(waits) “waits”, sum(gets) “gets” from v$rollstat;
當等待的比率大于1%,則考慮創建更多的rollback segment。
4)對于手動管理的rollback segment的數量的考慮
* 對于OLTP application,其特點是有大量的小transaction并發,每個transaction只修改很少的數據量。對此可以設置small rollback segments。一般的設定規律是,并發的transaction中,每4個設置一個rollback segment。
* 如果對于存在較大的批量transaction時,如果rollback segment較小,就可能會發生extend。允許rollback segment可以無限自行extend。
* 如果想要給long transaction分配large rollback segment,可以使用下面的語法:
SET TRANSACTION USE ROLLBACK SEGMENT large_rbs; –必須是事務的第一句
或
execute dbms_transaction.use_rollback_segment(‘large_rbs’);
5)Sizing 手動管理的rollback segment的大小
設置適當的rollback segment size一方面可以避免動態的extend,另一方面當undo blocks被請求時增大了它在cache的可能性。
* 對于small transactions設置segments的initial參數為8KB、16KB、32KB或64KB,對于larger transaction設置為128KB、256KB、512KB、1MB、2MB、4MB等。該值應該設置的足夠大,以免出現wrapping現象(當 一個rollback entry在當前使用的空間中找不到足夠的空間時,被寫入下一個extent)。
* 使用與initial相等的數值做next的參數值。因為PCTINCREASE設置為0,所以后續所有的extents都將是next大小。
* 將DB中的所有rollback segment都設置為相同的size。如果暫時不需要large rollback segment,可以先將其offline。
* 將minextents參數設置為20 。這大致可以避免extend的現象。
* 對于表空間的size設置,我以為書中沒有介紹太多的方法,需要在實際應用中查看產生的undo entries的數量進行設置。此外,可以為其保留一個專門用于large-than-usual transaction的segment。
3、transaction rollback data的sizing
1)不同的sql操作所產生的rollback data的大小有下面而定:
* delete操作對rollback segment的開銷很大,會存儲實際row的數據。如果使用truncate,則會對性能有所改變,但是因為沒有寫rollback entries,所以不能再恢復。
* insert 使用的rollback space很少,只會記錄row id。
* update操作占用的空間要依靠修改的字段數量而定。
* indexed 值將會產生較多rollback。因為server在修改index的同時需要修改tables中row,對于對index字段的update操作,需要 記錄old data value、old index value和new index value。
note:lob數據類型的回滾數據不使用rollback segment space,而是占用其自己的segment中由參數pctversion定義的大小的空間。
可以通過下面的sql查看當前事務產生的rollback data
select s.username, t.user_ublk, t.start_time from v$transaction t, v$session s where t.addr, s.taddr;
2)另一種衡量方法是,實際執行相應的操作,從而觀察rollback segment的變化
* 在執行操作前運行:select usn, writes from v$rollstat;
* 執行測試的事務操作
* 再次查看rollback segment的統計數據:select usn, writes from v$rollstat;
4、使用產生少量rollback data 的語句:
* user應該盡可能有規律的commit,避免其transaction鎖住外部的rollback segment extents。
* 開發人員應該在code時不使用long transaction。
* import操作時,指定commit=y,使得每插入一定數據后就進行commit;用buffer_size關鍵字設置rows集合的大小。
* export操作時:設置參數consistent=n,避免該是我被設置為只讀,那將占用更多的rollback segment space。consistent=y時,確保了導出的數據在一個時間點上是一致的。
* sql*loader:在執行時也應用rows關鍵字設置commit interval。
note:對于小rollback segments可能帶來的問題有:
* interested transaction list(ITL)被存放在block的header。每個ITL entry都包含了發起此處變更的transaction id、undo block的位置、標識位、空閑空間credit和SCN。row lock byte包含了ITL實體number,就相當于該transaction擁有該row的鎖。
如果transaction很大,可能會由于rollback segment達到其最大的extents,或是表空間中已經沒有可用于extend的空間給rollback segment了,而導致transaction的失敗。
* 在查詢操作遇到ORA-01555: snapshot too old (rollback segment too small)的錯誤時,說明此操作需要為了保持一致讀的鏡像數據塊被其他transaction覆蓋了。對此的修復只有增大rollback segments。
5、自動管理undo表空間模式
從9i開始,也已通過將UNDO_MANAGEMENT設置為auto將DB設置為自動管理undo表空間的模式(AUM),如果設置為manual則仍 使用手工的管理(RBU)。當在一個transaction中,第一個DML操作被執行,transaction將被分配到當前undo tablespace中的一個rollback segment上。可以通過參數UNDO_RETENTION設置存放在AUM中的undo信息的數量。
1)AUM的tablespace:
具體創建undo tablespace的方法:create database是使用undo tablespace子句,此時會創建一個名為SYS_UNDOTBS的undo tablespace,在$ORACLE_HOME/dbs下將會生成DBU1<SID>.dbf的文件,并且autoextend=on; 另外可以使用create undo tablespace創建。
2)對于AUM的表空間,可做下面的操作:
alter tablespace tspname
• ADD DATAFILE
• RENAME
• DATAFILE [ONLINE|OFFLINE]
• BEGIN BACKUP
• ENDBACKUP
DBA仍可切換當前使用的undo tablespace,只有一個undo tablespace可以設置為active。
eg:ALTER SYSTEM SET UNDO_TABLESPACE=UNDOTBS2;
當該指令發出,所有新的transaction將被指向新的undo tablespace,當前正在運行的transaction將繼續沿用舊的undo tablespace,直到結束。
DBA只能通過drop tablespace命令刪除當前非active的undo tablespace,并且其不包含任何未提交的transaction的rollback data。
3)對于自動管理undo tablespace的參數設置:
* UNDO_MANAGEMENT:指明是AUTO或MANUAL
* UNDO_TABLESPACE:指明當前active的undo tablespace。如果在創建是沒有undo tablespace可用,則會使用system表空間作為rollback segment的分配空間。
* UNDO_SUPPRESS_ERRORS:此參數主要用于使用SET TRANSACTION USE ROLLBACK命令下
* UNDO_RETENTION:設置存放在AUM中的undo信息的數量。其單位是秒,默認值是900
關于undo retention所需的空間的計算:
undo space = (UNDO_RETENTION * (undo blocks per second*db_block_size) ) + DB_BLOCK_SIZE
可以使用下面的sql進行計算,并設置undo tablespace的大小:
SELECT (RD*(UPS*OVERHEAD) + OVERHEAD) AS “bytes”
FROM (SELECT value AS RD FROM v$parameter where name = ‘undo_retention’),
(SELECT (SUM(UNDOBLKS)/SUM(((end_time-begin_time)*86400))) as UPS FORM v$undostat),
(SELECT value AS Overhead FROM v$parameter where name=’db_block_size’);
4)對自動管理undo tablespace的監控:
通過查看V$UNDOSTAT視圖可以完成監控的任務。字段UNDOBLKS顯示了undo blocks的分配數量。