Archivelog 模式下datafile header损坏恢复


偷学自大神Roger的博客,自己再做实验:
http://www.killdb.com/2013/01/29/archivelog-%E6%A8%A1%E5%BC%8F%E4%B8%8B%EF%BC%8Cdatafileheader%E6%8D%9F%E5%9D%8F%EF%BC%8C%E5%A6%82%E4%BD%95%E6%81%A2%E5%A4%8D%EF%BC%9F.html

Archivelog 模式下,datafile header损坏,如何恢复?

这里我来模拟下如果是datafile header block损坏的情况下,如何去手工恢复?

—先模拟文件头损坏的情况

BBED> info all
 File#  Name                                                        Size(blks)
 -----  ----                                                        ----------
     1  /oradata/node3/system01.dbf                                      96000
     2  /oradata/node3/sysaux01.dbf                                      69120
     3  /oradata/node3/undotbs01.dbf                                      6400
     4  /oradata/node3/users01.dbf                                         640
     5  /oradata/node3/example01.dbf                                     44240
     6  /oradata/node3/test1.dbf                                         25600

复制一个块覆盖file 6 的block 1
BBED> copy file 4 block 5 to file 6 block 1
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
 File: /oradata/node3/test1.dbf (6)
 Block: 1                Offsets:    0 to  511           Dba:0x01800001
------------------------------------------------------------------------
 1ea20000 05000001 163f0000 00000104 90c10000 04000000 80800f00 00000000 
......
 <32 bytes per line>
 
 
BBED> sum apply
Check value for File 6, Block 1:
current = 0xc190, required = 0xc190


BBED> set file 6 block 1
FILE#          6
BLOCK#         1

BBED> verify
DBVERIFY - Verification starting
FILE = /oradata/node3/test1.dbf
BLOCK = 1

Block 1 is corrupt
Corrupt block relative dba: 0x01000001 (file 0, block 1)
Bad header found during verification
Data in bad block:
 type: 30 format: 2 rdba: 0x01000005
 last change scn: 0x0000.00003f16 seq: 0x1 flg: 0x04
 spare1: 0x0 spare2: 0x0 spare3: 0x0
 consistency value in tail: 0x3f161e01
 check value in block header: 0xc190
 computed block checksum: 0x0


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   : 1
Total Blocks Influx           : 0
Message 531 not found;  product=RDBMS; facility=BBED


此时启动数据库,你会遇到类似如下错误:

SQL> startup
ORACLE instance started.

Total System Global Area  839282688 bytes
Fixed Size    2257880 bytes
Variable Size  545262632 bytes
Database Buffers  289406976 bytes
Redo Buffers    2355200 bytes
Database mounted.
ORA-01122: database file 6 failed verification check
ORA-01110: data file 6: '/oradata/node3/test1.dbf'
ORA-01210: data file header is media corrupt


SQL> recover datafile 6;
ORA-00283: recovery session canceled due to errors
ORA-01110: data file 6: '/oradata/node3/test1.dbf'
ORA-01122: database file 6 failed verification check
ORA-01110: data file 6: '/oradata/node3/test1.dbf'
ORA-01210: data file header is media corrupt


部分情况下,这种情况下是可以recover的。如果说文件头block彻底损坏完了。是不能直接进行修复的。
如果你有备份,那么你可以从备份里面将该datafile restore 出来,然后再去进行recover。
 
这种情况下归档全可以尝试重新创建 datafile

SQL> alter database create datafile 6 as '/oradata/node3/test1.dbf';
alter database create datafile 6 as '/oradata/node3/test1.dbf'
*
ERROR at line 1:
ORA-01178: file 6 created before last CREATE CONTROLFILE, cannot recreate
ORA-01110: data file 6: '/oradata/node3/test1.dbf'

针对这种情况下,创建datafile后,其scn是非常老的,如果你需要进行recover,那么需要从该scn开始至今的所有archivelog。
在这样的情况下起手就可以手工去修复数据文件头,如果是损坏很严重,那么你可以偷懒,从其他datfile copy过去,然后再修改。

+++++++++++ 如下是整个修复的过程,我这里来简单演示一下。


BBED> copy file 4 block 1 to file 6 block 1
 File: /oradata/node3/test1.dbf (6)
 Block: 1                Offsets:    0 to  511           Dba:0x01800001
------------------------------------------------------------------------
 0ba20000 01000001 00000000 00000104 81520000 00000000 0004200b f2cdfb78 
 4e4f4445 33000000 c00c0000 80020000 00200000 04000300 00000000 00000000 
......

 <32 bytes per line>

 
 BBED> map /v 
 File: /oradata/node3/test1.dbf (6)
 Block: 1                                     Dba:0x01800001
------------------------------------------------------------
 Data File Header

 struct kcvfh, 860 bytes                    @0       
    struct kcvfhbfh, 20 bytes               @0       
    struct kcvfhhdr, 76 bytes               @20      
    ub4 kcvfhrdb                            @96      
    struct kcvfhcrs, 8 bytes                @100     
    ub4 kcvfhcrt                            @108     
    ub4 kcvfhrlc                            @112     
    struct kcvfhrls, 8 bytes                @116     
    ub4 kcvfhbti                            @124     
    struct kcvfhbsc, 8 bytes                @128     
    ub2 kcvfhbth                            @136     
    ub2 kcvfhsta                            @138     
    struct kcvfhckp, 36 bytes               @484     
    ub4 kcvfhcpc                            @140     
    ub4 kcvfhrts                            @144     
    ub4 kcvfhccc                            @148     
    struct kcvfhbcp, 36 bytes               @152     
    ub4 kcvfhbhz                            @312     
    struct kcvfhxcd, 16 bytes               @316     
    sword kcvfhtsn                          @332     
    ub2 kcvfhtln                            @336     
    text kcvfhtnm[30]                       @338     
    ub4 kcvfhrfn                            @368     
    struct kcvfhrfs, 8 bytes                @372     
    ub4 kcvfhrft                            @380     
    struct kcvfhafs, 8 bytes                @384     
    ub4 kcvfhbbc                            @392     
    ub4 kcvfhncb                            @396     
    ub4 kcvfhmcb                            @400     
    ub4 kcvfhlcb                            @404     
    ub4 kcvfhbcs                            @408     
    ub2 kcvfhofb                            @412     
    ub2 kcvfhnfb                            @414     
    ub4 kcvfhprc                            @416     
    struct kcvfhprs, 8 bytes                @420     
    struct kcvfhprfs, 8 bytes               @428     
    ub4 kcvfhtrt                            @444     

 ub4 tailchk                                @8188    
 
 这里有个关键性的问题是,我们需要修改哪些地方?

++++++ 第一修改的地方:rdba_kcbh
BBED> p kcvfhbfh
struct kcvfhbfh, 20 bytes                   @0       
   ub1 type_kcbh                            @0        0x0b
   ub1 frmt_kcbh                            @1        0xa2
   ub1 spare1_kcbh                          @2        0x00
   ub1 spare2_kcbh                          @3        0x00
   ub4 rdba_kcbh                            @4        0x01000001
   ub4 bas_kcbh                             @8        0x00000000
   ub2 wrp_kcbh                             @12       0x0000
   ub1 seq_kcbh                             @14       0x01
   ub1 flg_kcbh                             @15       0x04 (KCBHFCKV)
   ub2 chkval_kcbh                          @16       0x5281
   ub2 spare3_kcbh                          @18       0x0000
   
这里是0×0100001,表示file 4 block 1,我们要将其改成正确的值:file 6 block 1 。 后面block号不变,即应该是0x01800001

BBED> modify /x 01008001 offset 4
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
 File: /oradata/node3/test1.dbf (6)
 Block: 1                Offsets:    4 to  515           Dba:0x01800001
------------------------------------------------------------------------
 01008001 00000000 00000104 81520000 00000000 0004200b f2cdfb78 4e4f4445 
 33000000 c00c0000 80020000 00200000 04000300 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 0f3f0000 00000000 8dc92131 93de0a36 d4a16b00 00000000 00000000 00000000 
 00000000 00000400 a6000000 b2e90a36 a4000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 04000000 05005553 45525300 00000000 00000000 00000000 
 00000000 00000000 00000000 04000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bcdd0a36 
 cda06b00 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 0ca86b00 00000000 9be90a36 01000000 01000000 c2090000 10009a04 02000000 

 <32 bytes per line>

 ++++++ 第2个修改的地方:kccfhfsz 即文件大小
 
 BBED> p kcvfhhdr
struct kcvfhhdr, 76 bytes                   @20      
   ub4 kccfhswv                             @20       0x00000000
   ub4 kccfhcvn                             @24       0x0b200400
   ub4 kccfhdbi                             @28       0x78fbcdf2
   text kccfhdbn[0]                         @32      N
   text kccfhdbn[1]                         @33      O
   text kccfhdbn[2]                         @34      D
   text kccfhdbn[3]                         @35      E
   text kccfhdbn[4]                         @36      3
   text kccfhdbn[5]                         @37       
   text kccfhdbn[6]                         @38       
   text kccfhdbn[7]                         @39       
   ub4 kccfhcsq                             @40       0x00000cc0
   ub4 kccfhfsz                             @44       0x00000280  --这里
   s_blkz kccfhbsz                          @48       0x00
   ub2 kccfhfno                             @52       0x0004
   ub2 kccfhtyp                             @54       0x0003
   ub4 kccfhacid                            @56       0x00000000
   ub4 kccfhcks                             @60       0x00000000
   text kccfhtag[0]                         @64       
   
  ......
  
首先你可以从os上去查看数据文件的实际大小,如下:
[oracle@node3 node3]$  ll test1.dbf 
-rw-r----- 1 oracle dba 209723392 Mar 17 04:25 test1.dbf

不过需要注意一点的是,dbfile的大小应该你操作系统上看到的实际大小减去一个db block_size,因为还存在一个os block header。

(209723392-8192)/8192=25600
25600=6400

BBED>  modify /x 00640000 offset 44
 File: /oradata/node3/test1.dbf (6)
 Block: 1                Offsets:   44 to  555           Dba:0x01800001
------------------------------------------------------------------------
 00640000 00200000 06000300 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 aafc6900 00000000 
 98210936 93de0a36 d4a16b00 00000000 00000000 00000000 00000000 00000400 
 a8000000 921a0b36 a7000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 07000000 05005445 53543100 00000000 00000000 00000000 00000000 00000000 
 00000000 06000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 bcdd0a36 cda06b00 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 93a26b36 00000000 
 6fdf0a36 01000000 01000000 c2090000 10009a04 02000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 

 <32 bytes per line>



++++++ 第3个修改的地方:kccfhfno datafile文件号
BBED> modify /x 06 offset 52
 File: /oradata/node3/test1.dbf (6)
 Block: 1                Offsets:   52 to  563           Dba:0x01800001
------------------------------------------------------------------------
 06000300 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 0f3f0000 00000000 8dc92131 93de0a36 
 d4a16b00 00000000 00000000 00000000 00000000 00000400 a6000000 b2e90a36 
 a4000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 04000000 05005553 
 45525300 00000000 00000000 00000000 00000000 00000000 00000000 04000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 bcdd0a36 cda06b00 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 0ca86b00 00000000 9be90a36 01000000 
 01000000 c2090000 10009a04 02000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 

 <32 bytes per line>
 
 ++++++ 第4个修改的地方:kscnbas v$datafile.create_change#
 
BBED> p kcvfhcrs
struct kcvfhcrs, 8 bytes                    @100     
   ub4 kscnbas                              @100      0x00003f0f
   ub2 kscnwrp                              @104      0x0000

6945962 转换为 16进制 69fcaa

BBED> modify /x aafc69 offset 100
 File: /oradata/node3/test1.dbf (6)
 Block: 1                Offsets:  100 to  611           Dba:0x01800001
------------------------------------------------------------------------
 aafc6900 00000000 8dc92131 93de0a36 d4a16b00 00000000 00000000 00000000 
 00000000 00000400 a6000000 b2e90a36 a4000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 04000000 05005553 45525300 00000000 00000000 00000000 
 00000000 00000000 00000000 04000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bcdd0a36 
 cda06b00 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 0ca86b00 00000000 9be90a36 01000000 01000000 c2090000 10009a04 02000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 

 <32 bytes per line>
 
++++++++ 第5个修改的地方:kcvfhcrt 表示v$datafile.create_time

BBED> p kcvfhcrt
ub4 kcvfhcrt                                @108      0x3121c98d

此时你将数据库mount,可以通过v$datafile直接查询得知,如下:
SQL> set lines 120
SQL> col creation_time_file for 999999999999999
SQL> col creation_name_scn for 999999999999999
SQL> select file#,to_char(creation_time,'yyyy-mm-dd hh24:mi:ss') creation_time_file,
 (to_char(creation_time,'yyyy')-1988)*12*31*24*3600+
 (to_char(creation_time,'mm')-1)*31*24*3600
 +(to_char(creation_time,'dd')-1)*24*3600
 +to_char(creation_time,'hh24')*3600
 +to_char(creation_time,'mi')*60
 +to_char(creation_time,'ss') creation_name_scn
 from v$datafile order by 1;

     FILE# CREATION_TIME_FILE  CREATION_NAME_SCN
---------- -------------------------------------- -----------------
 1 2013-08-24 11:37:33  824297853
 2 2013-08-24 11:37:37  824297857
 3 2013-08-24 12:07:19  824299639
 4 2013-08-24 11:37:49  824297869
 5 2016-02-02 12:03:21  902750601
 6 2016-03-15 16:28:08  906568088  --转换后 36092198

6 rows selected.

或者你可以直接dump controlfile,然后从trace中获得该信息。

修改为如下:

 BBED> modify /x  98210936 offset 108
 File: /oradata/node3/test1.dbf (6)
 Block: 1                Offsets:  108 to  619           Dba:0x01800001
------------------------------------------------------------------------
 98210936 93de0a36 d4a16b00 00000000 00000000 00000000 00000000 00000400 
 a6000000 b2e90a36 a4000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 04000000 05005553 45525300 00000000 00000000 00000000 00000000 00000000 
 00000000 04000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 bcdd0a36 cda06b00 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 0ca86b00 00000000 
 9be90a36 01000000 01000000 c2090000 10009a04 02000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 

 <32 bytes per line>
 
 ++++++++ 第6个修改的地方:kcvfhtsn 表示表空间号v$datafile.ts#

 BBED>  p kcvfhtsn
sword kcvfhtsn                              @332      4

通过v$datafile查询结果:
SQL> select file#,ts# from v$datafile order by 1;

     FILE#  TS#
---------- ----------
 1    0
 2    1
 3    2
 4    4
 5    6
 6    7
 
修改为:
BBED> modify /x 07 offset 332
 File: /oradata/node3/test1.dbf (6)
 Block: 1                Offsets:  332 to  843           Dba:0x01800001
------------------------------------------------------------------------
 07000000 05005553 45525300 00000000 00000000 00000000 00000000 00000000 
 00000000 04000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 bcdd0a36 cda06b00 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 0ca86b00 00000000 
 9be90a36 01000000 01000000 c2090000 10009a04 02000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 0d000d00 0d000100 
 00000000 00000000 00000000 02000001 03000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 

 <32 bytes per line>

 
 ++++++++ 第7个修改的地方: kcvfhrfn v$datafile.rfile# 即相对文件号
 
 
BBED> p kcvfhrfn
ub4 kcvfhrfn                                @368      0x00000004

BBED> modify /x 06 offset 368
 File: /oradata/node3/test1.dbf (6)
 Block: 1                Offsets:  368 to  879           Dba:0x01800001
------------------------------------------------------------------------
 06000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 bcdd0a36 cda06b00 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 0ca86b00 00000000 9be90a36 
 01000000 01000000 c2090000 10009a04 02000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 0d000d00 0d000100 00000000 
 00000000 00000000 02000001 03000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 

 <32 bytes per line>
 
 +++++++++ 第8个修改的地方:kcvfhtnm 表空间名称即v$tablespace.name

BBED> p kcvfhtnm
text kcvfhtnm[0]                            @338     U
text kcvfhtnm[1]                            @339     S
text kcvfhtnm[2]                            @340     E
text kcvfhtnm[3]                            @341     R
text kcvfhtnm[4]                            @342     S
text kcvfhtnm[5]                            @343      
text kcvfhtnm[6]                            @344      
text kcvfhtnm[7]                            @345      
text kcvfhtnm[8]                            @346      
text kcvfhtnm[9]                            @347      
text kcvfhtnm[10]                           @348      
text kcvfhtnm[11]                           @349      
text kcvfhtnm[12]                           @350      
text kcvfhtnm[13]                           @351      
text kcvfhtnm[14]                           @352      
text kcvfhtnm[15]                           @353      
text kcvfhtnm[16]                           @354      
text kcvfhtnm[17]                           @355      
text kcvfhtnm[18]                           @356      
text kcvfhtnm[19]                           @357      
text kcvfhtnm[20]                           @358      
text kcvfhtnm[21]                           @359      
text kcvfhtnm[22]                           @360      
text kcvfhtnm[23]                           @361      
text kcvfhtnm[24]                           @362      
text kcvfhtnm[25]                           @363      
text kcvfhtnm[26]                           @364      
text kcvfhtnm[27]                           @365      
text kcvfhtnm[28]                           @366      
text kcvfhtnm[29]                           @367      
 
BBED> d /v offset 338
 File: /oradata/node3/test1.dbf (6)
 Block: 1       Offsets:  338 to  849  Dba:0x01800001
-------------------------------------------------------
 55534552 53000000 00000000 00000000 l USERS...........
 00000000 00000000 00000000 00000600 l ................
 ......
 <16 bytes per line>
 
 我们只要知道表空间名称,转换一下即可:
SQL> select name from v$tablespace where ts#=7;
NAME
------------------------------------------------------------
TEST1

SQL> select dump('TEST1',16) from dual;

DUMP('TEST1',16)
--------------------------------------------------------
Typ=96 Len=5: 54,45,53,54,31

SQL> select dump ('USERS',16) from dual;

DUMP('USERS',16)
--------------------------------------------------------
Typ=96 Len=5: 55,53,45,52,53


修改为:


BBED>  modify  /x 54455354
 File: /oradata/node3/test1.dbf (6)
 Block: 1                Offsets:  338 to  849           Dba:0x01800001
------------------------------------------------------------------------
 54455354 53000000 00000000 00000000 00000000 00000000 00000000 00000600 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 0000bcdd 0a36cda0 6b000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000ca8 6b000000 00009be9 0a360100 
 00000100 0000c209 00001000 9a040200 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000d00 0d000d00 01000000 00000000 
 00000000 00000200 00010300 00000000 00000000 00000000 00000000 00000000 

 <32 bytes per line>
 
 BBED> modify /x 31 offset 342
 File: /oradata/node3/test1.dbf (6)
 Block: 1                Offsets:  342 to  853           Dba:0x01800001
------------------------------------------------------------------------
 31000000 00000000 00000000 00000000 00000000 00000000 00000600 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 0000bcdd 0a36cda0 6b000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000ca8 6b000000 00009be9 0a360100 00000100 
 0000c209 00001000 9a040200 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000d00 0d000d00 01000000 00000000 00000000 
 00000200 00010300 00000000 00000000 00000000 00000000 00000000 00000000 

 <32 bytes per line>


这里补充一下,如果你的表空间名称跟实际不符,可能还需要修改kcvfhtln,表示长度。我这里是users即为5.

BBED> p kcvfhtln
ub2 kcvfhtln                                @336      0x0005

test1 长度也是5 不用改啦

BBED> sum apply
Check value for File 2, Block 1:
current = 0x24ca, required = 0x24ca

尝试启动数据库

SQL> startup
ORACLE instance started.

Total System Global Area  839282688 bytes
Fixed Size    2257880 bytes
Variable Size  545262632 bytes
Database Buffers  289406976 bytes
Redo Buffers    2355200 bytes
Database mounted.
ORA-01122: database file 6 failed verification check
ORA-01110: data file 6: '/oradata/node3/test1.dbf'
ORA-01210: data file header is media corrupt


看来还有地方不对,我们来查询下v$datafile看下信息:

SQL>  SELECT file#,rfile#,CREATION_CHANGE#,CHECKPOINT_CHANGE# ,UNRECOVERABLE_CHANGE#,LAST_CHANGE#,OFFLINE_CHANGE# FROM v$datafile ORDER BY 1;

     FILE#     RFILE# CREATION_CHANGE# CHECKPOINT_CHANGE# UNRECOVERABLE_CHANGE# LAST_CHANGE# OFFLINE_CHANGE#
---------- ---------- ---------------- ------------------ --------------------- ------------ ---------------
 1    1     7  7053783      0      7053779
 2    2  1834  7053783      0      7053779
 3    3923328  7053783      0      7053779
 4    4 16143  7053783      0      7053779
 5    5952510  7053783      0      7053779
 6    6       6945962  7053971      0    0
 
 
可以看到检查点信息不一致,这是因为开始我为了演示模拟中途open过了一次。

而目前datafile 6的实际scn跟实际不符:


BBED> set file 6 block 1
FILE#          6
BLOCK#         1

BBED> p kcvfhckp
struct kcvfhckp, 36 bytes                   @484     
   struct kcvcpscn, 8 bytes                 @484     
      ub4 kscnbas                           @484      0x006ba80c  --checkpoint转换后 7055372
      ub2 kscnwrp                           @488      0x0000
   ub4 kcvcptim                             @492      0x360ae99b  --checkpoint time 转换 906684827
   ub2 kcvcpthr                             @496      0x0001
   union u, 12 bytes                        @500     
      struct kcvcprba, 12 bytes             @500     
         ub4 kcrbaseq                       @500      0x00000001
         ub4 kcrbabno                       @504      0x000009c2
         ub2 kcrbabof                       @508      0x0010
   ub1 kcvcpetb[0]                          @512      0x02
   ub1 kcvcpetb[1]                          @513      0x00
   ub1 kcvcpetb[2]                          @514      0x00
   ub1 kcvcpetb[3]                          @515      0x00
   ub1 kcvcpetb[4]                          @516      0x00
   ub1 kcvcpetb[5]                          @517      0x00
   ub1 kcvcpetb[6]                          @518      0x00
   ub1 kcvcpetb[7]                          @519      0x00
   
   
然而我们datafile 2的实际情况如何呢? 来查询v$datafile确认一下:
SQL> select file#,to_char(CHECKPOINT_TIME,'yyyy-mm-dd hh24:mi:ss') CHECKPOINT_TIME_file,
      (to_char(CHECKPOINT_TIME,'yyyy')-1988)*12*31*24*3600+
      (to_char(CHECKPOINT_TIME,'mm')-1)*31*24*3600
      +(to_char(CHECKPOINT_TIME,'dd')-1)*24*3600
      +to_char(CHECKPOINT_TIME,'hh24')*3600
      +to_char(CHECKPOINT_TIME,'mi')*60
      +to_char(CHECKPOINT_TIME,'ss') CHECKPOINT_TIME_scn
      from v$datafile order by 1;  2    3    4    5    6    7    8  

     FILE# CHECKPOINT_TIME_FILE   CHECKPOINT_TIME_SCN
---------- -------------------------------------- -------------------
 1 2016-03-17 00:06:46    906682006
 2 2016-03-17 00:06:46    906682006
 3 2016-03-17 00:06:46    906682006
 4 2016-03-17 00:06:46    906682006
 5 2016-03-17 00:06:46    906682006
 6 2016-03-17 00:10:23    906682223

6 rows selected.


 我们可以看到,checkpoint scn和time都不对,所以还需要修改下:

 7053971 =6BA293
 
BBED> modify /x 93a26b offset 484
 File: /oradata/node3/test1.dbf (6)
 Block: 1                Offsets:  484 to  995           Dba:0x01800001
------------------------------------------------------------------------
 93a26b00 00000000 9be90a36 01000000 01000000 c2090000 10009a04 02000000 
......
 <32 bytes per line>
 
 
 906682223 =  360ADF6F
 
 BBED>  d /v offset 492
 File: /oradata/node3/test1.dbf (6)
 Block: 1       Offsets:  492 to 1003  Dba:0x01800001
-------------------------------------------------------
 9be90a36 01000000 01000000 c2090000 l ...6............
 10009a04 02000000 00000000 00000000 l ................
......
 <16 bytes per line>
 
BBED> set file 6 block 1 offset 492
FILE#          6
BLOCK#         1
OFFSET         492

BBED>  modify /x 6fdf0a36  offset 492
 File: /oradata/node3/test1.dbf (6)
 Block: 1                Offsets:  492 to 1003           Dba:0x01800001
------------------------------------------------------------------------
 6fdf0a36 01000000 01000000 c2090000 10009a04 02000000 00000000 00000000 
......

 <32 bytes per line>
 
 
 修改完成之后我们可以通过dbv来检查下,看看文件头修改是否都正确,如下:
 
 [oracle@node3 trace]$ dbv file=/oradata/node3/test1.dbf start=1 end=2
DBVERIFY: Release 11.2.0.4.0 - Production on Thu Mar 17 03:42:23 2016
Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.
DBVERIFY - Verification starting : FILE = /oradata/node3/test1.dbf

DBVERIFY - Verification complete

Total Pages Examined         : 2
Total Pages Processed (Data) : 0
Total Pages Failing   (Data) : 0
Total Pages Processed (Index): 0
Total Pages Failing   (Index): 0
Total Pages Processed (Other): 2
Total Pages Processed (Seg)  : 0
Total Pages Failing   (Seg)  : 0
Total Pages Empty            : 0
Total Pages Marked Corrupt   : 0
Total Pages Influx           : 0
Total Pages Encrypted        : 0
Highest block SCN            : 7039342 (0.7039342)


最后我们再来将数据库open,如下:


SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-01122:database file 6 failed verification check
ORA-01110: data file 6: '/oradata/node3/test1.dbf'
ORA-01207: file is more recent than control file - old control file

SQL> recover datafile 6;
ORA-00283: recovery session canceled due to errors
ORA-01122: database file 6 failed verification check
ORA-01110: data file 6: '/oradata/node3/test1.dbf'
ORA-01207: file is more recent than control file - old control file

遇到过程了,先不要着急,我们来看下这个错误是什么意思? 从字面上的含义来看,意思是说改datafile的信息
可能比controlfile中的部分信息还要新,这个有可能,因为最开始我offline 文件后,open过,然后接着修改
文件头的时候的信息又是参考其他datafile header block来的,所以file 2的信息可能比以前的信息要新。
既然如此,那么我们重建下controlfile即可,注意要用noresetlogs方式创建:
 
SQL> oradebug setmypid
Statement processed.
SQL> alter database backup controlfile to trace;

Database altered.

SQL> oradebug tracefile_name
/u01/app/oracle/diag/rdbms/node3/node3/trace/node3_ora_31312.trc

CREATE CONTROLFILE REUSE DATABASE "NODE3" NORESETLOGS  ARCHIVELOG
    MAXLOGFILES 16
    MAXLOGMEMBERS 3
    MAXDATAFILES 100
    MAXINSTANCES 8
    MAXLOGHISTORY 292
LOGFILE
  GROUP 1 '/oradata/node3/redo01.log'  SIZE 50M BLOCKSIZE 512,
  GROUP 2 '/oradata/node3/redo02.log'  SIZE 50M BLOCKSIZE 512,
  GROUP 3 '/oradata/node3/redo03.log'  SIZE 50M BLOCKSIZE 512
-- STANDBY LOGFILE
DATAFILE
  '/oradata/node3/system01.dbf',
  '/oradata/node3/sysaux01.dbf',
  '/oradata/node3/undotbs01.dbf',
  '/oradata/node3/users01.dbf',
  '/oradata/node3/example01.dbf',
  --'/oradata/node3/test1.dbf'
CHARACTER SET WE8MSWIN1252;

SQL> alter database open;
Database altered.

SQL> select name,file#,status from v$datafile;

NAME  FILE# STATUS
--------------------------------
/oradata/node3/system01.dbf    1   SYSTEM
/oradata/node3/sysaux01.dbf    2   ONLINE
/oradata/node3/undotbs01.dbf   3   ONLINE
/oradata/node3/users01.dbf     4   ONLINE
/oradata/node3/example01.dbf   5   ONLINE
/u01/app/oracle/product/11.2.0/db_1/dbs/MISSING00006 6 RECOVER

SQL> alter database rename file '/u01/app/oracle/product/11.2.0/db_1/dbs/MISSING00006' to '/oradata/node3/test1.dbf';
Database altered.

SQL> recover datafile 6;
Media recovery complete.

SQL> alter database datafile 6 online;
Database altered.

简单的小总结,针对文件头损坏的情况下,在恢复的情况下可能需要修复如下内容:
1. rdba_kcbh (offset 4)即使文件头block的rdba地址
2. kccfhfsz (offset 44) 即文件大小
3. kccfhfno (offset 52) 即datafile文件号
4. kscnbas (offset 100) 即v$datafile.create_change#
5. kcvfhcrt (offset 108) 即v$datafile.create_time
6. kcvfhtsn (offset 332) 即v$datafile.ts#,表示表空间号
7. kcvfhrfn (offset 368) 即v$datafile.rfile#, 表示相对文件号
8. kcvfhtnm (offset 338) 即v$tablespace.name,表示表空间名称(根据实际情况,可能还会需要修改kcvfhtln,表示表空间名称字符长度)
9. kscnbas (offset 484) 即checkpoint scn
10.kcvcptim (offset 492) 即last checkpoint time.

这个总结并不全面,可能很多情况还需要修改一些其他的地方,另外如果是system datafile,那么也会有所不同,比如oracle
数据库中的bootstrap$对象是存储在file 1 block 337中.而system 表空间的第一个datafile header中会有个root rdba地址是指向
bootstrap地址的,在11gR2版本中该地址变为file 1 block 521(不同版本可能有所差异).
<think>我们正在处理一个Oracle数据库文件路径配置的问题。用户希望将数据库的各种文件(归档日志、控制文件、数据文件、在线日志)存储到特定目录下的四个子文件夹中。 根据引用[1][2][3],我们知道Oracle数据库的文件包括归档日志(ARCHIVELOG)、控制文件(CONTROLFILE)、数据文件(DATAFILE)和在线日志(ONLINELOG)。这些文件的路径可以通过数据库参数或创建数据库/控制文件时指定。 具体步骤: 1. 确保目标文件夹存在(ARCHIVELOG、CONTROLFILE、DATAFILE、ONLINELOG)。 2. 设置数据库参数,将不同类型的文件指向对应的文件夹。 对于归档日志(ARCHIVELOG): 设置参数`log_archive_dest_1`,例如: ```sql ALTER SYSTEM SET log_archive_dest_1='location=/path/to/RBSCM/ARCHIVELOG' SCOPE=both; ``` 对于控制文件(CONTROLFILE): 控制文件的位置由参数`control_files`指定。我们可以修改这个参数,但注意:修改控制文件位置需要关闭数据库并移动现有控制文件,然后重新启动。 ```sql -- 首先查看当前控制文件位置 SHOW PARAMETER control_files; -- 然后关闭数据库,移动控制文件到新位置,再修改参数: ALTER SYSTEM SET control_files='/path/to/RBSCM/CONTROLFILE/control01.ctl', '/path/to/RBSCM/CONTROLFILE/control02.ctl' SCOPE=spfile; ``` 对于数据文件(DATAFILE)和在线日志(ONLINELOG): 这些文件在创建表空间或重做日志组时指定。如果要改变现有文件的位置,需要移动文件并使用`ALTER DATABASE RENAME FILE`命令(如引用[2]所示)。 但是,用户提到的是“下载后”设置,可能是指新安装的数据库或者新创建的数据库。如果是新创建的数据库,可以在创建数据库时指定这些路径。 创建数据库时指定文件路径的示例: ```sql CREATE DATABASE mydb USER SYS IDENTIFIED BY password USER SYSTEM IDENTIFIED BY password LOGFILE GROUP 1 ('/path/to/RBSCM/ONLINELOG/redo01a.log', '/path/to/RBSCM/ONLINELOG/redo01b.log') SIZE 100M, GROUP 2 ('/path/to/RBSCM/ONLINELOG/redo02a.log', '/path/to/RBSCM/ONLINELOG/redo02b.log') SIZE 100M MAXLOGFILES 5 MAXLOGMEMBERS 5 MAXLOGHISTORY 1 MAXDATAFILES 100 MAXINSTANCES 1 CHARACTER SET AL32UTF8 NATIONAL CHARACTER SET AL16UTF16 DATAFILE '/path/to/RBSCM/DATAFILE/system01.dbf' SIZE 325M REUSE SYSAUX DATAFILE '/path/to/RBSCM/DATAFILE/sysaux01.dbf' SIZE 325M REUSE DEFAULT TABLESPACE users DATAFILE '/path/to/RBSCM/DATAFILE/users01.dbf' SIZE 500M REUSE AUTOEXTEND ON MAXSIZE UNLIMITED DEFAULT TEMPORARY TABLESPACE tempts1 TEMPFILE '/path/to/RBSCM/DATAFILE/temp01.dbf' SIZE 20M REUSE UNDO TABLESPACE undotbs DATAFILE '/path/to/RBSCM/DATAFILE/undotbs01.dbf' SIZE 200M REUSE AUTOEXTEND ON MAXSIZE UNLIMITED; ``` 对于归档日志,还需要设置数据库为归档模式archivelog mode)并设置归档路径(如前面所述)。 如果是一个已经存在的数据库,需要移动文件,步骤较为复杂: 1. 关闭数据库。 2. 移动文件到新位置。 3. 启动数据库到mount状态。 4. 使用`ALTER DATABASE RENAME FILE`命令更新文件路径(如引用[2]所示)。 5. 打开数据库。 注意:在移动文件之前,请确保数据库处于一致状态(正常关闭)。 因此,根据用户的需求,我们可以总结为: - 如果是新创建数据库,在创建时指定路径。 - 如果是现有数据库,则需要移动文件并更新数据库中的文件路径。 由于用户要求设置到全局变量RBSCM文件夹下的四个子文件夹,我们假设路径为:`/path/to/RBSCM/`,其中包含四个子目录:ARCHIVELOG、CONTROLFILE、DATAFILE、ONLINELOG。 这里我们假设用户已经创建了这些目录,并且Oracle进程用户(通常是oracle)有读写权限。 具体步骤(针对现有数据库): 1. 设置归档日志路径(动态参数,可以在线修改): ```sql ALTER SYSTEM SET log_archive_dest_1='location=/path/to/RBSCM/ARCHIVELOG' SCOPE=both; ``` 2. 移动控制文件: - 关闭数据库:`shutdown immediate` - 移动控制文件到`/path/to/RBSCM/CONTROLFILE/`目录下 - 修改参数文件中的`control_files`参数指向新的位置 - 启动数据库到mount(因为控制文件位置改变,需要读取新的控制文件):`startup mount` 3. 移动数据文件和在线日志文件: - 关闭数据库:`shutdown immediate` - 移动数据文件到`/path/to/RBSCM/DATAFILE/`,移动在线日志文件到`/path/to/RBSCM/ONLINELOG/` - 启动数据库到mount:`startup mount` - 使用`ALTER DATABASE RENAME FILE`命令逐个更改文件路径(需要知道每个文件的原始路径和当前路径) 例如: ```sql ALTER DATABASE RENAME FILE '/old/path/system01.dbf' TO '/path/to/RBSCM/DATAFILE/system01.dbf'; -- 对于在线日志文件,如引用[2]所示: ALTER DATABASE RENAME FILE '/old/path/redo01.log' TO '/path/to/RBSCM/ONLINELOG/redo01.log'; ``` - 然后打开数据库:`alter database open;` 注意:移动在线日志文件时,由于在线日志文件是活动的,在关闭数据库后移动,然后重命名。但是,如果数据库在打开状态下重命名在线日志文件,需要先将其状态置为INACTIVE(如果当前是ACTIVE或CURRENT,则不能重命名,需要先切换日志)。 由于步骤复杂,建议在操作前备份数据库。 另外,用户提到“全局变量RBSCM”,可能是指一个环境变量。在Oracle中,我们可以使用环境变量来指定路径,例如在参数文件中使用`${RBSCM}`来表示该变量。但是,这需要我们在Oracle参数文件中使用环境变量,并且确保在启动数据库时该环境变量已经设置。 例如,设置控制文件参数: ```sql control_files = '${RBSCM}/CONTROLFILE/control01.ctl', '${RBSCM}/CONTROLFILE/control02.ctl' ``` 但是,Oracle参数文件本身不支持环境变量扩展(除非使用动态注册,如通过Oracle的`env`文件设置)。通常,我们可以在启动数据库之前设置环境变量,然后在参数文件中使用这个环境变量,但Oracle数据库参数文件并不直接解析环境变量。 替代方案:在创建数据库时,使用shell脚本定义环境变量,并在创建命令中使用该变量。例如: ```bash export RBSCM=/path/to/RBSCM sqlplus / as sysdba <<EOF CREATE DATABASE ... DATAFILE '${RBSCM}/DATAFILE/system01.dbf' ... ... EOF ``` 但是,在数据库运行期间,参数文件中的路径不能使用环境变量(除非使用Oracle的OMF管理,并且设置`db_create_file_dest`等参数,让Oracle自动管理文件位置)。 因此,如果用户希望使用环境变量来指定基础路径,可以考虑使用Oracle的OMF(Oracle Managed Files)特性,通过设置以下参数: - `db_create_file_dest`:数据文件和临时文件的默认位置 - `db_create_online_log_dest_1`:在线日志文件和控制文件的默认位置 - `db_recovery_file_dest`:快速恢复区,通常用于归档日志和备份 例如: ```sql ALTER SYSTEM SET db_create_file_dest = '/path/to/RBSCM/DATAFILE'; ALTER SYSTEM SET db_create_online_log_dest_1 = '/path/to/RBSCM/ONLINELOG'; ALTER SYSTEM SET db_recovery_file_dest = '/path/to/RBSCM/ARCHIVELOG'; -- 注意:归档日志通常放在恢复区 ``` 但是,控制文件默认也会放在`db_create_online_log_dest_1`指定的位置,而数据文件放在`db_create_file_dest`,在线日志放在`db_create_online_log_dest_1`。归档日志则放在`db_recovery_file_dest`指定的恢复区。 注意:使用OMF后,文件命名由Oracle自动管理。 因此,如果用户希望使用环境变量,可以在Oracle初始化参数中设置这些参数,并在操作系统中设置环境变量`RBSCM`,然后在参数值中引用该环境变量。但是,Oracle参数文件本身不支持环境变量,所以我们必须在启动实例之前,通过操作系统的环境变量来设置参数值。这可以通过在启动数据库之前,在启动数据库的脚本中动态设置参数值。 例如,在启动脚本中(如`startup.sh`): ```bash export RBSCM=/path/to/RBSCM sqlplus / as sysdba <<EOF startup pfile='/tmp/init.ora'; exit; EOF ``` 而`/tmp/init.ora`文件内容可以包含: ``` db_create_file_dest='${RBSCM}/DATAFILE' db_create_online_log_dest_1='${RBSCM}/ONLINELOG' db_recovery_file_dest='${RBSCM}/ARCHIVELOG' ...其他参数... ``` 但是,这里有一个问题:在参数文件中,`${RBSCM}`不会被shell扩展,因为参数文件是文本文件,由Oracle实例读取。所以,我们需要在创建pfile时,用实际值替换环境变量。 另一种方法是:在启动实例之前,生成一个包含实际路径的pfile: ```bash export RBSCM=/path/to/RBSCM cat > /tmp/init.ora <<EOL db_create_file_dest='${RBSCM}/DATAFILE' db_create_online_log_dest_1='${RBSCM}/ONLINELOG' db_recovery_file_dest='${RBSCM}/ARCHIVELOG' EOL ``` 这样,在启动时,参数文件中的路径已经是实际路径。 综上所述,我们可以根据用户的需求选择不同的方法。如果用户希望使用环境变量,那么需要在启动数据库之前,通过脚本将环境变量展开到参数文件中。 总结: 1. 创建四个目录:ARCHIVELOG、CONTROLFILE、DATAFILE、ONLINELOG(注意:在OMF中,控制文件和在线日志放在同一个参数指定的位置,所以可能需要调整,比如将CONTROLFILE和ONLINELOG合并到一个目录?或者使用两个不同的参数?) 2. 设置Oracle参数,使用OMF特性,分别指定数据文件、在线日志文件(包括控制文件)和归档日志的路径。 3. 或者,不使用OMF,而是手动指定每个文件的位置(在创建数据库时或之后移动文件并重命名)。 注意:OMF参数`db_create_online_log_dest_1`用于指定在线日志文件和控制文件的创建位置。控制文件会创建在该目录下,而在线日志也会在该目录下。所以,如果用户希望将控制文件和在线日志分开,OMF可能无法满足(因为控制文件和在线日志使用同一个参数)。此时,只能手动指定。 因此,如果用户坚持要分开四个目录,我们可能需要手动管理文件位置(即不使用OMF),然后按照前面所述的方法移动文件并修改参数。 由于问题复杂,我们提供两种方案供用户选择。 方案一:使用OMF(简单,但控制文件和在线日志在同一个目录) - 设置参数: ```sql ALTER SYSTEM SET db_create_file_dest = '/path/to/RBSCM/DATAFILE'; ALTER SYSTEM SET db_create_online_log_dest_1 = '/path/to/RBSCM/ONLINELOG'; -- 控制文件和在线日志都在这里 ALTER SYSTEM SET db_recovery_file_dest = '/path/to/RBSCM/ARCHIVELOG'; ``` - 然后,控制文件会自动创建在`db_create_online_log_dest_1`指定的目录下,但用户希望控制文件在CONTROLFILE目录下,这就不符合了。 方案二:手动管理(复杂,但可以精确控制) - 按照前面所述步骤,分别移动文件并修改参数。 因此,我们可能需要折中:将控制文件和在线日志放在同一个目录(比如ONLINELOG)下,或者将控制文件放在CONTROLFILE目录,而在线日志放在ONLINELOG目录,但这样就需要在创建数据库时分别指定,并且在OMF中无法实现。 鉴于用户要求四个独立的文件夹,我们选择手动管理方案。 步骤总结(手动管理): 1. 创建四个目录,并确保Oracle用户有权限。 2. 设置归档日志路径(动态参数,立即生效)。 3. 移动控制文件: a. 关闭数据库。 b. 移动控制文件到CONTROLFILE目录。 c. 修改参数文件中的`control_files`参数指向新位置。 d. 启动数据库到mount,然后open。 4. 移动数据文件: a. 将表空间置于脱机状态(或关闭数据库后操作)。 b. 移动数据文件。 c. 使用`ALTER DATABASE RENAME FILE`命令更新数据字典。 d. 将表空间联机。 5. 移动在线日志文件: a. 关闭数据库。 b. 移动在线日志文件。 c. 启动到mount状态。 d. 使用`ALTER DATABASE RENAME FILE`命令更新每个在线日志文件的位置。 e. 打开数据库。 注意:移动在线日志文件时,如果文件是当前活动的,需要先切换日志,确保要移动的日志文件状态为INACTIVE。在关闭数据库后移动,可以避免这个问题。 由于步骤较多,我们建议用户参考Oracle官方文档或寻求专业DBA帮助,并在操作前进行完整备份。 根据引用[3],我们还可以通过重新创建控制文件来指定新的文件路径,但重新创建控制文件需要知道所有数据文件、日志文件的位置,并且需要备份控制文件,风险较高。 因此,我们推荐使用`ALTER DATABASE RENAME FILE`命令(如引用[2]所示)来移动文件。 最后,回答用户的问题:如何设置Oracle数据库下载后文件路径到指定文件夹? 答:可以通过修改数据库参数和移动文件的方式实现,具体步骤如上。但请注意,这是一个涉及数据库物理结构的操作,务必谨慎并在测试环境验证后再进行。 由于问题复杂,我们提供一个大致的步骤指南,具体操作需要根据实际环境调整。 相关问题: 1. 如何设置Oracle数据库的归档日志路径? 2. 如何移动Oracle数据库的控制文件? 3. 如何移动Oracle数据库的数据文件? 4. 如何移动Oracle数据库的在线日志文件? 5. 使用OMF管理Oracle文件有什么优缺点?</think>### 设置Oracle数据库文件路径的方法 要配置Oracle数据库将文件存储到指定目录下的四个子文件夹(`ARCHIVELOG`, `CONTROLFILE`, `DATAFILE`, `ONLINELOG`),需通过以下步骤实现: --- #### **1. 创建目录结构** 在操作系统层创建目标文件夹(以Linux为例): ```bash mkdir -p /path/to/RBSCM/{ARCHIVELOG,CONTROLFILE,DATAFILE,ONLINELOG} chown -R oracle:oinstall /path/to/RBSCM # 授权Oracle用户 ``` --- #### **2. 配置归档日志路径(ARCHIVELOG)** ```sql ALTER SYSTEM SET log_archive_dest_1='LOCATION=/path/to/RBSCM/ARCHIVELOG' SCOPE=both; ``` 此命令将归档日志定向到指定目录[^1]。 --- #### **3. 移动控制文件(CONTROLFILE)** ```sql -- 查看当前控制文件位置 SELECT name FROM v$controlfile; -- 关闭数据库 SHUTDOWN IMMEDIATE; -- 移动文件到新位置(操作系统命令) mv /old/path/control01.ctl /path/to/RBSCM/CONTROLFILE/ -- 更新控制文件路径 STARTUP MOUNT; ALTER SYSTEM SET control_files='/path/to/RBSCM/CONTROLFILE/control01.ctl' SCOPE=spfile; ALTER DATABASE OPEN; ``` --- #### **4. 设置数据文件路径(DATAFILE)** ##### **方案A:修改现有表空间路径** ```sql -- 将表空间脱机 ALTER TABLESPACE users OFFLINE; -- 移动数据文件(操作系统命令) mv /old/path/users01.dbf /path/to/RBSCM/DATAFILE/ -- 更新路径 ALTER DATABASE RENAME FILE '/old/path/users01.dbf' TO '/path/to/RBSCM/DATAFILE/users01.dbf'; -- 将表空间联机 ALTER TABLESPACE users ONLINE; ``` ##### **方案B:创建新表空间时指定路径** ```sql CREATE TABLESPACE new_tbs DATAFILE '/path/to/RBSCM/DATAFILE/newtbs01.dbf' SIZE 100M; ``` --- #### **5. 迁移在线重做日志(ONLINELOG)** ```sql -- 添加新日志组到目标路径 ALTER DATABASE ADD LOGFILE GROUP 4 ('/path/to/RBSCM/ONLINELOG/redo04a.log') SIZE 100M; -- 切换日志直到旧组状态为INACTIVE ALTER SYSTEM SWITCH LOGFILE; -- 删除旧日志组 ALTER DATABASE DROP LOGFILE GROUP 1; -- 更新文件路径(引用[2]方法) ALTER DATABASE RENAME FILE '/old/path/redo01.log' TO '/path/to/RBSCM/ONLINELOG/redo01.log'; ``` --- #### **关键验证命令** ```sql -- 检查文件路径 SELECT name FROM v$datafile; -- 数据文件 SELECT member FROM v$logfile; -- 在线日志 SELECT name FROM v$controlfile; -- 控制文件 SELECT destination FROM v$archive_dest; -- 归档路径 ``` > **注意**: > 1. 操作前务必备份数据库 > 2. 确保Oracle用户对目录有读写权限 > 3. 路径中的`/path/to/RBSCM/`需替换为实际全局变量路径 > 4. 移动文件需在数据库关闭或脱机状态下进行 --- ### 相关问题 1. 如何验证Oracle数据库的文件路径配置是否正确? 2. 迁移数据库文件时出现权限错误应如何解决? 3. 使用OMF(Oracle Managed Files)自动管理文件路径有哪些优缺点? 4. 如何在不中断服务的情况下迁移在线重做日志文件? 5. 控制文件丢失后如何通过备份恢复? [^1]: 归档日志文件是实例一致性恢复必需的文件,同时可将数据库恢复到特定时间点。 [^2]: 使用`ALTER DATABASE RENAME FILE`命令重命名文件路径。 [^3]: 创建控制文件需获取日志组、日志大小和redo block size信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值