某個使用9i資料庫且位於大陸深圳的客戶,在使用RMAN做異機還原的時候遇到類似以下的訊息,Offline 的datafile無法使用 RMAN 還原。
客戶是在 2011年 offline datafile的,所以也找不到當初的 archive log 來將這兩個datafile restore,也無法 recover datafile,也由於 resetlogs過了,所以事情變得非常麻煩,上 mos 查了一下資料,使用bbed解決。
由於 file$ 所記載的 datafile 資訊,datafile 不能斷號,如果 offline 的 file id 是最後一個! 那恭喜
,可以使用重建control file 的方式將最後一個 file id 狀況為 offline line 的 datafile 去掉,否則r就只能用 bbed 來騙資料庫。
狀況模擬與說明
以下為archive log mode 下模擬出來的情況。
2 . offline 12 , 14 號 datafile ,並 recover 使其成為 offline,並多次 checkpoint 與 switch logfile。
3 . 使用 RMAN backup & restore ,並resetlogs。
4 . 使用RMAN 清除 archive log。
5 . 使用 RMAN backup & restore ,出現 RMAN-06023 no backup or copy of datafile n found to restore 狀況。
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of restore command at 12/12/2014 08:47:23
RMAN-06026: some targets not found - aborting restore
RMAN-06023: no backup or copy of datafile 14 found to restore
RMAN-06023: no backup or copy of datafile 12 found to restore
select a.ts#, a.file#, b.file_name, a.checkpoint_change#, a.last_change#, a.status
from v$datafile a , dba_data_files b
where a.file# = b.file_id
order by a.file#
/
select file#, checkpoint_change#, RESETLOGS_CHANGE#
from v$datafile_header
/
可以看到 datafile_header 紀錄中, checkpoint_change# 與 resetlogs_change# 不一樣了。
要注意的是,datafile 有沒有被分配 extent
select count(*) from dba_extents where file_id in (12,14);
˙
查詢出來的沒有 row 就代表兩 datafile 是空的。
在已經沒有當初archive log 的備份且resetlogs狀態下,online 這兩個datafile 會遇到以下錯誤。
SQL> alter database datafile 12 online;
alter database datafile 12 online
*
ERROR at line 1:
ORA-01190: controlfile or data file 12 is from before the last RESETLOGS
ORA-01110: data file 12: '/u01/app/oracle/oradata/orcl/dbs1-02.dbf'
SQL> alter database datafile 14 online;
alter database datafile 14 online
*
ERROR at line 1:
ORA-01190: controlfile or data file 14 is from before the last RESETLOGS
ORA-01110: data file 14: '/u01/app/oracle/oradata/orcl/dbs1-04.dbf'
一個長期運作的資料庫,archive log 或 RMAN 很少有機會可以完整保留的,大部分都會有設定一個有效日期來刪除,所以目前看來應該沒救了,若要讓RMAN可以正常備份還原,看起來得使用非正規的手段恢復。
由於datafile沒內容物,當初客戶是因為 datafile 建錯名子,所以 offline 這兩個 datafile。
本次因客戶為需要,非得讓這樣的狀況正常,所以決定使用以下非正規的方法讓這兩個datafile正常運作。
BBED 工具準備與說明
cd $ORACLE_HOME/rdbms/lib
make -f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed
BBED 可以使用 filelist,filelist中記錄 file id, file name , file size ,可以使用以下的sql指令的結果寫到 filelist中。
set pagesize 0
select file#||' '||name||' '||bytes from v$datafile ;
</u01/app/oracle/product/9.2.0/db_1/rdbms/lib> cat /tmp/filelist.lst
1 /u01/app/oracle/oradata/orcl/system01.dbf 429916160
2 /u01/app/oracle/oradata/orcl/undotbs01.dbf 414187520
3 /u01/app/oracle/oradata/orcl/cwmlite01.dbf 20971520
4 /u01/app/oracle/oradata/orcl/drsys01.dbf 20971520
5 /u01/app/oracle/oradata/orcl/example01.dbf 156631040
6 /u01/app/oracle/oradata/orcl/indx01.dbf 26214400
7 /u01/app/oracle/oradata/orcl/odm01.dbf 20971520
8 /u01/app/oracle/oradata/orcl/tools01.dbf 10485760
9 /u01/app/oracle/oradata/orcl/users01.dbf 26214400
10 /u01/app/oracle/oradata/orcl/xdb01.dbf 47185920
11 /u01/app/oracle/oradata/orcl/dbs1-01.dbf 104857600
12 /u01/app/oracle/oradata/orcl/dbs1-02.dbf 104857600
13 /u01/app/oracle/oradata/orcl/dbs1-03.dbf 104857600
14 /u01/app/oracle/oradata/orcl/dbs1-04.dbf 104857600
15 /u01/app/oracle/oradata/orcl/dbs1-05.dbf 104857600
16 /u01/app/oracle/oradata/orcl/dbs1-06.dbf 104857600
cd $ORACLE_HOME/rdbms/lib
$ ./bbed listfile=/tmp/filelist.lst blocksize=8192 mode=edit password=blockedit
觀察map一下利用 filelist.lst載入的資訊
BBED> info
File# Name Size(blks)
----- ---- ----------
1 /u01/app/oracle/oradata/orcl/system01.dbf 52480
2 /u01/app/oracle/oradata/orcl/undotbs01.dbf 50560
3 /u01/app/oracle/oradata/orcl/cwmlite01.dbf 2560
4 /u01/app/oracle/oradata/orcl/drsys01.dbf 2560
5 /u01/app/oracle/oradata/orcl/example01.dbf 19120
6 /u01/app/oracle/oradata/orcl/indx01.dbf 3200
7 /u01/app/oracle/oradata/orcl/odm01.dbf 2560
8 /u01/app/oracle/oradata/orcl/tools01.dbf 1280
9 /u01/app/oracle/oradata/orcl/users01.dbf 3200
10 /u01/app/oracle/oradata/orcl/xdb01.dbf 5760
11 /u01/app/oracle/oradata/orcl/dbs1-01.dbf 12800
12 /u01/app/oracle/oradata/orcl/dbs1-02.dbf 12800
13 /u01/app/oracle/oradata/orcl/dbs1-03.dbf 12800
14 /u01/app/oracle/oradata/orcl/dbs1-04.dbf 12800
15 /u01/app/oracle/oradata/orcl/dbs1-05.dbf 12800
16 /u01/app/oracle/oradata/orcl/dbs1-06.dbf 12800
這次目的是要修改file id 為 12 , 14 的 file header,使這兩個 datafile 的 file header 中所記錄的 CHECKPOINT_CHANGE# ,RESETLOGS_CHANGE# 與其他datafile 一樣。
修改前建議做全資料庫備份,非常重要。
確認所需要的 offset 位置
切換 datafile
BBED> set filename '/u01/app/oracle/oradata/orcl/system01.dbf' block 1
FILENAME /u01/app/oracle/oradata/orcl/system01.dbf
BLOCK# 1
確認目前使用的 datafile
BBED> map
File: /u01/app/oracle/oradata/orcl/system01.dbf (0)
Block: 1 Dba:0x00000000
------------------------------------------------------------
Data File Header
struct kcvfh, 360 bytes @0
ub4 tailchk @8188
列出 block 1 各 struct 中的數值。
BBED> p kcvfh
.............................. 略 ..............................
ub4 kcvfhcrt @108 0x1f05276d
ub4 kcvfhrlc @112 0x339fb560 -- resetlogs count
struct kcvfhrls, 8 bytes @116
ub4 kscnbas @116 0x000571e1 -- resetlogs scn
ub2 kscnwrp @120 0x0000
ub4 kcvfhbti @124 0x00000000
struct kcvfhbsc, 8 bytes @128
ub4 kscnbas @128 0x00000000
ub2 kscnwrp @132 0x0000
ub2 kcvfhbth @136 0x0000
ub2 kcvfhsta @138 0x0004 (KCVFHOFZ)
struct kcvfhckp, 36 bytes @140
struct kcvcpscn, 8 bytes @140
ub4 kscnbas @140 0x00057560 -- checkpoint 低位
ub2 kscnwrp @144 0x0000 -- checkpoint 高位
ub4 kcvcptim @148 0x33a0dc16 -- checkpoint time
ub2 kcvcpthr @152 0x0001
union u, 12 bytes @156
struct kcvcprba, 12 bytes @156
ub4 kcrbaseq @156 0x00000009
ub4 kcrbabno @160 0x00000054
ub2 kcrbabof @164 0x0010
struct kcvcptr, 12 bytes @156
struct kcrtrscn, 8 bytes @156
ub4 kscnbas @156 0x00000009
ub2 kscnwrp @160 0x0054
ub4 kcrtrtim @164 0x00000010
ub1 kcvcpetb[0] @168 0x02
ub1 kcvcpetb[1] @169 0x00
ub1 kcvcpetb[2] @170 0x00
ub1 kcvcpetb[3] @171 0x00
ub1 kcvcpetb[4] @172 0x00
ub1 kcvcpetb[5] @173 0x00
ub1 kcvcpetb[6] @174 0x00
ub1 kcvcpetb[7] @175 0x00
ub4 kcvfhcpc @176 0x00000041 -- checkpoint 計數
ub4 kcvfhrts @180 0x339fb558
ub4 kcvfhccc @184 0x00000040 -- checkpoint 計數 - 1
.............................. 略 ..............................
說明
### 有關於 reset logs
kcvfhrlc -- resetlogs count
struct kcvfhrls 裡面的 kscnbas -- resetlogs scn
### scn 相關
struct kcvfhrls 裡面的
kscnbas -- checkpoint 低位
kscnwrp -- checkpoint 高位
kcvcptim -- checkpoint time
kcvfhcpc -- checkpoint 計數
kcvfhccc -- checkpoint 計數 - 1
所以由上面列表,我們得知以下的 offset 是我們需要的
@112
@116
@140
@144
@148
@176
由SYSTEM01中確定 6 個offset 位置中所需要的值。
可以使用 dump 卻確認 offset 中的數值
dump /v dba fileid,block offset n
BBED> dump /v dba 1,1 offset 112 count 16
File: /u01/app/oracle/oradata/orcl/system01.dbf (1)
Block: 1 Offsets: 112 to 127 Dba:0x00400001
-------------------------------------------------------
60b59f33 e1710500 00000000 00000000 l `?3嫭..........
<16 bytes per line>
以上 60b59f33 就是 offset 112 內的數值,用以下的方式確認system01 block01裡面以下所需的 offset。
@112 = 60b59f33
@116 = e1710500
@140 = 60750500
@144 = 00000000 <= 觀察一下,不一定需要改。
@148 = 16dca033
@176 = 41000000
@184 = 40000000
修改 file_id 12 , 14 中相關 offset 的值
BBED> set file 12 block 1
FILE# 12
BLOCK# 1
BBED> map
File: /u01/app/oracle/oradata/orcl/dbs1-02.dbf (12)
Block: 1 Dba:0x03000001
------------------------------------------------------------
Data File Header
struct kcvfh, 360 bytes @0
ub4 tailchk @8188
BBED> modify /x 60b59f33 offset 112
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) Y
File: /u01/app/oracle/oradata/orcl/dbs1-02.dbf (12)
Block: 1 Offsets: 112 to 127 Dba:0x03000001
------------------------------------------------------------------------
60b59f33 b46c0200 00000000 00000000
<32 bytes per line>
BBED> modify /x e1710500 offset 116
File: /u01/app/oracle/oradata/orcl/dbs1-02.dbf (12)
Block: 1 Offsets: 116 to 131 Dba:0x03000001
------------------------------------------------------------------------
e1710500 00000000 00000000 00000000
<32 bytes per line>
BBED> modify /x 60750500 offset 140
File: /u01/app/oracle/oradata/orcl/dbs1-02.dbf (12)
Block: 1 Offsets: 140 to 155 Dba:0x03000001
------------------------------------------------------------------------
60750500 00000000 c6b39f33 01000000
<32 bytes per line>
BBED> modify /x 16dca033 offset 148
File: /u01/app/oracle/oradata/orcl/dbs1-02.dbf (12)
Block: 1 Offsets: 148 to 163 Dba:0x03000001
------------------------------------------------------------------------
16dca033 01000000 12000000 02000000
<32 bytes per line>
BBED> modify /x 41000000 offset 176
File: /u01/app/oracle/oradata/orcl/dbs1-02.dbf (12)
Block: 1 Offsets: 176 to 191 Dba:0x03000001
------------------------------------------------------------------------
41000000 20b59f33 09000000 00000000
<32 bytes per line>
BBED> modify /x 40000000 offset 184
File: /u01/app/oracle/oradata/orcl/dbs1-02.dbf (12)
Block: 1 Offsets: 184 to 199 Dba:0x03000001
------------------------------------------------------------------------
40000000 00000000 00000000 00000000
<32 bytes per line>
以相同的方式修改 dbs1-04.dbf,修改完成後記得 sum , sum apply 。
BBED> sum
Check value for File 12, Block 1:
current = 0xb21d, required = 0xd471
BBED> sum apply
Check value for File 12, Block 1:
current = 0xd471, required = 0xd471
DBVERIFY datafile 12 14的 block 1
BBED> verify dba 12,1
DBVERIFY - Verification starting
FILE = /u01/app/oracle/oradata/orcl/dbs1-02.dbf
BLOCK = 1
Total Blocks Examined : 1
Total Blocks Processed (Data) : 0
Total Blocks Failing (Data) : 0
Total Blocks Processed (Index): 0
Total Blocks Failing (Index): 0
Total Blocks Empty : 0
Total Blocks Marked Corrupt : 0
Total Blocks Influx : 0
BBED> verify dba 14,1
DBVERIFY - Verification starting
FILE = /u01/app/oracle/oradata/orcl/dbs1-04.dbf
BLOCK = 1
DBVERIFY - Verification complete
Total Blocks Examined : 1
Total Blocks Processed (Data) : 0
Total Blocks Failing (Data) : 0
Total Blocks Processed (Index): 0
Total Blocks Failing (Index): 0
Total Blocks Empty : 0
Total Blocks Marked Corrupt : 0
Total Blocks Influx : 0
修改 datafile header 後的操作
理論上應該可以 online datafile了。
SQL> alter database datafile 12 online;
alter database datafile 12 online
*
ERROR at line 1:
ORA-01113: file 12 needs media recovery
ORA-01110: data file 12: '/u01/app/oracle/oradata/orcl/dbs1-02.dbf'
SQL> recover datafile 12;
ORA-00283: recovery session canceled due to errors
ORA-00600: internal error code, arguments: [3672], [12], [4294967295], [64],
[4294967295], [], [], []
出現了錯誤,查為controlfile裡面紀錄的scn與修改過後的scn不一致,由於control file 還沒想到可以用任何工具修改,所以重建control file,把 datafile header中所記錄的寫回 controlfile。
SQL> col CHECKPOINT_CHANGE# HEADING 'CHECKPOINT|CHANGE#'
SQL> col RESETLOGS_CHANGE# HEADING 'RESETLOGS|CHANGE#'
SQL> select file#, checkpoint_change#, RESETLOGS_CHANGE#
from v$datafile_header;
datafile_header 中紀錄的 scn ,resetlogs_change# 都一致。
SQL> select a.ts#, a.file#, b.file_name, a.checkpoint_change#, a.last_change#, a.status
from v$datafile a , dba_data_files b
where a.file# = b.file_id
order by a.file#
/
control file 中紀錄的 scn 不一樣,因此recover datafile 出現 ORA-00600: internal error code, arguments: [3672] 錯誤
重建 controlfile 即可將 datafile 12 , 14 正常 online。
CREATE CONTROLFILE REUSE DATABASE "ORCL" NORESETLOGS ARCHIVELOG
MAXLOGFILES 50
MAXLOGMEMBERS 5
MAXDATAFILES 100
MAXINSTANCES 1
MAXLOGHISTORY 226
LOGFILE
GROUP 1 '/u01/app/oracle/oradata/orcl/redo01.log' SIZE 100M,
GROUP 2 '/u01/app/oracle/oradata/orcl/redo02.log' SIZE 100M,
GROUP 3 '/u01/app/oracle/oradata/orcl/redo03.log' SIZE 100M
DATAFILE
'/u01/app/oracle/oradata/orcl/system01.dbf',
'/u01/app/oracle/oradata/orcl/undotbs01.dbf',
'/u01/app/oracle/oradata/orcl/cwmlite01.dbf',
'/u01/app/oracle/oradata/orcl/drsys01.dbf',
'/u01/app/oracle/oradata/orcl/example01.dbf',
'/u01/app/oracle/oradata/orcl/indx01.dbf',
'/u01/app/oracle/oradata/orcl/odm01.dbf',
'/u01/app/oracle/oradata/orcl/tools01.dbf',
'/u01/app/oracle/oradata/orcl/users01.dbf',
'/u01/app/oracle/oradata/orcl/xdb01.dbf',
'/u01/app/oracle/oradata/orcl/dbs1-01.dbf',
'/u01/app/oracle/oradata/orcl/dbs1-02.dbf',
'/u01/app/oracle/oradata/orcl/dbs1-03.dbf',
'/u01/app/oracle/oradata/orcl/dbs1-04.dbf',
'/u01/app/oracle/oradata/orcl/dbs1-05.dbf',
'/u01/app/oracle/oradata/orcl/dbs1-06.dbf'
CHARACTER SET AL32UTF8
;
# Take files offline to match current control file.
ALTER DATABASE DATAFILE '/u01/app/oracle/oradata/orcl/dbs1-02.dbf' OFFLINE DROP;
ALTER DATABASE DATAFILE '/u01/app/oracle/oradata/orcl/dbs1-04.dbf' OFFLINE DROP;
# Recovery is required if any of the datafiles are restored backups,
# or if the last shutdown was not normal or immediate.
RECOVER DATABASE
# All logs need archiving and a log switch is needed.
ALTER SYSTEM ARCHIVE LOG ALL;
# Database can now be opened normally.
ALTER DATABASE OPEN;
再重新把 datafile online 即可
No comments:
Post a Comment