天天看點

undo表空間手動管理

UNDO_MANAGEMENT specifies which undo space management mode the system should use. When set to AUTO, the instance starts in automatic undo management mode. In manual undo management mode, undo space is allocated externally as rollback segments.

Automatic Undo Management

自動重做管理

Oracle 伺服器自動管理重做段的建立、配置設定、和調整

Manual Undo Management

手工管理重做

手工管理重做段的建立、配置設定、調整。這是Oracle9I之前的唯一方法

1、使用manual

1)復原段的配置設定和使用

    1>當事務産生的時候,資料庫會給事務配置設定一個復原段。當然我們可以指定事務使用某個復原段。在我的測試用的資料庫中,有如下復原段

SQL> select SEGMENT_ID ,SEGMENT_NAME  from dba_rollback_segs;
 
     
    
 
 
     
    
SEGMENT_ID SEGMENT_NAME
 
     
    
---------- ------------------------------
 
     
    
         0 SYSTEM
 
     
    
         1 RBS0
 
     
    
         2 RBS1
 
     
    
         3 RBS2
 
     
    
         4 RBS3
 
     
    
         5 RBS4
 
     
    
         6 RBS5
 
     
    
         7 RBS6
 
     
    
         9 RBS12
 
     
    
 
 
     
    
9 rows selected.
 
     
    
 
 
     
    
SQL>      

如果我們要指定事務使用某個復原段,如下

SQL>  set transaction use rollback segment rbs6;
 
     
    
 
 
     
    
Transaction set.
 
     
    
 
 
     
    
SQL>  insert into t select * from all_objects;
 
     
    
 
 
     
    
25649 rows created.
 
     
    
 
 
     
    
SQL> commit;
 
     
    
 
 
     
    
Commit complete.      

       如果我們不人為的指定使用哪個復原段,則資料庫會根據復原段中事務來權衡,以使得所有復原段中事務壓力盡可能平均。我們考慮存在非系統復原段的情況(這 也是絕大多數系統的情況,除非因為DBA嚴重錯誤才會使得系統隻存在系統復原段),在這種情況下我們發出的事務不會去使用系統復原段,這時系統復原段隻用 于系統級使用,比如create、drop、truncate等發生的時候的系統級的資料字典的復原記錄。資料庫為我們發出的事務選擇非系統復原段,同一 個事務不能跨越復原段,也就是說即使其他復原段還很空閑,該大事務也隻能使用被配置設定的復原段即使該復原段擴充。

接 下來我們來考究單個復原段内的使用、擴充、回縮的問題。一個復原段至少包含2個extent。每個復原段有一個復原段頭,復原段頭是一個block,裡面 主要記錄了事務表資訊。當産生一個事務的時候,就在復原段頭的事務表中記錄一條資訊,該資訊中包含了事務标志、事務狀态、使用的復原段塊數等等資訊。我們 假定新建立的一個復原段存在extent 1,2,3,4,5。當第一個事務配置設定到復原段中的時候,除了事務表資訊,該事務從extent 1的第二個block開始使用,該事務送出後陸續不斷的事務到來并送出,假設我們已經使用到了extent 5的末尾。這時再來事務内容需要寫入,則重新使用extent 1 的第二個block。這樣循環使用復原段空間。同理復原段頭的事務表也是如此循環使用。循環的次數,可以通過如下查詢獲得

SQL>  select usn,WRAPS from v$rollstat;
 
     
    
 
 
     
    
       USN      WRAPS
 
     
    
---------- ----------
 
     
    
         0          0
 
     
    
         1         15
 
     
    
         2         15
 
     
    
         3         15
 
     
    
         4         15
 
     
    
         5         12
 
     
    
         6         15
 
     
    
         7         17
 
     
    
         9         12
 
     
    
       
 
     
    
9 rows selected.
 
     
    
 
 
     
    
SQL>      

      那麼我們會有一個問題,那就是既然復原段是循環使用的,那為什麼會擴充呢?注意在上面的例子中,所有的事務都是迅速送出了的。那我們現在假定這樣一種情 況,存在一個事務,假設在extent 3 中有一個事務一直沒有送出,然後復原段一直循環使用到了extent 2。當extent 2使用完畢的時候發現extent 3中存在未送出事務,這是即使extent 4,5,1中的事務都已經送出,目前事務也不能越過extent 3而去使用後面的可使用的extent,這時該復原段就擴充新的extent,假定為extent 2-1。在資料庫中實際上復原段的extent之間是通過指針連起來的一個單向循環的連結清單結構。擴充的時候相當于在連結清單中插入一個節點extent 2-1,但節點2-1的下一個extent依然是 extent 3,假如2-1使用完畢發現extent 3仍然存在未送出事務復原段會繼續擴充。

    我們做個例子,在SQLPLUS 1 中運作不送出(我們在v$rollstat 和 dba_rollback_segs中分别查詢發現usn =5的復原段對應了名字 rbs4)

SQL> select a.usn,b.segment_name from v$rollstat a,dba_rollback_segs b
 
     
    
  2  where a.usn = b.segment_id;
 
     
    
 
 
     
    
       USN SEGMENT_NAME
 
     
    
---------- ------------------------------
 
     
    
         0 SYSTEM
 
     
    
         1 RBS0
 
     
    
         2 RBS1
 
     
    
         3 RBS2
 
     
    
         4 RBS3
 
     
    
         5 RBS4
 
     
    
         6 RBS5
 
     
    
         7 RBS6
 
     
    
         9 RBS12
 
     
    
 
 
     
    
9 rows selected.
 
     
    
 
 
     
    
SQL>
 
     
    
SQL> select usn,rssize "rollback segment size" from v$rollstat where usn = 5;
 
     
    
 
 
     
    
USN     rollback segment size
 
     
    
---------- ---------------------
 
     
    
5         4186112
 
     
    
 
 
     
    
SQL>  set transaction use rollback segment rbs4;
 
     
    
 
 
     
    
Transaction set.
 
     
    
 
 
     
    
SQL>  update t_small set object_id = 1;
 
     
    
 
 
     
    
100 rows updated.
 
     
    
 
 
     
    
打開SQLPLUS 2運作
 
     
    
begin
 
     
    
for i in 1..1000 loop
 
     
    
set transaction use rollback segment rbs4;
 
     
    
update t set object_id = i where rownum < 101;
 
     
    
commit;
 
     
    
end loop;
 
     
    
end;
 
     
    
SQL>  select usn,rssize "rollback segment size" from v$rollstat where usn = 5;
 
     
    
 
 
     
    
USN      rollback segment size
 
     
    
----------    ---------------------
 
     
    
5          55042048
 
     
    
 
 
     
    
    現在我們來看在一個獨立的session中運作下面的查詢并對比查詢前後的復原段變化。
 
     
    
 
 
     
    
 
 
     
    
SQL> select  usn,rssize "rollback segment size" from v$rollstat where usn= 4;
 
     
    
 
 
     
    
USN     rollback segment size
 
     
    
---------- ---------------------
 
     
    
4        4186112
 
     
    
 
 
     
    
SQL> begin
 
     
    
  2  for i in 1..1000 loop
 
     
    
  3  set transaction use rollback segment rbs3;
 
     
    
  4  update t set object_id = i where rownum < 101;
 
     
    
  5  commit;
 
     
    
  6  end loop;
 
     
    
  7  end;
 
     
    
  8  /
 
     
    
 
 
     
    
PL/SQL procedure successfully completed.
 
     
    
 
 
     
    
SQL>  select  usn,rssize "rollback segment size" from v$rollstat where usn= 4;
 
     
    
 
 
     
    
USN     rollback segment size
 
     
    
---------- ---------------------
 
     
    
4         4186112
 
     
    
 
 
     
    
SQL>
 
     
    
 
 
     
    
     在這兩個例子中我們很明顯地看到了復原段是否擴充的對比。那麼,做完第二個例子後,我再回過頭來查詢原來擴充的比較大的復原段,發現又變成4M了
 
     
    
 
 
     
    
SQL>  select  usn,rssize "rollback segment size" from v$rollstat where usn= 5;
 
     
    
 
 
     
    
       USN rollback segment size
 
     
    
---------- ---------------------
 
     
    
         5               4186112
 
     
    
 
 
     
    
SQL>      

      復原段在擴充後,是要回縮的。假設復原段目前extent n,使用完畢将準備使用extent n+1 的時候(extent n+1 無活動事務),如果設定了optimal并且復原段大于 optimal設定的大小,檢查extent n+2 中是否有未送出事務,如果沒有,則回收extent n+2,本質上,就是在復原段的連結清單上摘去extent n+2 ,然後繼續檢查extent n+3 決定是否回收,由此重複該動作。Optimal設定決定了復原段最終回收後的大小,復原段回縮後大小盡可能的接近optimal設定,如上面例子是4M, 可通過下面查詢(shrinks表示復原段回縮的次數,實際上v$rollstat提供了很多的復原段資訊,大家可以參考oracle document)

SQL> select  USN,OPTSIZE,SHRINKS  from  v$rollstat;
 
     
    
 
 
     
    
       USN    OPTSIZE    SHRINKS
 
     
    
---------- ---------- ----------
 
     
    
         0                     0
 
     
    
         1    4194304          0
 
     
    
         2    4194304          0
 
     
    
         3    4194304          0
 
     
    
         4    4194304          0
 
     
    
         5    4194304         10
 
     
    
         6    4194304          0
 
     
    
         7    4194304          0
 
     
    
         9                     0
 
     
    
 
 
     
    
9 rows selected.      

   2> 系統復原段、非系統的復原段與延遲復原段

 SYSTEM 

Undo Segment

SYSTEM 復原段是建立在系統表空間中,主要是用于系統級的事務和配置設定普通事務于其他復原段上。當手工建立資料庫後需要建立普通復原段之前必須首先建立系統復原段。 按照oracle文檔說明,當普通事務異常多的事情可能會出現使用系統復原段的情況。但正常情況下,系統復原段主要用于兩個方面。一是系統事務,比如針對 資料字典的操作的truncate table 和 drop table 。如果truncate table or  drop table 的過程中沒有成功,則系統會根據系統復原段中的資料字典操作資訊對該DDL操作進行回退。另一個方面,就是延遲復原段(Deferred Rollback Segment)。延遲復原段表示的是,當我們使一個表空間OFFLINE(exeample: alter tablespace users offline)之後,由于表空間不可用(不能進行讀寫),這個時候若有事務資料位于該表空間并且執行了復原指令,復原完成将顯示給client,對于 client看起來該事務已經復原,但是對于資料庫來說該復原并沒有真正完成,這個時候資料庫将該復原資訊寫入系統復原段(這就是延遲復原段),等表空間 重新ONLINE的時候,資料庫從系統復原段中将復原資訊寫入表空間。

Non-SYSTEM Undo Segments

非系統重做段

資料庫擁有多個表空間時需要至少一個非系統的手工模式重做段或者自動模式的重做表空間

 2)復原段的設定和管理

     事實上,對于作為個人意見來說,復原段的管理本不應該是作為DBA的複雜的任務來對待的,因為復原段的管理本來就可以使其很簡單。幾乎所有的系統出現回 滾段問題,不外乎都是復原段大小不足、復原段個數太少。9i以前的版本因為對于我們來說,無非也就是這兩個問題。

關于復原段表空間大小、復原段資料檔案的擴充、復原段的擴充等建立時指定的參數問題,我想參考建立文法就足夠了,沒有必要在這上去糾纏max extents是100還是200,你會發現去考慮這些參數沒有實質上的意義了。所有的一切設定,我隻需要問幾個問題就足夠了:

1:系統并發事務數有多少?

2:系統是否存在大查詢或者大是事務?頻繁麼?

3:能提供給系統的復原段表空間的磁盤空間是多少?

    在初始化參數檔案中存在參數transactions_per_rollback_segment和transactions,共同決定了執行個體啟動的時候 将嘗試聯機的最大復原段個數,transactions決定了同時存在的最大事務數。在這裡順便提及的2個初始化參數

max_rollback_segments   系統允許的最大復原段個數

rollback_segments  該參數是一個參數清單,假如建立復原段的時候是PUBLIC類型,則跟該參數無關,假如是PRIVATE類型的,則必須使得復原段出現在該參數清單裡面, 否則資料庫啟動之後這些復原段不會自動聯機(可手動)。在OPS/RAC中,PUBLIC類型的復原段表示所有的INSTANCE都可以聯機這些復原段 (但同一時刻隻能有一個執行個體聯機),相當于是一個公共復原段池。

在 執行個體啟動的時候,執行個體嘗試聯機rollback_segments中設定的復原段,直到達到個數為 min(CEIL(transactions/transactions_per_rollback_segment), max_rollback_segments)。若沒有達到這個值,則執行個體嘗試在PUBLIC類型的復原段池中嘗試聯機復原段,直到達到該值或者不再有回 滾段可聯機。

當一個執行個體啟動後其聯機復原段的個數是否足夠,跟并發事務數有關,若每個復原段上活動事務過多可能導緻嚴重的復原段争用。

這 裡說了問題一相關内容,我們再看後面兩個問題。由于復原段的擴充和回收是昂貴代價的操作,通常我們是要避免的。如果存在大的查詢,就算不會去寫復原段,但 是由于一緻讀,我們也可以參照前面内容,知道如果這期間事務繁忙復原段被循環使用覆寫過,可能出現著名的ORA-01555錯誤。又由于事務産生的時候除 非人為指定使用哪個復原段,否則事務使用哪個復原段對于我們應用來說是透明的,同時我們能指定事務使用哪個復原段但并不能阻止别的事務不使用某個復原段, 這樣我們就必須認識到,復原段設定成大小不一緻是不合适的,幾乎是沒有意義的,因為瓶頸總是決定于最小的一個復原段(這類似于木桶原理,決定裝水量的多少 是由最短的片所決定的)。是以我們應該統一復原段的大小。那通常對于一個系統來說,幾百M的磁盤空間甚至幾G的磁盤空間根本不是問題,是以我們沒有理由在 這裡研究復原段到底是使用4M大小還是10M大小,我們根據能提供的磁盤空間的估計,完全可以設定復原段為50M/100M甚至更大的大小,這主要決定于 在大查詢運作期間每個復原段上可能的事務生成量,以及單個事務可能産生的復原資料的大小。假如系統偶爾存在批量作業的時候可能使得某個復原段擴充到1G, 但平常我們的復原段大小在50M就不會出現回縮現象。那這個特定的時候如果資料庫不繁忙隻有大作業我們可以建立幾個很大的復原段,然後是其他復原段 offline,等批作業完成然後再online其他復原段,使大復原段offline。當然可能的話也可以指定批作業使用大的復原段。或者,我們可以為 所有復原段設定optimal為50M,任其特定時刻擴充然後回縮(注意所有復原段的optimal必須設定一樣大小)。

    對于復原段除了按照我們對系統狀況估計進行建立、删除外,還有使復原段聯機和脫機,我們要注意的是如果復原段處于聯機并且裡面有活動事務的時候,若想使回 滾段脫機(offline),則這時復原段處于一種懸置的狀态,也就是新的事務将不能使用該復原段,而原有的事務繼續存在,等待復原段中所有事務完畢後, 復原段成為脫機狀态。

使用manual時,涉及使用的一初始化些參數:

【undo_namanement=manual;】
【rollback_segments=(segment_name[, segment_name]……)
ROLLBACK_SEGMENTS allocates one or more rollback segments by name to this instance. If you set this parameter, the instance acquires all of the rollback segments named in this parameter, even if the number of rollback segments exceeds the minimum number required by the instance (calculated as TRANSACTIONS / TRANSACTIONS_PER_ROLLBACK_SEGMENT).
You cannot change the value of this parameter dynamically, but you can change its value and then restart the instance. Although this parameter usually specifies private rollback segments, it can also specify public rollback segments if they are not already in use.
To find the name, segment ID number, and status of each rollback segment in the database, query the data dictionary view DBA_ROLLBACK_SEGS.
When UNDO_MANAGEMENT is set to AUTO, ROLLBACK_SEGMENTS is ignored.】      

3)建立rollback segment

Creating a Rollback Segment: Example The following statement creates a rollback segment with default storage values in an appropriately configured tablespace:
 
 
CREATE TABLESPACE rbs_ts
   DATAFILE 'rbs01.dbf' SIZE 10M
   EXTENT MANAGEMENT LOCAL UNIFORM. SIZE 100K;

/* This example and the next will fail if your database is in 
   automatic undo mode.
*/
CREATE ROLLBACK SEGMENT rbs_one
   TABLESPACE rbs_ts;
 
 
The preceding statement is equivalent to the following:
 
 
CREATE ROLLBACK SEGMENT rbs_one
   TABLESPACE rbs_ts
   STORAGE
   ( INITIAL 10K
     NEXT 10K
     MAXEXTENTS UNLIMITED );