Oracle-UNDO表空间解读
文章目錄
- UNDO概述
- UNDO數據的作用
- 1,回退事務
- 2,讀一致性
- 3,事務恢復
- 4,閃回查詢(FlashBack Query)
- 數據恢復栗子
- 回滾段著名的ORA-01555問題
- Undo 表空間的兩種管理方式
- 使用 rollback segment
- 使用 Undo 表空間
- undo_retention 和 retention guarantee 參數
- 調優原則
- 相關數據字典
- undo 表空間滿時的處理方法
- 模擬 UNDO 表空間滿的情況
- 解決辦法
- 增加數據文件
- 切換 UNDO 表空間
- undo 表空間損壞的處理方法
- 方法一: 使用 system segment
- 方法二: 跳過損壞的 segment
UNDO概述
官方文檔Managing Undo Tablespaces
UNDO 表空間用于存放UNDO數據,當執行DML操作(INSERT,UPDATE和DELETE)時,oracle會將這些操作的舊數據寫入到UNDO段。
在 oracle9i之前,管理UNDO數據時使用(Rollback Segment)完成的.從oracle9i開始,管理UNDO數據不僅可以使用回滾段,還可以使用UNDO表空間。
10g開始貌似已經不在使用Rollback Segment來管理UNDO數據了,統一使用UNDO表空間。
UNDO數據的作用
1,回退事務
當執行DML操作修改數據時,UNDO數據被存放到UNDO段,而新數據則被存放到數據段中,如果事務操作存在問題,舊需要回退事務,以取消事務變化.
比如:
用戶A執行了語句UPDATE emp SET sal=9999 WHERE empno=7788后發現,應該修改雇員7963的工資,而不是雇員7788的工資,那么通過執行ROLLBACK語句可以取消事務變化.
>update emp a set a.sal=9999 where a.empno=7788; >rollback;當執行ROLLBACK命令時,oracle會將UNDO段的UNDO數據800寫回的數據段中.
2,讀一致性
用戶檢索數據庫數據時,oracle 總是讓用戶只能看到被提交過的數據(讀取提交)或特定時間點的數據(SELECT語句時間點).這樣可以確保數據的一致性.
比如:
當用戶A執行語句 UPDATE emp SET sal=1000 WHERE empno=7788時,UNDO記錄會被存放到回滾段中,而新數據則會存放到EMP段中;假定此時該數據尚未提交,并且用戶B執行SELECT sal FROM emp WHERE empno=7788,此時用戶B將取得UNDO數據 800,而該數據正是在UNDO記錄中取得的.
會話A:
SQL> SELECT sal FROM emp WHERE empno=7369;SAL ---------800.00SQL> UPDATE emp SET sal=1000 WHERE empno=7369;1 row updatedSQL>會話B(在這里我們通過新開一個SQL窗口來模擬) ,如果還是繼續使用會話A,則查詢的仍是1000.
SQL> SELECT sal FROM emp WHERE empno=7369;SAL ---------800.003,事務恢復
事務恢復是例程恢復的一部分,它是由oracle server自動完成的.
如果在數據庫運行過程中出現例程失敗(如斷電,內存故障,后臺進程故障等),那么當重啟oracle server時,后臺進程SMON會自動執行例程恢復,執行例程恢復時,oracl會重新做所有未應用的記錄.回退未提交事務.
4,閃回查詢(FlashBack Query)
倒敘查詢用于取得特定時間點的數據庫數據, 它是9i新增加的特性,假定當前時間為上午09:00,某用戶在上午10:00執行UPDATE emp SET sal= 1000 WHERE empno=7369語句,修改并提交了事務(雇員原工資為800),為了取得10:00之前的雇員工資,用戶可以使用倒敘查詢特征.
Oracle10g閃回查詢特性的增強
Oracle 9i的閃回查詢只能提供某個時間點的數據視圖,并不能告訴用戶這樣的數據經過了幾個事務、怎樣的修改(UPDATE、INSERT、DELETE等),而這些信息在回滾段中是存在的,在Oracle10g中,Oracle進一步加強了閃回查詢的特性,提供了以下兩種閃回查詢:
- 閃回版本查詢(Flashback Versions Query)
- 閃回事務查詢(Flashback Transaction Query)
閃回版本查詢允許使用一個新的VERSIONS子句查詢兩個時間點或者SCN之間的數據版本。這些版本可以按照事務區分,閃回版本查詢只返回提交數據,未提交數據不被顯示。
Oracle10g的閃回版本查詢通過使用VERSIONS子句和對數據表引入一系列的偽列(version_starttime等),可以獲得對數據表的所有事務操作,versions_operation代表不同類型的操作(D-DELETE、I_INSERT、U_UPDATE),VERSIONS_XID是一個重要依據,代表了不同版本的事務ID。
Select versions_starttime,versions_endtime,versions_xid,versions_operation,字段xx From table_name versions between timestamp minvalue and maxvalue;通過以上查詢,根據versions_xid可以清晰地區分不同事務在不同時間對數據所作的更改。
由于這個查詢需要從Undo中獲取前鏡像信息,如果Undo中的信息被覆蓋,則以上查詢將會失敗。
數據恢復栗子
用戶更新了或者誤刪除了一批數據(假設數據量很大),
下面用一條數據做演示:7369工號的原始工資為800 ,更新后工資為1000
UPDATE emp SET sal=1000 WHERE empno=7369;此時用戶想恢復,假設刪除的時間點是2016-11-13 09:00:00 之后,那么我們找到9點之前的 SCN(System Change Number 系統改變號) .
SCN提供了Oracle的內部時鐘機制,可被看作邏輯時鐘,這對于恢復操作是至關重要的.
1.獲得當前SCN
select timestamp_to_scn(to_timestamp('2016-11-13 09:00:00','YYYY-MM-DD HH24:MI:SS')) as scn from dual ; select dbms_flashback.get_system_change_number scn from dual; --查詢當前數據庫的SCN2.將emp表中的scn點的數據取出
select * from emp AS OF SCN 13267939370491;可以看到這個時間點之前的數據 7369是800.
3.然后可以根據這個數據進行還原操作
insert into emp select * from emp AS OF SCN 13267939370491;回滾段著名的ORA-01555問題
從應用角度來看ORA-01555
-
1.查詢執行時間太長。首先是優化查詢,然后考慮在數據塊不繁忙的時候運行,最后考慮加大回滾段。
-
2.過渡頻繁的提交。把能夠成批提交的單條事務改成成批提交
-
3.exp的時候使用而來consistent = y. 這個參數主要是為了保證在exp的時候使得所有的到處的表在時間點上具有一致性,避免存在主外鍵關系的表由于不同的時間點的不一致而破壞了數據的完整性。建議該操作在系統空閑的時候進行。
-
4.由于回滾段回縮導致回滾段還沒有循環使用的情況下就出現了回滾段中找不著數據的情況。只能加大回滾段增大optimal設置。
Undo 表空間的兩種管理方式
Oracle 的 Undo 有兩種方式: 一是使用 undo 表空間,二是使用回滾段.
我們通過 undo_management 參數來控制使用哪種方式,
如果設為 auto, 就使用 UNDO 表空間,這時必須要指定一個 UNDO 表空間。
如果設為 manual,系統啟動后使用 rollback segment 方式存儲 undo 信息。
SQL> show parameter undoNAME TYPE VALUE ------------------------------------ ----------- ------------------------------ undo_management string AUTO undo_retention integer 900 undo_tablespace string UNDOTBS1SQL>Undo配置參數含義
-
UNDO_MANAGEMENT undo的管理模式,分自動和手動
-
UNDO_TABLESPACE 當前正在被使用的undo表
-
UNDO_RETENTION 規定多長時間內,數據不能被覆蓋。
-
AUTO 表示undo 為自動管理模式。
-
900 表示在900秒內,undo上的數據不能被覆蓋。
-
UNDOTBS1 是當前正在使用的undo表空間
如果系統沒有指定 undo_management,那么系統默認以 manual 方式啟動,即使設置了 auto 方式的參數,這些參數將被忽略。
當實例啟動的時候,系統自動選擇第一個有效的 undo 表空間或者是 rollback
segment, 如果沒有有效的可用的 undo 表空間或者是回滾段,系統使用 system rollback segment。這種情況是不被推薦的,當系統運行在沒有 undo 的情況下,系統會在 alert.log 中記錄一條警告信息。
使用 rollback segment
當 undo_management 被設置成 MENUAL 時使用系統回滾段, 即將 undo records 記錄到 SYSTEM 表空間下的 SYSTEM 段。
select segment_name,tablespace_name,bytes,next_extent from dba_segments where segment_type='ROLLBACK';通過上面的這條語句,我們查到了這個用于 rollback 的 system segment 存在
與 system 表空間。 默認情況下,只有一個 segment,并且它還比較小, 所以,如果使用 system 段來存儲 undo records,肯定會影響數據庫的性能。 所以 Oracle是建議使用 Undo tablespace 來管理 undo records。
使用 Undo 表空間
當 undo_management 設置成 AUTO 時使用 UNDO tablespace 來管理回滾段這個時候,我們將有多個 undo segment,并且這些 segment 是存放在 UNDO 表空間里的, 這樣對 DB 的性能就會提高。
select segment_name,tablespace_name,bytes,next_extent from dba_segments where segment_type='TYPE2 UNDO';目前我們的這個數據庫已經有58個undo segment了。默認的好像是10個。
除了通過dba_segment 表查看的結果, 也可以通過 vrollstat和vrollstat 和 vrollstat和vrollname 兩個視圖來查看信息, 這 2 個視圖會顯示所有 rollback 段的信息,包括 system 段和 undo 段。
select s.usn,n.name,s.extents,s.hwmsize,s.status from v$rollstat s, v$rollname n where s.usn=n.usn;undo_retention 和 retention guarantee 參數
使用如下SQL 來查看 undo 表空間里空閑和非空閑比例:
SELECT tablespace_name, status, SUM (bytes) / 1024 / 1024 "Bytes(M)" FROM dba_undo_extentsGROUP BY tablespace_name, status;UNEXPIRED 和 EXPIRED 是已使用的 undo 表空間,
其中 expired 說明是已經過期的數據,也就是 15 分鐘(默認情況)以外的數據,已經被覆蓋, 可以認為是空閑的。
在這里就關系到一個參數: UNDO_RETENTION, 該參數用來指定 undo 記錄保存的最長時間,以秒為單位,是個動態參數,完全可以在實例運行時隨時修改,通常默認是 900 秒,也就是 15 分鐘。
如下所示:
SQL> show parameter undoNAME TYPE VALUE ------------------------------------ ----------- ------------------------------ undo_management string AUTO undo_retention integer 900 undo_tablespace string UNDOTBS1SQL>undo_retention 只是指定 undo 數據的過期時間,并不是說, undo 中的數據一定會在 undo 表空間中保存 15 分鐘,比如說剛一個新事務開始的時候,如果undo 表空間已經被寫滿, 則新事務的數據會自動覆蓋已提交事務的數據,而不管這些數據是否已過期,
因此呢,這就又關聯回了第一點,當你創建一個自動管理的 undo 表空間時,還要注意其空間大小,要盡可能保證 undo 表空間有足夠的存儲空間。
undo_retention 中指定的時間一過,已經提交事務中的數據就立刻無法訪問,它只是失效,只要不被別的事務覆蓋,它會仍然存在,并可隨時被 flashback 特性引用。
如果你的 undo 表空間足夠大,而數據庫又不是那么繁忙,那么其實undo_retention 參數的值并不會影響到你,哪怕你設置成 1,只要沒有事務去覆蓋 undo 數據,它就會持續有效。 總之, 要注意 undo 表空間的大小,保證其有足夠的存儲空間。
只有在一種情況下, undo 表空間能夠確保 undo 中的數據在undo_retention指定時間過期前一定有效,就是為 undo 表空間指定 Retention Guarantee,指定之后, oracle 對于 undo 表空間中未過期的 undo 數據不會覆蓋.
例如:
SQL> Alter tablespace undotbs1 retention guarantee;禁止 undo 表空間 retention guarantee
總結:
-
UNDO 表空間是會被重用的,只有當事務沒結束,或開了 retention guarantee, 或在 undo_retention時間內不能被重用。
-
在 undo_retention 規定的時間內,數據都是有效的,過期后都會設為無效, 狀態被改為 Expired,這些回滾段將會被看作Free Space。但是只要數據沒有被覆蓋就可以使用。
-
如果空間已滿,新事務的數據會自動覆蓋掉已經提交的事務數據,即使在 undo_retention 的時間內。除非指定 Retention
Guarantee 模式,才能保證在 undo_retention 內不被覆蓋。
調優原則
關于oracle UNDO表空間自動管理自動調優的原則介紹,在Oracle 10gr2后面的版本中添加了UNDO信息最短保留時間段自動調優的特性,不再僅僅依據參數UNDO_RETENTION的設定,其調優原則如下:
1 當UNDO TABLESPACE為 fixed-size,Oracle將根據表空間的大小和歷史使用情況,自動調整undo信息保存時間,同時忽略 undo_retention的值除非 undo_retention的guarantee 特性被啟用。
2 當UNDO TABLESPACE為AUM時,Oracle將動態調整撤銷信息最短保留時間為該時段最長查詢時間(MAXQUERYLEN)加上300秒或參數UNDO_RETENTION間的較大者,即MAX((MAXQUERYLEN+300),UNDO_RENTION);
在自動調整啟用的情況下,實際的撤銷信息最短保留時間可以通過查詢V$UNDOSTAT視圖上的TUNED_UNDORETENTION列獲得。往往最短保存時間遠遠大于設定的UNDO_RETENTION。在無法就UNDO TABLESPACE做相應修改的情況,可以通過修改隱式參數”_UNDO_AUTOTUNE”為FALSE關閉該自動調優特性。以上設定生效后,V$UNDOSTAT視圖上TUNED_UNDORETENTION列不再更新,且撤銷信息最短保留時間固定為參數UNDO_RETENTION的設定值。該參數可以不用重啟數據庫而動態設置生效。
UNDO自動優化功能能夠最大限度的使用undo表空間,滿足大部分的sql執行,但是也帶來一個問題:很多事務執行完畢之后,發現UNDO表空間會在很長時間都一直保持著使用率是接近100%的狀態,active 狀態的很少。
這種接近狀態還無法手工的收縮,甚至于重啟數據庫實例也無法緩解,而此時常常會收到undo表空間的監控報警。
可以通過修改隱式參數”_UNDO_AUTOTUNE”為FALSE關閉該自動調優特性。以上設定生效后,V$UNDOSTAT視圖上TUNED_UNDORETENTION列不再更新,且撤銷信息最短保留時間固定為參數UNDO_RETENTION的設定值。該參數可以不用重啟數據庫而動態設置生效。
> alter system set "_undo_autotune"=false; System altered.禁用UNDO自動優化之后,Oracle不再的每十分鐘記錄一次當前UNDO使用情況了,在動態視圖V$UNDOSTAT中也只保留禁止undo自動調優之前的數據 。 .一般不建議關閉Oracle的自動調優
相關數據字典
| v$undostat | 包含所有undo表空間的統計信息,用于對undo表空間進行監控和調整。通過該視圖,可以估計當前undo表空間的大小,Oracle利用該視圖完成對回退信息的自動管理,該視圖數據是有最近4天內,每10分鐘產生一條統計記錄構成的。 |
| v$rollstat | 包含undo表空間中回退段的性能統計信息 |
| v$transaction | 包含事務所使用的回退段信息 |
| dba_undo_extents | 包含undo表空間中區的大小與狀態信息 |
| dba_hist_undostat | 包含v$undostat的快照,主要是4天前的統計信息 |
undo表空間中區的狀態一共有3種:EXPIRED、UNEXPIRED、ACTIVE。
-
EXPIRED:表示該回退信息對應的事務已經提交,保存時間超過保留區;
-
UNEXPIRED:表示該回退信息對應的事務已經提交,保存時間沒有超過保留區;
-
ACTIVE:表示回退信息對應的事務還沒有提交,該區還在使用;
undo 表空間滿時的處理方法
默認情況下的 Undo_retention 只有 15 分鐘,這個默認值,一般都無法滿足
系統的需求。 一般建議是改成 3 個小時, 這樣給萬一的情況,多爭取一些時間。
當然, undo_retention 設置的越大,所需要的 undo tablespace 也就越大。 這個需要結合自己的系統來設置這個參數。
模擬 UNDO 表空間滿的情況
SQL> create undo tablespace undo datafile '/oradata/undo.dbf' size 1m; 表空間已創建。 SQL> alter tablespace undo retention guarantee; 表空間已更改。 SQL> alter system set undo_tablespace=undo; 系統已更改。 SQL> create table DBA(id number); 表已創建。 SQL> begin 2 for i in 1 .. 100000 loop 3 insert into dba values(i); 4 commit; 5 end loop; 6 end; 7 / begin * 第 1 行出現錯誤: ORA-30036: 無法按 8 擴展段 (在還原表空間 'UNDO' 中) ORA-06512: 在 line 3解決辦法
處理方法有兩種,
- 一是添加 undo 表空間的數據文件,
- 二是切換 UNDO tablespace. 這種情況下多用在 undo 表空間已經非常大的情況。
增加數據文件
SQL> ALTER TABLESPACE undo ADD DATAFILE '/oradata/undo2.dbf' size 100M reuse; 表空間已更改。 SQL> begin 2 for i in 1..100000 loop 3 insert into dba values(1); 4 commit; 5 end loop; 6 end; 7 / PL/SQL 過程已成功完成。切換 UNDO 表空間
1、 建立新的表空間 UNDOTBS2
SQL> CREATE UNDO TABLESPACE UNDOTBS2 DATAFILE '/oradata/und3.dbf' size 100M reuse; 表空間已創建。2、 切換到新建的 UNOD 表空間上來,操作如下
SQL> alter system set undo_tablespace=UNDOTBS2 scope=both; 系統已更改。3、將原來的 UNDO 表空間,置為脫機:
SQL> alter tablespace UNDO offline; 表空間已更改。4、刪除原來的 UNDO 表空間:
SQL> drop tablespace UNDO including contents AND DATAFILES CASCADE CONSTRAINTS ; 表空間已刪除。如果只是 drop tablespace UNDO ,則只會在刪除控制文件里的記錄,并不會物理刪除文件。
Drop undo 表空間的時候必須是在未使用的情況下才能進行。如果 undo 表空間正在使用(例如事務失敗,但是還沒有恢復成功),那么 drop 表空間命令將失敗。在 drop 表空間的時候可以使用 including contents。
undo 表空間損壞的處理方法
出現 undo 損壞的情況, 大多數是因為異常宕機,在啟動的時候報的錯誤,DB 不能啟動。
比如: ORA-00600: internal error code, arguments: [4194]
當 alert log 里出現 ORA-600 + [4194] 時,基本就可以斷定,是 undo 表空間出現了損壞。 對于 Undo 損壞的情況,能用備份恢復最好,如果不能,就只能通過一些特殊的方法來恢復。
方法一: 使用 system segment
當我們使用 undo 表空間出現損壞時,可以先用 system segment 啟動 DB,
啟動之后,在重新創建 UNDO 表空間,在用 undo 來啟動。 步驟如下:
( 1) 用 spfile 創建 pfile,然后修改參數:
#*.undo_tablespace='UNDOTBS1' #*.undo_management='AUTO' #*.undo_tablespace #*.undo_retention undo_management='MANUAL' rollback_segments='SYSTEM'如何通過SPFILE創建PFILE?
SQL> shutdown immediate 數據庫已經關閉。 已經卸載數據庫。 ORACLE 例程已經關閉。 SQL> create pfile from spfile; 文件已創建。pfile文件-linux等平臺在ORACLEHOME/dbs下,Oralce在啟動實例的時讀取‘ORACLE_HOME/dbs下, Oralce在啟動實例的時讀取`ORACLEH?OME/dbs下,Oralce在啟動實例的時讀取‘ORACLE_HOME/dbs`下面的初始化文件。
( 2)用修改之后的 pfile,重啟 DB
SQL> STARTUP MOUNT pfile='F:\initorcl.ora' ;( 3)刪除原來的表空間,創建新的 UNDO 表空間
SQL> drop tablespace undotbs; SQL> create undo tablespace undotbs1 datafile '/u01/oradata/undotbs1.dbf' size 10M;( 4)關閉數據庫,修改 pfile 參數,然后用新的 pfile 創建 spfile,在正常啟動數據庫。
*.undo_tablespace='UNDOTBS1' *.undo_management='AUTO' #undo_management='MANUAL' #rollback_segments='SYSTEM'創建SPFILE
SQL> CREATE SPFILE=$ORACLE_HOME/dbs/spfileSID.ora FROM PFILE $ORACLE_HOME/dbs/initSID.ora若都使用默認的,則可簡寫為:
SQL> CREATE SPFILE FROM PFILE; SQL> show parameter spfileNAME TYPE VALUE ------------------------------------ ----------- ------------------------------ spfile string /oracle/product/112/dbs/spfilecc.ora方法二: 跳過損壞的 segment
在方法一里面,我們使用了 system segment。 通過前面的說明, 我們了解到,undo segment 有多個,我們可以通過 alert log 來查看正在使用的是哪些 segment,這些段有可能損壞了。 我們只需要把這些損壞的 segment 跳過,先正常啟動 DB,在創建新的 UNDO 表空間,在切換一下。
( 1)修改 pfile,添加參數:
*._corrupted_rollback_segments='_SYSSMU11$','_SYSSMU12$','_SYSSMU13$'這些字段的值, 我們通過 alert log 查看。 也可以通過如下命令查看:
#strings system01.dbf | grep _SYSSMU | cut -d $ -f 1 | sort -u( 2)用修改之后的 pfile 啟動 DB
因為跳過了哪些損壞的 segment,所以 DB 可以正常啟動。
( 3)創建新的 UNDO 表空間,并切換過來
( 4)修改 pfile,創建 spfile,并正常啟動
刪除:
*._corrupted_rollback_segments='_SYSSMU11$','_SYSSMU12$','_SYSSMU13$'總結
以上是生活随笔為你收集整理的Oracle-UNDO表空间解读的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle-SYSAUX表空间解读
- 下一篇: Oracle-数据字典解读