oracle undo head,淺談Oracle的undo管理

1、什么是undo

當我們對數據執行修改操作時,數據庫會生成undo 信息,這樣一旦執行的事務或語句由於某種原因失敗,或者發出一條ROLLBACK 語句請求回滾,就可以利用這些undo信息將數據放回到修改前的樣子。undo 信息存儲在一組特殊的段中,這稱為undo 段(undo segment)。

select segment_name,tablespace_name,status,block_id,file_id from dba_rollback_segs;

2、undo有什么作用

在Oracle數據庫中,undo主要有三大作用:提供一致性讀(Consistent Read)、回滾事務(Rollback Transaction)以及實例恢復(Instance Recovery)。

2.1、一致性讀(Consistent Read)

一致性讀是相對於臟讀(Dirty Read)而言的。假設某個表T中有10000條記錄,獲取所有記錄需要15分鍾時間。當前時間為9點整,某用戶A發出一條查詢語句:select * from T,該語句在9點15分時執行完畢。當用戶A執行該SQL語句到9點10分的時候,另外一個用戶B發出了一條delete命令,將T表中的最后一條記錄刪除並提交了。那么到9點15分時,A用戶將返回多少條記錄?正確的應該是10000條記錄。很明顯,在 9點鍾那個時間點發出查詢語句時,表T中確實有10000條記錄,只不過由於I/O的相對較慢,所以才會花15分鍾來完成所有記錄的檢索。

這是因為ORACLE通過構造CR(consistent read)塊提供一致讀的方式,保證了數據的完整性。具體的實現方式如下:

用戶在進行查詢時oracle會先記錄當時的SCN號,當查詢讀到被B用戶更新刪除記錄后的塊時,發現這個塊頭部ITL槽中的SCN號比查詢開始時的SCN號大,這樣就會在回滾段中尋找這個塊的前映像數據,找到這個數據的前映像后,把前映像和CURRENT的數據塊進行合並,就形成了一個CR BLOCK,通過查詢CR BLOCK就可以得到一致性的數據。

2.2、回滾事務(Rollback Transaction)

當用戶發出一個update 操作后,會在回滾段中記錄更新記錄的前映像數據,如果用戶再發出rollback命令撤銷數據變化時,Oracle利用記錄在ITL槽里記錄的undo 塊的地址找到該undo塊,然后從中取出變化前的值,並放入數據塊中,從而對事務所作的變化進行回滾。

2.3、實例恢復(Instance Recovery)

實例恢復則是在SMON進程完成前滾並打開數據庫以后發生。SMON進程會去查看undo segment頭部(所謂頭部就是undo segment里的第一個數據塊)記錄的事務表(每個事務在使用undo塊時,首先要在該undo塊所在的undo segment的頭部記錄一個條目,該條目里記錄了該事務相關的信息,其中包括是否提交等),將其中既沒有提交也沒有回滾,而是在實例崩潰時被異常終止的事務全部回滾。

3、回滾段管理方式

oracle的undo管理有兩種方式,自動管理和手動管理,可以使用 undo_management 參數來進行控制。當設置為auto時使用undo表空間的方式來自動管理undo段,如果設置為manual則使用rollback segment方式存儲undo信息。

oracle9i 以后開始使用undo自動管理,手動管理方式只在特殊的場合下才會偶爾使用到。后面在介紹undo恢復時再做相應介紹。

說到自動管理,首先要介紹UNDO_RETENTION參數,這個參數用來指定undo 記錄保存的最長時間,默認為900秒,可以動態的進行修改。這個參數不是指undo中的數據在undo表空間中一定要保存900秒,例如當一個新事務開始的時候,如果發現undo表空間已經被寫滿,則新事務的數據會自動覆蓋已提交事務的數據,而不管這些數據是否已存放夠900秒。同時也不是指undo_retention 中指定的時間一過,已經提交事務中的數據就立刻無法訪問,通常它只是失效,只要沒有被別的事務覆蓋,它就會仍然存在,這時我們可以使用flashback 特性查看表在更新前不同時刻的數據。

因此UNDO表空間中的數據在不同時段就會有不同的狀態顯示,在dba_undo_extents 數據字典里記錄了UNDO中每個區段的狀態.

SQL> SELECT   tablespace_name, status, SUM (bytes) / 1024 / 1024 "Bytes(M)"

FROM   dba_undo_extents

GROUP BY   tablespace_name, status;

TABLESPACE_NAME                STATUS      Bytes(M)

---------------- --------- ----------

UNDOTBS2                       EXPIRED       1.4375

UNDOTBS2                       UNEXPIRED       .375

UNDOTBS2                       ACTIVE          .125

UNDOTBS1                       EXPIRED           22

其中:

ACTIVE :未提交的回滾數據,該數據所關聯的事務並未提交,用於實現讀一致性,所以該數據不能被其它事務的數據所覆蓋 。

UNEXPIRED:已經提交但未過期的回滾數據,該數據關聯的事務已經提交,但是仍受到undo retention參數保持時間的影響,當undo表空間中沒有可用的數據塊時,這些數據塊會直接被覆蓋而進行重用。

EXPIRED: 事務已經提交,而且數據保存時間已經超過undo retention參數指定的時間,屬於已經過期的數據.可以被隨時重用。

需要說明的是,當設置表空間啟動Guarantee特性時,UNEXPIRED類型的塊就必須要等到undo_retention 指定時間過期后才能被重用。

4、undo段的常見問題及維護操作

4.1、Oracle ORA-01555 快照太舊

ORA-01555是oracle中常見的一個錯誤,例如當我們進行的事務需要使用undo數據來構造CR塊的時候,如果對應的undo信息已經被覆蓋時,就會報出ora-01555錯誤。

對於這種情況,通常有以下幾種解決辦法。

1、優化出錯的SQL,減少語句的查詢時間。

2、增加UNDO表空間大小

3、增加undo_retention 時間,默認只有15分鍾

4、避免頻繁的提交

4.2、Oracle ORA-1628 回滾段達到32765最大值

undo表空間自動管理方式下,單個回滾段的最大區數為32765,我們知道一個事務只能使用一個回滾段,當一個大事務在進行大量數據更新時,所使用的回滾段不能完全存放這個事務的前映像數據時, 就可能會出現這種情況,這種情況下只能通過切換undo表空間來排除故障。避免這種故障的根本原因還是要優化相應的SQL語句,減少UNDO塊的產生。

出現ORA-1628故障時至少會有一個回滾段的狀態會顯示為FULL,如下表信息:

SQL> select segment_name,max_extents,status from dba_rollback_segs;

SEGMENT_NAME                   MAX_EXTENTS STATUS

----------------------- ----------- --------

SYSTEM                               32765 ONLINE

_SYSSMU1$                            32765 OFFLINE

_SYSSMU2$                            32765 OFFLINE

_SYSSMU3$                            32765 FULL

_SYSSMU4$                            32765 OFFLINE

_SYSSMU5$                            32765 OFFLINE

_SYSSMU6$                            32765 OFFLINE

4.3、UNDO表空間損壞后的數據恢復

如果數據庫在運行過程中出現undo表空間故障時,通常可以通過在線新建undo表空間,並且切換為默認表空間后就能快速解決故障。假如undo損壞而且數據庫在關閉狀態,如果沒有任何有效的備份時,可以通過修改undo手動管理的方式來啟動數據庫。

這里用一個案例來說明恢復的過程。

系統環境:  oracle 10.2.0.4 非歸檔方式,無有效備份

故障現象:

數據庫無法啟動,alert日志中有大量的ora-600 錯誤

ORA-00600: internal error code, arguments: [2662], [1], [3008810928], [1], [3008849117], [8388617], [], []

ORA-00600: internal error code, arguments: [4194], [15], [6], [], [], [], [], []

Mon May 23 18:36:46 2011

Doing block recovery for file 2 block 336654

Block recovery from logseq 2200, block 63 to scn 7317545555

故障分析:

根據提示信息,可以查到是undo表空間的數據文件出現壞塊造成數據庫無法啟動,因數據庫為非歸檔方式,沒有有效的undo備份文件,這種情況下就可以使用undo手動管理的方式啟動數據庫,詳細可以參考Metalink文章[ID 281429.1] 。

下面是大概的步驟介紹。

1、啟動到nomount 狀態,備份參數文件

2、修改參數文件,undo_management=manual

3、使用新的參數文件啟動數據庫

4、創建新的回滾段

SQL> create rollback segment r01;

5、設置回滾段為online

SQL> alter rollback segment r01 online;

6、創建表空間undotbs2

7、停庫,修改參數為表空間自動管理,

8、重啟啟動數據庫。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值