沒有備份undo segment出現問題的處理

warehouse發表於2014-02-11

--為了增加可讀性,先顯示一些和undo有關的資訊:
SQL> show parameter undo

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS1

SQL> select file_name, tablespace_name from dba_data_files;

FILE_NAME                                TABLESPACE_NAME
---------------------------------------- ------------------------------
E:\ORADATA\TEST\SYSTEM01.DBF             SYSTEM
E:\ORADATA\TEST\UNDOTBS01.DBF            UNDOTBS1
E:\ORADATA\TEST\SYSAUX01.DBF             SYSAUX
E:\ORADATA\TEST\USERS01.DBF              USERS

SQL> select segment_name,tablespace_name,status from dba_rollback_segs;

SEGMENT_NAME                   TABLESPACE_NAME                STATUS
------------------------------ ------------------------------ ----------------
SYSTEM                         SYSTEM                         ONLINE
_SYSSMU1$                      UNDOTBS1                       ONLINE
_SYSSMU17$                     UNDOTBS1                       ONLINE
_SYSSMU16$                     UNDOTBS1                       ONLINE
_SYSSMU15$                     UNDOTBS1                       ONLINE
_SYSSMU14$                     UNDOTBS1                       ONLINE
_SYSSMU13$                     UNDOTBS1                       ONLINE
_SYSSMU12$                     UNDOTBS1                       ONLINE
_SYSSMU11$                     UNDOTBS1                       ONLINE
_SYSSMU3$                      UNDOTBS1                       ONLINE
_SYSSMU2$                      UNDOTBS1                       ONLINE

已選擇11行。

--建立一張測試表t
SQL> create table t(id int,name varchar2(10)) tablespace users;

表已建立。

SQL> insert into t values(1,'a');

已建立 1 行。

SQL> commit;

提交完成。

SQL> update t set name='b';

已更新 1 行。
--這裡沒有提交,使用360線上強制刪除undo對應的資料檔案,刪除之後嘗試訪問t還是可以訪問的,嘗試commit了一下也沒有問題。

SQL> select * from t;

        ID NAME
---------- ----------
         1 b

SQL> commit;

提交完成。

SQL> select * from t;

        ID NAME
---------- ----------
         1 b
--當發出checkpoint的時侯報錯了。
SQL> alter system checkpoint;
alter system checkpoint
*
第 1 行出現錯誤:
ORA-03113: 通訊通道的檔案結束


SQL> exit
從 Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options 斷開

C:\>sqlplus / as sysdba

SQL*Plus: Release 10.2.0.5.0 - Production on 星期二 2月 11 08:04:23 2014

Copyright (c) 1982, 2010, Oracle.  All Rights Reserved.

已連線到空閒例程。

SQL> startup
ORACLE 例程已經啟動。

Total System Global Area  209715200 bytes
Fixed Size                  1302416 bytes
Variable Size              75497584 bytes
Database Buffers          125829120 bytes
Redo Buffers                7086080 bytes
資料庫裝載完畢。
ORA-01157: 無法標識/鎖定資料檔案 2 - 請參閱 DBWR 跟蹤檔案
ORA-01110: 資料檔案 2: 'E:\ORADATA\TEST\UNDOTBS01.DBF'


SQL> archive log list;
資料庫日誌模式             非存檔模式
自動存檔             禁用
存檔終點            USE_DB_RECOVERY_FILE_DEST
最早的聯機日誌序列     15
當前日誌序列           17
SQL> alter database datafile 2 offline drop;

資料庫已更改。

SQL> alter database open ;

資料庫已更改。

SQL> select * from t;
select * from t
              *
第 1 行出現錯誤:
ORA-00376: 此時無法讀取檔案 2
ORA-01110: 資料檔案 2: 'E:\ORADATA\TEST\UNDOTBS01.DBF'


SQL> select segment_name,tablespace_name,status from dba_rollback_segs;

SEGMENT_NAME                   TABLESPACE_NAME                STATUS
------------------------------ ------------------------------ ----------------
SYSTEM                         SYSTEM                         ONLINE
_SYSSMU1$                      UNDOTBS1                       NEEDS RECOVERY
_SYSSMU17$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU16$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU15$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU14$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU13$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU12$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU11$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU3$                      UNDOTBS1                       NEEDS RECOVERY
_SYSSMU2$                      UNDOTBS1                       NEEDS RECOVERY

已選擇11行。

SQL> drop tablespace undotbs1;
drop tablespace undotbs1
*
第 1 行出現錯誤:
ORA-30013: 還原表空間 'UNDOTBS1' 當前正在使用中


SQL> create undo tablespace undotbs2 datafile 'E:\oradata\test\undotbs02.dbf' size 20m;

表空間已建立。

SQL> show parameter undo

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS1
SQL> alter system set undo_tablespace=undotbs2;

系統已更改。

SQL> select segment_name,tablespace_name,status from dba_rollback_segs;

SEGMENT_NAME                   TABLESPACE_NAME                STATUS
------------------------------ ------------------------------ ----------------
SYSTEM                         SYSTEM                         ONLINE
_SYSSMU1$                      UNDOTBS1                       NEEDS RECOVERY
_SYSSMU17$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU16$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU15$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU14$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU13$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU12$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU11$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU3$                      UNDOTBS1                       NEEDS RECOVERY
_SYSSMU2$                      UNDOTBS1                       NEEDS RECOVERY

SEGMENT_NAME                   TABLESPACE_NAME                STATUS
------------------------------ ------------------------------ ----------------
_SYSSMU30$                     UNDOTBS2                       ONLINE
_SYSSMU29$                     UNDOTBS2                       ONLINE
_SYSSMU28$                     UNDOTBS2                       ONLINE
_SYSSMU27$                     UNDOTBS2                       ONLINE
_SYSSMU26$                     UNDOTBS2                       ONLINE
_SYSSMU25$                     UNDOTBS2                       ONLINE
_SYSSMU24$                     UNDOTBS2                       ONLINE
_SYSSMU23$                     UNDOTBS2                       ONLINE
_SYSSMU22$                     UNDOTBS2                       ONLINE
_SYSSMU21$                     UNDOTBS2                       ONLINE

已選擇21行。

SQL> drop tablespace undotbs1;
drop tablespace undotbs1
*
第 1 行出現錯誤:
ORA-01548: 已找到活動回退段 '_SYSSMU1$', 終止刪除表空間


SQL> drop rollback segment "_SYSSMU1$";
drop rollback segment "_SYSSMU1$"
*
第 1 行出現錯誤:
ORA-30025: 不允許刪除段 '_SYSSMU1$' (在還原表空間中)


SQL> shutdown immediate
資料庫已經關閉。
已經解除安裝資料庫。
ORACLE 例程已經關閉。

--此時需要用到oracle的一個和undo有關的隱含引數_corrupted_rollback_segments
把狀態為NEEDS RECOVERY的undo segment都放在引數_corrupted_rollback_segments的列表裡面,
具體_corrupted_rollback_segments=(_SYSSMU1$,_SYSSMU17$,_SYSSMU16$,_SYSSMU15$,_SYSSMU14$,_SYSSMU13$,_SYSSMU12$,_SYSSMU11$,_SYSSMU3$,_SYSSMU2$)
由於我在啟動例項的時侯使用的是init檔案,因此直接編輯init檔案把
_corrupted_rollback_segments=(_SYSSMU1$...)放進去之後重啟例項就可以了,
如下圖:
沒有備份undo segment出現問題的處理

init檔案我編輯了2個地方,一個是增加了最後一行_corrupted_rollback_segments=...,另外倒數第三行
*.undo_tablespace='UNDOTBS2'由原來的UNDOTBS1改成了UNDOTBS2

SQL> startup
ORACLE 例程已經啟動。

Total System Global Area  209715200 bytes
Fixed Size                  1302416 bytes
Variable Size              75497584 bytes
Database Buffers          125829120 bytes
Redo Buffers                7086080 bytes
資料庫裝載完畢。
資料庫已經開啟。
SQL> show parameter undo

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS2
SQL> select segment_name,tablespace_name,status from dba_rollback_segs;

SEGMENT_NAME                   TABLESPACE_NAME                STATUS
------------------------------ ------------------------------ ----------------
SYSTEM                         SYSTEM                         ONLINE
_SYSSMU1$                      UNDOTBS1                       NEEDS RECOVERY
_SYSSMU17$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU16$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU15$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU14$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU13$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU12$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU11$                     UNDOTBS1                       NEEDS RECOVERY
_SYSSMU3$                      UNDOTBS1                       NEEDS RECOVERY
_SYSSMU2$                      UNDOTBS1                       NEEDS RECOVERY

SEGMENT_NAME                   TABLESPACE_NAME                STATUS
------------------------------ ------------------------------ ----------------
_SYSSMU30$                     UNDOTBS2                       ONLINE
_SYSSMU29$                     UNDOTBS2                       ONLINE
_SYSSMU28$                     UNDOTBS2                       ONLINE
_SYSSMU27$                     UNDOTBS2                       ONLINE
_SYSSMU26$                     UNDOTBS2                       ONLINE
_SYSSMU25$                     UNDOTBS2                       ONLINE
_SYSSMU24$                     UNDOTBS2                       ONLINE
_SYSSMU23$                     UNDOTBS2                       ONLINE
_SYSSMU22$                     UNDOTBS2                       ONLINE
_SYSSMU21$                     UNDOTBS2                       OFFLINE

已選擇21行。
--有了_corrupted_rollback_segments的作用,我們把undotbs1裡面的undo segment以及undotbs1表空間都可以輕鬆刪除了
SQL> drop rollback segment "_SYSSMU1$";

回退段已刪除。

SQL> drop tablespace undotbs1;

表空間已刪除。

SQL> select segment_name,tablespace_name,status from dba_rollback_segs;

SEGMENT_NAME                   TABLESPACE_NAME                STATUS
------------------------------ ------------------------------ ----------------
SYSTEM                         SYSTEM                         ONLINE
_SYSSMU30$                     UNDOTBS2                       ONLINE
_SYSSMU29$                     UNDOTBS2                       ONLINE
_SYSSMU28$                     UNDOTBS2                       ONLINE
_SYSSMU27$                     UNDOTBS2                       ONLINE
_SYSSMU26$                     UNDOTBS2                       ONLINE
_SYSSMU25$                     UNDOTBS2                       ONLINE
_SYSSMU24$                     UNDOTBS2                       ONLINE
_SYSSMU23$                     UNDOTBS2                       ONLINE
_SYSSMU22$                     UNDOTBS2                       ONLINE
_SYSSMU21$                     UNDOTBS2                       OFFLINE

已選擇11行。

SQL> select * from t;

        ID NAME
---------- ----------
         1 b
--測試t表也可以正常訪問了,這個我想是因為我在drop掉undotbs1表空間對應的資料檔案
之後發出了一個commit的緣故,否則我不知道是否還能訪問這張表,大家可以測試。在生產環境中
遇到的情況可能比這個還要複雜,到時候我們根據情況來處理就是了。在編輯init引數_corrupted_rollback_segments=...
的時侯為了測試需要我順便把_SYSSMU21$也放在裡面了,_SYSSMU21$屬於undotbs2,是一個沒有問題的undo segment,
,把沒有問題的undo segment放在引數_corrupted_rollback_segments之後,例項啟動之後其狀態由原來的online變成
offline了,同時也可以對其刪除。看下面的結果:這種辦法可以回縮過段擴張導致undo資料檔案很大的資料檔案,當然
也可以通過重新建立新的undo來刪除原來的undo來解決。


SQL> drop rollback segment "_SYSSMU21$";

回退段已刪除。

SQL> select segment_name,tablespace_name,status from dba_rollback_segs;

SEGMENT_NAME                   TABLESPACE_NAME                STATUS
------------------------------ ------------------------------ ----------------
SYSTEM                         SYSTEM                         ONLINE
_SYSSMU30$                     UNDOTBS2                       ONLINE
_SYSSMU29$                     UNDOTBS2                       ONLINE
_SYSSMU28$                     UNDOTBS2                       ONLINE
_SYSSMU27$                     UNDOTBS2                       ONLINE
_SYSSMU26$                     UNDOTBS2                       ONLINE
_SYSSMU25$                     UNDOTBS2                       ONLINE
_SYSSMU24$                     UNDOTBS2                       ONLINE
_SYSSMU23$                     UNDOTBS2                       ONLINE
_SYSSMU22$                     UNDOTBS2                       ONLINE

已選擇10行。

SQL>
--======================
上面測試中其實只要有undotbs1裡面狀態為NEEDS RECOVERY的undo segment沒有被包含
在隱含引數_corrupted_rollback_segments當中,對應的這個undo segment以及undotbs1
這個表空間都是不能被刪除的。即使狀態為NEEDS RECOVERY的undo segment都被包含在
_corrupted_rollback_segments當中了,也有可能這些undo segment或者undotbs1還是不能
被刪除,此時我們可以修改引數undo_management為manual,然後繼續刪除這些有問題的
undo segment或者這個有問題的undo表空間。另外在生產環境中可能會遇到的問題是某些undo段
出現問題,不是我們模擬的整個undo表空間對應的資料檔案出現問題,此時_corrupted_rollback_segments
的作用就更加明顯了。


 


 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/19602/viewspace-1079279/,如需轉載,請註明出處,否則將追究法律責任。

相關文章