Oracle 壞快處理:Undo 與 datafile

數據庫版本:9.2.0.5.0
平臺:windows2003

下午接到通知以數據庫出現壞塊現象,無備份,應用無法正常使用,要予以解決由於沒有備份,無法恢復,只能採用跳過壞塊方法,然後通過業務補數據。

首先要通知業務需要停服務,其次用PL/SQL登錄把OPTCABLE表的sql導出來。
首先要查出壞塊中的對象是什麼 file_id爲截圖中文件號,and 爲數據庫的塊號。
SQL> SELECT tablespace_name,segment_type, owner, segment_name FROM dba_extents WHERE file_id =82 AND 326677between block_id AND block_id + blocks - 1;

TABLESPACE_NAME SEGME OWNER    SEGMENT_NAME
------------------------------ ----------  ---------        --------
USERS                        TABLE   GISTAR      OPTCABLE

然後需要查詢數據對象的id(用於查詢rowid的參數)
SQL> SELECT data_object_id FROMdba_objects WHERE object_name = 'OPTCABLE' and owner='GISTAR';
DATA_OBJECT_ID
--------------
97248

找出壞塊最小的rowid (1, DATA_OBJECT_ID ,file_id,數據庫的塊號,0)
SQL> select dbms_rowid.rowid_create(1,97248,82,326677,0) from dual;

DBMS_ROWID.ROWID_C
------------------
AAAXvgABSAABPwVAAA

找出壞塊最大的rowid (1, DATA_OBJECT_ID ,file_id,數據庫的塊號+1,0)

SQL> select dbms_rowid.rowid_create(1,97248,82,326678,0) from dual;

DBMS_ROWID.ROWID_C
------------------
AAAXvgABSAABPwWAAA

然後通過rowid來確定壞塊數據的範圍,以便排除

這裏要注意,rowid的取值一定要大於大的,小於小的(上步驟查詢出來的2個rowid)

SQL> SELECT /*+ ROWID(A) */ COUNT(*)FROM OPTCABLE A WHERE ROWID>='AAAXvgABSAABPwWAAA';

當進行查詢時又報出undo表空間也有壞塊

ERROR 位於第 1 行:

ORA-01578: ORACLE 數據塊損壞(文件號107,塊號225)

ORA-01110: 數據文件 107:'D:\ORACLE\ORADATA\LNXC\UNDOTBS07.DBF'

解決此問題要替換undo表空間(注意未結束的回滾段)

create undo tablespace undo2 datafile'd:\oracle\oradata\lnxc\undo02_01.dbf' size 2048M;

alter system set undo_tablespace=undo2;

重啓數據庫後查詢undo信息(undo已經更換)

SQL> show parameter undo;

NAME TYPE VALUE
-------------------------------------------- ------------------------------
undo_management string AUTO

undo_retention integer 10800

undo_suppress_errors boolean FALSE

undo_tablespace string UNDO2

刪除老undo表空間報錯,發現了未結束的回滾段

SQL> drop tablespace UNDOTBS1 includingcontents and datafiles;

drop tablespace UNDOTBS1 including contentsand datafiles

*

ERROR 位於第 1 行:

ORA-01548: 已找到活動回退段'_SYSSMU5$',終止刪除表空間

創建pfile

SQL> create pfile='d:\t.txt' fromspfile;
關閉實例
SQL> shutdown immediate
編輯pfile加入如下參數(注意,CORRUPTED_ROLLBACK_SEGMENTS中一定要包含未結束的回滾段)

*.undo_management='MANUAL'

*._CORRUPTED_ROLLBACK_SEGMENTS=(_SYSSMU5$,_SYSSMU6$,_SYSSMU7$,_SYSSMU8$,_SYSSMU9$,_SYSSMU10$)

用pfile啓動數據庫
SQL> startup pfile='d:\t.txt';
刪除原來的undo表空間(數據文件也刪除)
SQL> drop tablespace UNDOTBS1 includingcontents and datafiles;
再用spfile重啓數據庫,因爲我們要用undo2表空間進行修復(不用指定參數文件,默認)
startup
查詢undo段信息
SQL> selectsegment_name,status,tablespace_name from dba_rollback_segs;
SEGMENT_NAME STATUS TABLESPACE_NAME
-------------------- ----------------------------------------------
SYSTEM ONLINE SYSTEM

_SYSSMU17$ ONLINE UNDO2

_SYSSMU18$ ONLINE UNDO2

_SYSSMU19$ ONLINE UNDO2

_SYSSMU20$ ONLINE UNDO2

_SYSSMU21$ ONLINE UNDO2

_SYSSMU22$ ONLINE UNDO2

_SYSSMU23$ ONLINE UNDO2

_SYSSMU24$ ONLINE UNDO2

_SYSSMU25$ ONLINE UNDO2

_SYSSMU26$ ONLINE UNDO2

發現沒有問題,切換生產用戶,繼續修復壞塊
然後通過rowid來確定壞塊數據的範圍,以便排除
這裏要注意,rowid的取值一定要大於大的,小於小的(上步驟查詢出來的2個rowid)


SQL> SELECT /*+ ROWID(A) */ COUNT(*)FROM OPTCABLE A WHERE ROWID>='AAAXvgABSAABPwWAAA';
COUNT(*)
----------
151362

SQL> SELECT /*+ ROWID(A) */ COUNT(*)FROM OPTCABLE A WHERE ROWID<'AAAXvgABSAABPwVAAA';
COUNT(*)
----------
27699


以原表結構創建一個新表,用來存放該表完好的數據(rowid依然大於大的小於小的)

SQL> CREATE TABLE OPTCABLE_BAK AS SELECT/*+ ROWID(A) */ * FROM OPTCABLE A WHERE ROWID>='AAAXvgABSAABPwWAAA';
SQL> INSERT INTO OPTCABLE_BAK SELECT /*+ ROWID(A) */ * FROMOPTCABLE A WHERE ROWID<'AAAXvgABSAABPwVAAA';
SQL> commit;


現在就把完好的數據成功找回,這裏注意不要用rename的方式去修改表名讓業務使用,因爲新創建表字段的默認值已經丟失,還需要重新加默認值。
按照一開始用PL/SQL導出的表sql去重新創建表結構,非表對象等等。
然後重新插入數據
SQL> insert into optcable select * fromoptcable_bak;
SQL> commit;
刪除創建的臨時表(9i或9i以上沒有開回收站的數據庫不用加purge,其他建議加purge)
SQL> drop table optcable_bak;
SQL> drop table optcable_bak1;
到此壞塊問題解決,如果11G版本還有統計信息的,建議追加統計信息。


原文鏈接:https://blog.csdn.net/roc_phoneix/article/details/39637235

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章