一、回退段介紹
在Oracle數據庫中,當某個事物對數據進行修改時,Oracle首先將數據的原始值保存到一個回退段中。一個事物只能將它的回退信息保存到一個回退段中,而多個並行事物可以使用同一個回退段。
(1)回退段的作用
回退段主要有4個作用,分別是:事物回滾、數據庫恢復、讀一致性、閃回查詢。
--事物回滾:當事物執行失敗或用戶執行回滾操作(rollback)時,Oracle會利用保存在回退段中的信息將數據恢復到原來的值;
--數據庫恢復:當數據庫實例運行失敗,在數據庫重啟恢復時,Oracle先利用重做日志文件的信息對數據庫進行恢復(包括已提交和未提交的事務),再利用回滾段中的信息回滾未提交的事務;
--讀一致性:當一個用戶對數據進行修改時,會預先將其原始值保存到回退段中,這時,如果有其它用戶訪問該數據,則訪問回退段中的信息,使當前用戶未提交的修改其他用戶無法看到,保證了數據的一致性;
--閃回查詢:通過保留在回退段中的信息,用戶可以查詢某個數據在過去某個時刻的狀態
(2)回退段的工作方式
當事務開始時,系統分配給該事物一個回退段,在事務的整個生命周期中,當數據發生改變時,數據的原始值被復制到回退段中。回退段采用循環寫的方式進行工作,當事務寫滿回退段的一個區之后,會接着寫入回退段的下一個區,當所有的區都寫滿后,事務開始循環寫入到第一個區或者分配新的區(datafile為autoextend)。回退段歸用戶sys所有,每個回退段至少包含2個區。
二、回退表空間的管理
(1)創建undo表空間
在Oracle 11g中,創建undo tablespace有2種方法,一種是在創建數據庫時創建undo tablespace,另一種是使用create undo tablespace來創建undo tablespace。undo tablespace用來保存事務的回退信息,用戶不能在其中創建數據庫對象。
我們這里介紹如何使用craete undo tablespace 來創建undo表空間。
--使用create undo tablespace
CREATE [BIGFILE | SMALLFILE] UNDO TABLESPACE tbs_name DATAFILE 'path/filename' SIZE integer [K | M] [REUSE] [AUTOEXTEND] [OFF | ON] NEXT integer [K | M] MAXSIZE [UNLIMITED | integer [K | M] ] [EXTENT MANAGEMENT LOCAL] [AUTOALLOCATE] [RETENTION GUARANTEE | NOGUARANTEE]
(2)修改undo表空間
可以使用alter tablespace修改undo表空間,允許對undo表空間進行如下操作:
--添加undo表空間的數據文件;
--重命名undo表空間的數據文件;
--將undo表空間的數據文件聯機或脫機;
--啟用或禁用保護回退信息在回退段中的保留時間;
例子1、當undo表空間容量不足時,可以考慮增加新的數據文件或改變數據文件的大小
--為undo tablespace添加新的數據文件 alter tablespace undotbs1 add datafile '/home/app/oracle/oradata/orcl/untbs02.dbf' size 50M; --將undo tablespace里面的untbs02.dbf文件擴充為100M alter database datafile '/home/app/oracle/oradata/orcl/untbs02.dbf' resize 100M;
(3)刪除undo表空間
與普通表空間一樣,可以使用drop tablespace來刪除undo表空間,但是不能刪除當前正在使用的undo表空間。如果在undo表空間中含有任何未提交的事務的回退信息,則不能使用drop tablespace來刪除表空間。此外,即使已經使用drop tablespace刪除了undo表空間,在該表空間中也可能存在未過期的回退信息,這樣導致某些查詢所需的回退信息丟失。因此,在刪除時應該注意,不要刪除這樣的undo表空間。
(4)切換undo表空間
在數據庫運行過程中,可以從一個undo表空間切換到另一個undo表空間,由於初始化參數undo_tablespace是一個動態參數,直接修改即可,無需重啟實例,切換方式如下:
ALTER SYSTEM SET UNDO_TABLESPACE = undotbs_name
在以下情況,undo表空間切換會發生錯誤:
--指定的undo表空間不存在;
--指定的表空間不是undo表空間;
--指定的undo表空間正在被其它實例使用;
在完成undo表空間的切換后,任何新的事物的回退信息都會進入新的undo表空間中,如果舊的undo表空間還存在未提交的事務,則舊的undo表空間進入“掛起脫機狀態”,“掛起脫機狀態”的undo表空間不能被新的事務使用,也不能刪除,當前未提交的事務將繼續使用該表空間。當所有事務都提交完成后,舊的undo表空間進入脫機狀態。
例子2、切換undo表空間
--切換undo表空間 --實驗目的:
-- 1.學會切換undo表空間
-- 2.學會刪除undo表空間 12:40:16 SQL> show parameter undo_tablespace --【窗口1】查看當前undo表空間 NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ undo_tablespace string UNDOTBS1 12:45:59 SQL> insert into dept values(50,'a','b'); --【窗口1】執行一條insert語句,且不提交 1 row inserted SQL> alter system set undo_tablespace = UNDOTNS2; --【窗口2】切換undo表空間 System altered SQL> show parameter undo_tablespace; --【窗口2】查看新的表空間 NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ undo_tablespace string UNDOTNS2 SQL> drop tablespace undotbs1 including contents and datafiles; --【窗口2】刪除舊的表空間,報錯,提示舊的表空間正在使用 ORA-30013: undo tablespace 'UNDOTBS1' is currently in use 12:53:02 SQL> commit; --【窗口1】提交事務 SQL> drop tablespace undotbs1 including contents and datafiles; --【窗口2】過一段時間之后,成功刪除 Tablespace dropped
(5)回退信息保留時間
前面我們講了回退信息的4個作用,當我們提交了事務之后,回退信息對於事務回滾以及數據庫恢復已經不再起作用。但是,對於一個長事務而言,具有讀一致性的作用,保證查詢到的信息一直是舊的信息。此外,數據庫的各種閃回操作的實現也需要回退段中的信息。Oracle根據undo表空間的大小以及事物量的多少自動調整回退信息的保留時間,可通過調整初始化參數undo_retention設置回退信息在回退段中的保留時間:
-- 將回退信息的保留時間設置為1800s SQL > ALTER SYSTEM SET UNDO_RETENTION = 1800 ;
需要注意的是,undo_retention是Oracle的一個”軟設置“,這個”軟設置“如何理解呢?例如,當用戶將UNDO_RETENTION參數設置為1800s后,Oracle會盡量的將回退信息保存1800s,但是,在這個過程中,如果回退表空間不夠用了,新的回退信息依然會將未達到1800s的回退信息覆蓋。
為了保證長時間的查詢的讀一致性以及各種閃回操作,我們也可以指定回退信息必須保留到undo_retention規定的時間,通過啟用undo表空間的retention guarantee特性,保證只有過期(已提交且達到undo_retention設定的值)的數據才會被覆蓋,即使undo表空間容量已經不足,也不會覆蓋未過期的回退信息。
--啟用retention_guarantee SQL > ALTER TABLESPACE UNDOTBS1 RETENTION GUARANTEE;
三、查詢undo表空間
與undo表空間相關的數據字典如下:
數據字典 | 解釋 |
v$undostat | 包含所有undo表空間的統計信息,用於對undo表空間進行監控和調整。 通過該視圖,可以估計當前undo表空間的大小,Oracle利用該視圖完成對回退信息的自動管理,該視圖數據是有最近4天內,每10分鍾產生一條統計記錄構成的。 |
v$rollstat | 包含undo表空間中回退段的性能統計信息 |
v$transaction | 包含事務所使用的回退段信息 |
dba_undo_extents | 包含undo表空間中區的大小與狀態信息 |
dba_hist_undostat | 包含v$undostat的快照,主要是4天前的統計信息 |
例子3、查詢undo表空間中回退信息的當前狀態
SQL> select tablespace_name,segment_name,extent_id,status from dba_undo_extents; TABLESPACE_NAME SEGMENT_NAME EXTENT_ID STATUS ------------------------------ ------------------------------ ---------- --------- UNDOTBS3 _SYSSMU10_968665341$ 0 UNEXPIRED UNDOTBS3 _SYSSMU10_968665341$ 1 EXPIRED UNDOTBS3 _SYSSMU9_3484649867$ 0 UNEXPIRED UNDOTBS3 _SYSSMU9_3484649867$ 1 EXPIRED ... ... ... ...
undo表空間中區的狀態一共有3種:EXPIRED、UNEXPIRED、ACTIVE。
--EXPIRED:表示該回退信息對應的事務已經提交,保存時間超過保留區;
--UNEXPIRED:表示該回退信息對應的事務已經提交,保存時間沒有超過保留區;
--ACTIVE:表示回退信息對應的事務還沒有提交,該區還在使用;