6. Oracle 復原(ROLLBACK)和撤銷(UNDO)

來源:互聯網
上載者:User

標籤:username   nts   tns   orm   lstat   form   資料表空間   delete   最大   

轉載自:http://blog.csdn.net/leshami/article/details/5731158

 

一、復原(ROLLBACK)和撤銷(UNDO)

復原和前滾是保證Oracle資料庫中的資料處於一致性狀態的重要手段。--在9i版本以前    Oracle使用資料庫中的復原段來實現未提交資料或因系統故障導致執行個體崩潰時進行復原操作    每一個資料表空間需要建立復原段,各個資料表空間對復原段實現各自的管理--在9i及後續版本    提供了一種新的復原資料的管理方式,即使用Oracle自動管理的撤銷(Undo)資料表空間    自動撤銷管理資料表空間統一管理所有DML的復原操作,簡化了對於復原工作的管理    在9i,10g中的復原段僅僅用作保留向後相容    撤銷段代替了原有版本中的復原段,因此本文所有描述均使用撤銷撤銷的實質意味著將所作的修改退回到修改前的狀態,即倒退所有DML語句

二、撤銷段中的內容及相關特性

對於任何DML操作而言,必須同時處理資料區塊和撤銷塊,並且還會產生重做資訊在ACID中,A、C、I要求產生撤銷,D則要求產生重做INSERT:撤銷段記錄插入記錄的rowid,如果需要撤銷,則根據rowid將該記錄刪除即可UPDATE: 撤銷段記錄被更新欄位的原始值,撤銷時將原始值覆蓋新值即可DELETE:撤銷段記錄整行的資料,撤銷時執行反向操作將該記錄插入原表--由上可知,UNDO段中的內容總結如下:資料為修改之前的副本從每個改變資料的事務中獲得在事務結束前一直被保留--UNDO段中資料的作用:用於復原操作讀一致性和閃回查詢用於事務失敗時的恢複    --UNDO段與事務:一個事物的啟動,Oracle將為其分配僅僅一個UNDO段,若該段用完,則Oracle會自動為該UNDO段添加另一個區間(extent)一個UNDO段能夠同時為多個事務服務    --UNDO段與UNDO資料表空間:UNDO段中的內容儲存在UNDO資料表空間任意給定時刻只能使用一個UDNO資料表空間UNDO資料表空間必須被建立為持久的、本地管理、可自動擴充的資料表空間正在使用的UNDO資料表空間不能撤銷或刪除UNDO資料表空間使用迴圈寫的方式,與聯機記錄檔寫相似,不同的是UNDO中可以設定了undo_retention 保留時間--UNDO段的兩種管理方式:AUTO    自動管理(推薦)MANUAL  手動管理(僅保留)

三、與撤銷相關的幾個參數

--查看本機中Oracle的版本SQL> SELECT * FROM v$version;BANNER----------------------------------------------------------------Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - ProdPL/SQL Release 10.2.0.1.0 - ProductionCORE    10.2.0.1.0      ProductionTNS for Linux: Version 10.2.0.1.0 - ProductionNLSRTL Version 10.2.0.1.0 - Production--查看和UNDO相關的參數SQL> SHOW PARAMETER undo;NAME                                 TYPE        VALUE------------------------------------ ----------- ------------------------------undo_management                      string      MANUALundo_retention                       integer     900undo_tablespace                      string      UNDOTBS1        --undo_management:設定資料庫的撤銷段是否使用自動管理員模式,值可以為auto或manual,當為manual時將不使用撤銷段,即不使用自動管理員模式該參數為靜態參數,修改後需重啟執行個體才會生效    --undo_retention:指定撤銷段資料在undo段中為非使用中後被覆蓋前保留的時間,單位為秒。在undo_management位auto時生效,為動態參數    --undo_tablespace:指定使用哪個資料表空間來實現資料的撤銷,在undo_management位auto時生效,為動態參數    --retention guarantee子句:保證撤銷保留,使用下面的操作來實現ALTER TABLESPACE undo_tablespace_name RETENTION GUARANTEE;--下面的查詢中是當undo_management為manual時的結果集,可以看出撤銷資料表空間的撤銷段都處於offline狀態    SQL> SELECT segment_name,tablespace_name,status FROM dba_rollback_segs;SEGMENT_NAME                   TABLESPACE_NAME                STATUS------------------------------ ------------------------------ ----------------SYSTEM                         SYSTEM                         ONLINE_SYSSMU1$                      UNDOTBS1                       OFFLINE_SYSSMU2$                      UNDOTBS1                       OFFLINE_SYSSMU3$                      UNDOTBS1                       OFFLINE_SYSSMU4$                      UNDOTBS1                       OFFLINE_SYSSMU5$                      UNDOTBS1                       OFFLINE_SYSSMU6$                      UNDOTBS1                       OFFLINE_SYSSMU7$                      UNDOTBS1                       OFFLINE_SYSSMU8$                      UNDOTBS1                       OFFLINE_SYSSMU9$                      UNDOTBS1                       OFFLINE_SYSSMU10$                     UNDOTBS1                       OFFLINE--在undo_management 參數為manual時,對scott.emp插入一條新記錄,收到了錯誤提示--非系統資料表空間不能夠使用復原段SQL> INSERT INTO scott.emp(empno,ename,salary) VALUES(6666,‘Jenney‘,3000);INSERT INTO scott.emp(empno,ename,salary)                  *ERROR at line 1:ORA-01552: cannot use system rollback segment for non-system tablespace ‘USERS‘--查看段的類型,發現僅僅system資料表空間存在ROLLBACK 段,所以前一條插入語句收到錯誤提示SQL> SELECT DISTINCT segment_type,tablespace_name FROM dba_segments ORDER BY tablespace_name;SEGMENT_TYPE       TABLESPACE_NAME------------------ ------------------------------INDEX              EXAMPLEINDEX PARTITION    EXAMPLELOBINDEX           EXAMPLELOBSEGMENT         EXAMPLENESTED TABLE       EXAMPLETABLE              EXAMPLETABLE PARTITION    EXAMPLEINDEX              SYSAUXINDEX PARTITION    SYSAUXLOB PARTITION      SYSAUXLOBINDEX           SYSAUXLOBSEGMENT         SYSAUXNESTED TABLE       SYSAUXTABLE              SYSAUXTABLE PARTITION    SYSAUXCLUSTER            SYSTEMINDEX              SYSTEMLOBINDEX           SYSTEMLOBSEGMENT         SYSTEMNESTED TABLE       SYSTEMROLLBACK           SYSTEM       --與之前的版本相容的復原段TABLE              SYSTEMTABLE              TBS1TYPE2 UNDO         UNDOTBS1     --9i之後使用的撤銷段INDEX              USERSLOBINDEX           USERSLOBSEGMENT         USERSNESTED TABLE       USERSTABLE              USERS--下面將undo_management改為支援自動管理,需要重啟執行個體SQL> ALTER SYSTEM SET undo_management = ‘auto‘ SCOPE = SPFILE;System altered.SQL> SHUTDOWN IMMEDIATE;Database closed.Database dismounted.ORACLE instance shut down.SQL> STARTUP;ORACLE instance started.Total System Global Area  251658240 bytesFixed Size                  1218796 bytesVariable Size              67110676 bytesDatabase Buffers          180355072 bytesRedo Buffers                2973696 bytesDatabase mounted.Database opened.--再次查看dba_rollback_segs視圖所有的撤銷段全部處於online狀態--注意第一行為system資料表空間的撤銷段,用於系統資料表空間的撤銷SQL> SELECT segment_name,tablespace_name,status FROM dba_rollback_segs;SEGMENT_NAME                   TABLESPACE_NAME                STATUS------------------------------ ------------------------------ ----------------SYSTEM                         SYSTEM                         ONLINE  _SYSSMU1$                      UNDOTBS1                       ONLINE_SYSSMU2$                      UNDOTBS1                       ONLINE_SYSSMU3$                      UNDOTBS1                       ONLINE_SYSSMU4$                      UNDOTBS1                       ONLINE_SYSSMU5$                      UNDOTBS1                       ONLINE_SYSSMU6$                      UNDOTBS1                       ONLINE_SYSSMU7$                      UNDOTBS1                       ONLINE_SYSSMU8$                      UNDOTBS1                       ONLINE_SYSSMU9$                      UNDOTBS1                       ONLINE_SYSSMU10$                     UNDOTBS1                       ONLINE--由上面的樣本可知:ROLLBACK 段:      --與之前的版本相容的復原段TYPE2 UNDO 段:    --9i之後使用的撤銷段關於復原,一個時刻僅能使用一種類段類型,即要麼使用與以前版本相容的復原段,要麼使用撤銷段事實上,在9i之後僅僅支援撤銷段,從上面錯誤的提示即可證實--查看DML語句產生的事務SQL> SHOW USER;                                    USER is "SYS"SQL> SELECT * FROM scott.emp WHERE ename = ‘SCOTT‘;     EMPNO ENAME           JOB              MGR HIREDATE      SALARY     DEPTNO---------- --------------- --------- ---------- --------- ---------- ----------      7788 SCOTT           ANALYST         7566 19-APR-87       3500         20      SQL> UPDATE scott.emp SET sal = sal * 2 WHERE  ename = ‘SCOTT‘;1 row updated.SQL> SELECT addr,xidusn,status,start_time,used_ublk FROM v$transaction;ADDR         XIDUSN STATUS           START_TIME            USED_UBLK-------- ---------- ---------------- -------------------- ----------2DA2B17C          9 ACTIVE           07/10/10 20:29:08             1--查看當前哪些使用者使用撤銷段以及段的大小,啟動時間,活動狀態等SQL> SELECT t.xidusn,t.start_time,t.used_ublk,t.status, s.username,r.segment_name FROM v$transaction t     JOIN v$session s ON t.ses_addr = s.saddr JOIN dba_rollback_segs r ON r.segment_id = t.xidusn ;    XIDUSN START_TIME            USED_UBLK STATUS           USERNAME                       SEGMENT_NAME---------- -------------------- ---------- ---------------- ------------------------------ -------------         9 07/10/10 20:29:08             1 ACTIVE           SYS                            _SYSSMU9$    

 四、UNDO資料表空間的建立與管理 

--建立UNDO資料表空間建立文法:CREATE UNDO TABLESPACE tablespace_name DATAFILE ‘...‘ SIZE n更多資料表空間的建立:請參照:Oracle 資料表空間與資料檔案 --切換UNDO資料表空間  執行個體中允許多個UNDO資料表空間存在可以從一個UNDO資料表空間切換到另外一個UNDO資料表空間任一時刻只能有一個UNDO資料表空間被指定使用ALTER SYSTEM SET undo_tablespace = undo_tablespace_name實現切換    --刪除UNDO資料表空間DROP TABLESPACE undo_tablespace_name任意執行個體的UNDO資料表空間在非使用中可以刪除對於活動狀態的UNDO資料表空間,應當先將切換到其它資料表空間,在所有事務完成後再刪除該資料表空間    --示範建立、切換及刪除UNDO資料表空間--查看當前系統中的資料表空間    SQL> SELECT file_name,tablespace_name FROM dba_data_files;FILE_NAME                                                    TABLESPACE_NAME------------------------------------------------------------ ------------------------------/u01/app/oracle/oradata/orcl/tbs1_2.dbf                      TBS1/u01/app/oracle/oradata/orcl/tbs1_1.dbf                      TBS1/u01/app/oracle/oradata/orcl/example01.dbf                   EXAMPLE/u01/app/oracle/oradata/orcl/users01.dbf                     USERS/u01/app/oracle/oradata/orcl/sysaux01.dbf                    SYSAUX/u01/app/oracle/oradata/orcl/undotbs01.dbf                   UNDOTBS1/u01/app/oracle/oradata/orcl/system01.dbf                    SYSTEM--建立一個新的UNDO資料表空間undo2SQL> CREATE UNDO TABLESPACE undo2 DATAFILE ‘/u01/app/oracle/oradata/orcl/undotbs02.dbf‘ SIZE 3M AUTOEXTEND ON;Tablespace created.SQL> SELECT file_name,tablespace_name FROM dba_data_files WHERE tablespace_name LIKE ‘UNDO%‘;FILE_NAME                                                    TABLESPACE_NAME------------------------------------------------------------ ------------------------------/u01/app/oracle/oradata/orcl/undotbs01.dbf                   UNDOTBS1/u01/app/oracle/oradata/orcl/undotbs02.dbf                   UNDO2--查看當前系統使用的UNDO資料表空間為UNDOTBS1SQL> SELECT name,value FROM v$parameter WHERE name LIKE ‘undo%‘;NAME                           VALUE------------------------------ --------------------------------------------------undo_management                AUTOundo_tablespace                UNDOTBS1undo_retention                 900--建立一張表tb_test用於示範,假定該會話為session1SQL> CREATE TABLE tb_test (ID INT, Name VARCHAR2(20));Table created.--插入一條記錄到tb_test,此時未提交將產生UNDO 資訊SQL> INSERT INTO tb_test SELECT 1,‘Robinson‘ FROM dual;1 row created.--此時開啟另外一個回話,假定為session2,在session2中切換資料表空間SQL> ALTER SYSTEM SET undo_tablespace = ‘undo2‘;  System altered.   --undotbs1中有未提交的事務,竟然可以成功切換?如此這般閃回時估計會有問題SQL> SHOW PARAMETER undo;NAME                                 TYPE        VALUE------------------------------------ ----------- ------------------------------undo_management                      string      AUTOundo_retention                       integer     900undo_tablespace                      string      undo2--在session1中執行commitSQL> COMMIT;Commit complete.   --成功執行了commit,且下面的查詢看到了提交後的結果SQL> SELECT * FROM tb_test;        ID NAME---------- ------------------------------         1 Robinson     --登出系統後再次查看,結果依然存在,比較納悶        SQL> exitDisconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - ProductionWith the Partitioning, OLAP and Data Mining options[uniread] Saved history (716 lines)[[email protected] ~]$ sqlplus / as sysdba;SQL*Plus: Release 10.2.0.1.0 - Production on Sat Jul 10 21:29:36 2010Copyright (c) 1982, 2005, Oracle.  All rights reserved.Connected to:Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - ProductionWith the Partitioning, OLAP and Data Mining optionsSQL> SELECT * FROM tb_test;        ID NAME---------- --------------------         1 Robinson --刪除UNDO資料表空間--在session1中插入一條新記錄SQL> INSERT INTO tb_test SELECT 2,‘Jack‘ FROM DUAL;1 row created.--在session2中將撤銷資料表空間切換為undotbs1SQL> ALTER SYSTEM SET undo_tablespace = ‘undotbs1‘;System altered.--緊接著在該回話中刪除undo2,提示正在使用SQL> DROP TABLESPACE undo2;DROP TABLESPACE undo2*ERROR at line 1:ORA-30013: undo tablespace ‘UNDO2‘ is currently in use--在session1中提交事務SQL> COMMIT;Commit complete.--在session2中再次刪除資料表空間undo2,收到了相同的錯誤提示SQL> /DROP TABLESPACE undo2*ERROR at line 1:ORA-30013: undo tablespace ‘UNDO2‘ is currently in useSQL> SHOW PARAMETER undo   --查看的確是已切換到undotbs1NAME                                 TYPE        VALUE------------------------------------ ----------- ------------------------------undo_management                      string      AUTOundo_retention                       integer     900undo_tablespace                      string      undotbs1--在session2中再次執行資料表空間切換到undotbs1SQL> ALTER SYSTEM SET undo_tablespace = ‘undotbs1‘;System altered.--此時undo2成功刪除,可以看出需要在將活動事務提交或復原後,再切換之後才能成功刪除撤銷資料表空間SQL> DROP TABLESPACE undo2;Tablespace dropped.SQL> ho ls $ORACLE_BASE/oradata/orcl;control01.ctl  redo03.log   redo2.log     system01.dbf   undotbs02.dbfcontrol02.ctl  redo04.log   redo3.log     tbs1_1.dbf     users01.dbfexample01.dbf  redo07.log   redo7.log     tbs1_2.dbfredo01.log     redo08.log   redo8.log     temp01.dbfredo02.log     redo1.log    sysaux01.dbf  undotbs01.dbf--刪除UNDO資料表空間的物理檔案SQL> ho rm $ORACLE_BASE/oradata/orcl/undotbs02.dbf;--在session1中可以看到兩條記錄也被成功插入SQL> SELECT * FROM tb_test;                            ID NAME---------- --------------------         1 Robinson         2 Jack             --查看當前撤銷資料表空間的大小SQL> SELECT tablespace_name,bytes/1024/1024 FROM dba_data_files WHERE tablespace_name = ‘UNDOTBS1‘;TABLESPACE_NAME                BYTES/1024/1024------------------------------ ---------------UNDOTBS1                                    30--迴圈插入記錄到tb_test後查看undo資料表空間的使用方式SQL> BEGIN   2  FOR i IN 1..20000  3  LOOP  4     INSERT INTO tb_test VALUES(i,‘Unkown Name‘);  5  END LOOP;  6  END;  7  /PL/SQL procedure successfully completed.    --可以看到UNDO 資料表空間只用了個塊SQL> SELECT addr,xidusn,used_ublk FROM v$transaction;ADDR         XIDUSN  USED_UBLK-------- ---------- ----------2D9FC160          6        174SQL> SELECT 174 * 8 || ‘KB‘ FROM dual;174*8|------1392KB

五、計算UNDO資料表空間的大小

計算公式:MAX(undoblks)/600 * MAX(maxquerylen)   位於v$undostat   * db_block_size                     位於v$parameter--建立示範環境SQL> INSERT INTO tb_test SELECT employee_id,first_name FROM hr.employees;107 rows createdSQL> INSERT INTO tb_test SELECT * from tb_test;109 rows created.--多次執行上述命令,下面是的tb_test表中的記錄數SQL> /892928 rows created.SQL> COMMIT;Commit complete.--查看當前undo資料表空間的大小SQL> SELECT t.name,d.name,d.bytes/1024/1024 as TotalSize ,t.flashback_on,d.status FROM v$tablespace t JOIN v$datafile d USING (ts#) WHERE t.name LIKE ‘UNDO%‘;  NAME                              NAME                                         TOTALSIZE FLA STATUS--------------------------------- ------------------------------------------- ---------- --- -------UNDOTBS1                          /u01/app/oracle/oradata/orcl/undotbs01.dbf          30 YES ONLINE--將undo資料表空間修改為RETENTION GUARANTEE及關閉自動擴充SQL> ALTER TABLESPACE undotbs1 RETENTION GUARANTEE;Tablespace altered.SQL> ALTER DATABASE DATAFILE ‘/u01/app/oracle/oradata/orcl/undotbs01.dbf‘ AUTOEXTEND OFF;Database altered.SQL> SELECT tablespace_name,contents,retention FROM dba_tablespaces WHERE tablespace_name LIKE ‘UNDO%‘;TABLESPACE_NAME                CONTENTS  RETENTION------------------------------ --------- -----------UNDOTBS1                       UNDO      GUARANTEE--修改保留時間為分鐘SQL> ALTER SYSTEM SET undo_retention = 120;System altered.--迴圈刪除tb_test中的記錄,提示undo資料表空間空間容量不夠SQL> BEGIN  2      FOR i IN 1..1000       3          LOOP  4              DELETE FROM tb_test WHERE rownum < 1001;  5              COMMIT;  6          END LOOP;  7  END;  8  /BEGIN*ERROR at line 1:ORA-30036: unable to extend segment by 8 in undo tablespace ‘UNDOTBS1‘ORA-06512: at line 4    --修改回話的時間參數SQL> ALTER SESSION SET nls_date_format=‘yyyy-mm-dd HH24:MI:SS‘;Session altered.--查看v$undostat視圖,獲得相關資訊SQL> SELECT begin_time,end_time,undoblks,maxquerylen, ssolderrcnt,nospaceerrcnt FROM v$undostat;BEGIN_TIME          END_TIME              UNDOBLKS MAXQUERYLEN SSOLDERRCNT NOSPACEERRCNT------------------- ------------------- ---------- ----------- ----------- -------------2010-07-12 19:12:18 2010-07-12 19:22:18          6           0           0             02010-07-12 19:02:18 2010-07-12 19:12:18          9           0           0             02010-07-12 18:52:18 2010-07-12 19:02:18         47           0           0             02010-07-12 18:42:18 2010-07-12 18:52:18       2136           0           0             12010-07-12 18:32:18 2010-07-12 18:42:18          6           0           0             02010-07-12 18:22:18 2010-07-12 18:32:18        413        1541           0             02010-07-12 18:12:18 2010-07-12 18:22:18        179         938           0             02010-07-12 18:02:18 2010-07-12 18:12:18          6           0           0             0--計算undo資料表空間所需的大小SQL> SELECT (  2    (SELECT MAX(undoblks)/600 * MAX(maxquerylen) FROM v$undostat) *  3      (SELECT value FROM v$parameter WHERE name = ‘db_block_size‘))/1024/1024 as Need_Size  4  FROM dual; NEED_SIZE----------42.8590625    --取消撤銷保留選項SQL> ALTER TABLESPACE undotbs1 RETENTION NOGUARANTEE;Tablespace altered

六、UNDO配額

對於超長的事務或不當的SQL指令碼將耗用大量的UNDO資料表空間,使用UNDO資料表空間配額可以提高資源的利用率對於不同組的使用者可以分配不同的最大UNDO資料表空間配額當某個組超出了最大的資源限制,則該組不允許新的事務產生,直到當前組的UNDO資料表空間釋放或終止

  

七、撤銷常見的兩個錯誤

--1.ORA-1555 snapshot too old 快照過舊錯誤的解決配置合適的保留時間(undo_retention)調整undo資料表空間的大小考慮保證撤銷保留的使用(retention guarantee)    --2.ORA-30036 unable to extend segment in undo tablespace 無法擴充撤銷資料表空間內的撤銷段調整undo資料表空間的大小確保大量的事務能夠周期性的提交

  

八、UNDO涉及的幾個相關視圖:

V$TRANSACTIONV$SESSIONDBA_ROLLBACK_SEGS   --顯示所有的segmentsV$ROLLSTATV$UNDOSTATV$ROLLNAME          --顯示當前線上的segments

  

6. Oracle 復原(ROLLBACK)和撤銷(UNDO)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.