2013/12/26

Published 12月 26, 2013 by

Oracle檔案異常資料還原(temp,redo,index,file,password,control block error)

檔案異常資料還原(11gAW2 Cheaper6,7)
一、Temp file error
二、REDO Log file error:
三、Index error
四、File error
五、Password file error
六、Control file error
七、Block Error

Oracle Version:10g/11g



Temp file error:
分可以重啟及不可以重啟兩種狀況:
可重啟:把file 刪除掉,重新啟動oracle即可
不可重啟:建立tempfile,刪除舊有的tempfile,以下分兩種建立方式:

一、
SQL> select file_name from dba_temp_files where tablespace_name='TEMP';  --找出temp tablespace所使用的tempfiles


SQL> select tablespace_name from dba_tablespaces where contents='TEMPORARY';  --找出所有可用的temporary tablespace

--建議建立一個新temporary tablespace取代已經毀損的temporary tablespace
SQL> create temporary tablespace temp2 tempfile '/u02/oradata/orcl/temp2.dbf' size 100M  AUTOEXTEND ON NEXT 8K maxsize unlimited;;

--變更資料庫的預設temporary tablespacetemp2
SQL> alter database default temporary tablespace temp2;

查詢Usertemp tablespace
SQL> select temporary_tablespace from dba_users where username='HR';

刪除壞掉的temp
SQL> drop tablespace temp INCLUDING CONTENTS AND DATAFILES;;
<====在原本的user session 沒斷前可能會卡住,須等session斷掉,或手動kill session才會成功drop

二、
SQL> alter tablespace temp add tempfile '/home/oracle/temp01.dbf' size 100M;    --add new tempfiletemp tablespace

SQL> alter tablespace temp drop tempfile '/u02/oradata/orcl/temp01.dbf';  --drop corrupted tempfile

SQL> select file_name from dba_temp_files where tablespace_name='TEMP';  --找出temp tablespace所使用的tempfiles


*********************************************************************
REDO Log file error:
如果是inactive,現在不影響運作狀況,等待轉換的時候,才會受影響
--一個database至少要有兩個logfile groups
--logfile group的特色,只要logfile group裡尚有一個以上的logfile member存在,則此logfile group還是維持正常的操作
--每個logfile group裡至少需要一個member,最多只能有5個members.建議各個member應該放在不同disk controller所管理的不同disk

Redo log擺放路徑
SQL> select group#,member from v$logfile order by group#;

redo log的狀態
SQL> select group#,sequence#,members,to_char(first_time,'YYYY-MM-DD:HH24:MI:SS'),status,archived from v$log;
current->lgwr正在使用的logfile group(如果需要將log buffer的redo entry寫到logfile group時,lgwr會把redo entry寫到此logfile group的所有logfile member之中)
inactive->如果現在發生instance crash.當instance重新啟動並進行rollforward時,不需要使用此logfile group的內容來復原dirty buffers
active->如果現在發生instance crash.當instance重新啟動並進行rollforward時,將需要使用此logfile group的內容,將dirty buffers復原


SQL> alter system checkpoint;  --要求將目前所有的dirty buffers全數寫回datafiles(Buffer cache寫入資料檔中).因此目前所有為ACTIVE的logfile group,在此指令完成後,都將變成INACTIVE

SQL> alter system switch logfile;  --lgwr更換current logfile group
                                   --並呼叫ckpt對舊的current logfile group進行checkpoint(dbwr將此log sequence#區間的dirty buffers變成clean buffer)
                                   --如果是archivelog mode,則也會呼叫archiver對舊的current logfile group進行archive

--針對尚未被archived的logfile group(若檔案遺失,會自動建立此file,db必需要經過alter system switch logfile才知道檔案移失,才會自動建立檔案)
SQL> alter database clear unarchived logfile group 2;

SQL>  select group#,sequence#,members,to_char(first_time,'YYYY-MM-DD:HH24:MI:SS') first_time,status,archived from v$log;

    GROUP#  SEQUENCE#    MEMBERS FIRST_TIME          STATUS           ARC
---------- ---------- ---------- ------------------- ---------------- ---
         1         31          1 2010-10-12:04:47:06 INACTIVE         YES
         2          0          1 2010-10-12:04:48:37 UNUSED           YES
         3         33          1 2010-10-12:04:49:51 CURRENT          NO


查看archivelog sequence
SQL>  select sequence#,name from v$archived_log;


**此時應該立刻進行一次whole backup.這樣就不需要使用到log seq# 32,因為現在的current logfile sequence#為33
**不然如果現在有任何datafile發生media failure,當recovery它時,將需要log seq# 32

RMAN> backup database;


備註:
SQL> alter system set "_allow_resetlogs_corruption"=true scope=spfile;
設置此參數之后,在數據庫Open過程中,Oracle會跳過某些一致性檢查,從而使數據庫可能跳過不一致狀態。
注意_allow_resetlogs_corruption是Oracle中的一個隱含參數如果系統實在不能resetlogs方式打開的後只能出此下策
http://www.sadtojoy.com/aspx/Detail.aspx?id=3996

*********************************************************************
Index Error
index tablespace發生media failure,可以採用以下的做法
1.當作一般的datafile,進行offline->restore->recover->online的復原操作


2.drop index tablespace,create new index tablespace,create index --因為index內容與table內容相依.所以只要table存在,便可以重建index

查詢User底下的tablespace的型態是否全部都為index
SQL> select segment_type,count(*) from dba_segments where tablespace_name='USERS' group by segment_type;

資料重建:
SQL> alter database datafile '/oradata1/testdb/index_ts01.dbf' offline drop;

SQL> drop tablespace index_ts including contents and datafiles;

SQL> create tablespace index_ts datafile '/oradata1/testdb/index_ts01.dbf' size 10M;

SQL> create index scott.t5_idx1 on scott.t5(object_id) tablespace index_ts;

透過rman回覆:
RMAN> run {
2> sql 'alter database datafile 4 offline';
3> restore datafile 4;
4> recover datafile 4;
5> sql 'alter database datafile 4 online';}

*********************************************************************
File Error

透過Rman的方式還原+Archive log還原,若是一般的User,不一定要停機,
[oracle@oracleDB ~]$ rman target /
RMAN>  run {
2> sql 'alter database datafile 6 offline';
3>  restore datafile 6;
4>  recover datafile 6;
5>  sql 'alter database datafile 6 online';}


*********************************************************************
Password file error
user process要求以as sysdbaas sysoper身分建立session,Oracle server使用下列2種方式驗證其身分
1.os驗證(user必須先登入os(Oracle Server所在的os),同時user所使用的os username必須屬於某個特殊的os group,即所謂的dba group(在安裝oracle software時指定的os group)
2.os驗證失敗或使用remote登入時,則使用password file進行驗證

**重建密碼檔
[oracle@oracleDB ~]$ orapwd file=$ORACLE_HOME/dbs/orapworcl password=oracle entries=10  ignorecase=y --filepassword file的名字,有特定的格式.orapw開頭,緊接著instance name,記得不需要副檔名                                                                                                     --passwordsys的密碼(11g預設有區分大小寫)
 --ignorecase=y取消大小寫區分,可以向前相容.

SQL> select * from v$pwfile_users;  --顯示現在password file內的資訊
               
*********************************************************************
Control error(Control file的任一檔案壞掉,db就會有異常)

查看Control file 存放位置
SQL> select value from v$system_parameter where name='control_files';

1.如果只有部分的controlfile發生media failure,只需要將尚存好的controlfile複製給壞的controlfile即可,接著重新啟動即可(instance recovery自動發生)
  使用OS指命COPY即可
     [oracle@oracleDB ~]$ cp /u2/oradata/orcl/control01.ctl /u01/app/oracle/flash_recovery_area/orcl/control02.ctl
        SQL> alter database mount;
        SQL> alter database open; --將會進行instance recovery.因此無資料遺失.

2.controlfile全數毀損,則必須在nomount階段,restore之前所做的controlfile備份,
SQL>startup nomount;
--使用rman復原controlfile,目前instance已經在nomount階段
[oracle@oracleDB ~]$ rman target /
RMAN> restore controlfile from autobackup;   --Oracle Server自行找尋最新的autobackup所產生的controlfile backup
------restore controlfile from '/home/oracle/orcl_control_20101020.ctl';  --DBA明確選擇使用某一個controlfile backup
------restore controlfile; --RC的內容將controlfile復原--$ rman target / catalog rmanuser/oracle@192.168.56.1:1521/orcl


mount下執行:
SQL>alter database mount;
SQL> recover database until cancel using backup controlfile;(應該會出錯...因還原出來的ControlSystem.dbf這個檔不一致)

control遺失,所以要做restore database,從backup到現在的time,資料一併不見
RMAN> restore database;             
RMAN> recover database;

SQL> alter database open resetlogs;

查看現在的INSTANCE狀態
SQL> select status from v$instance;

--使用sql command備份controlfilebinary format
SQL> alter database backup controlfile to '/home/oracle/orcl_control_20101020.ctl';

*********************************************************************
Block Error
**主動使用rman指令驗證整個datafile,看看是否還有其他尚未發現的錯誤blocks
    --backup validate nochecksum datafile 4; --nochecksum將關閉自動physical corruption檢查
RMAN> backup validate datafile 4;  --只檢查physical corruption.預設自動檢查checksum(physical corruption)
    --backup check logical validate datafile 4; --同時檢查physical/logical corruption(check logical啟動logical corruption檢查)


查詢錯誤的block
SQL> select * from v$database_block_corruption;  --內容來自於v$backup_corruptionv$copy_corruption
                                                 --v$backup_corruption的內容來自於執行rmanbackupbackup validate所發現的corrupted blocks
                                                 --v$copy_corruption的內容來自於執行rmanbackup as copybackup as copy validate所發現的corrupted blocks

**可以直接藉由跳過毀損block不讀取的方式,取得其他完好block的內容
SQL> execute dbms_repair.skip_corrupt_blocks('HR','T1',flags=>1); --可以不寫flags=>1,因為此選項為預設值

--blockrecover10g的語法
--10g> blockrecover datafile 4 block 679;
RMAN> recover datafile 4 block 679;  --不需要offline datafiletablespace(availability較高).僅需restore/recovery corrupted blocks(復原速度較快)
做完之後,再查詢一下是否有錯誤的block