Focus On Oracle

Installing, Backup & Recovery, Performance Tuning,
Troubleshooting, Upgrading, Patching

Oracle Engineered System


当前位置: 首页 » 技术文章 » 内部原理

Interpret The Datafile OS Header/Block Zero

Oracle数据文件的第一个块,也称为Block Zero,她用来记录OS的信息,包含了数据库的块的类型、格式、RDBA(虚设的)、块大小、文件中总的块数、Magic Number,还有块的校验值等。她并不是我们所说的数据文件头部(Datafile Header)的那个块,如果这个块被损坏,可能导致数据库启动失败。比如ORA-27047,ORA-27048。dbfsize可以用来检测块头的完整性,也只能用来做这些工作。还有一个工具可以用来检测,她就是dbv,她是在11g之后的版本才增加的,她只能检测数据文件,不能检测控制文件和日志文件(DBVERIFY checks are limited to cache-managed blocks (that is, data blocks). Because DBVERIFY is only for use with data files, it does not work against control files or redo logs.)。


dbfsize

[oracle@db1 ~]$ dbfsize /oradata/upgr/control01.ctl
Database file: /oradata/upgr/control01.ctl
Database file type: file system
Database file size: 594 16384 byte blocks
[oracle@db1 ~]$ dbfsize /oradata/upgr/system01.dbf
Database file: /oradata/upgr/system01.dbf
Database file type: file system
Database file size: 94720 8192 byte blocks

ORA-27047,ORA-27048错误描述
[oracle@db1 ~]$ oerr ora 27047
27047, 00000, "unable to read the header block of file"
// *Cause:  read system call failed, additional information indicates which
//          function encountered the error
// *Action: check errno
[oracle@db1 ~]$

[oracle@db1 ~]$ oerr ora 27048
27048, 00000, "skgfifi: file header information is invalid"
// *Cause:  possibly trying to use a non-database file as a database file
// *Action: verify that file is a database file
[oracle@db1 ~]$
Database upgrade (OPEN MIGRATE) or NORMAL OPEN may fail with errors ORA-01157 ORA-27048:
ORA-01157: cannot identify/lock data file 1 - see DBWR trace file
ORA-01110: data file 1: '/oracle/upgr/system.dbf'
ORA-27048: skgfifi: file header information is invalid

数据文件在OS上第一个块(Block Zero)和数据文件头头部、数据块头部格式差不多,这个块只使用了前面的30多个字节(AIX:36byte,Linux:34byte)

以AIX上system表空间为例,标注红色的是数据文件在OS上第一个块(Block Zero)内容,这个块也符合块的校验算法

# od -x system01.dbf|head -6
0000000  00a2 0000 ffc0 0000 0000 0000 0000 0000
0000020  a8c4 0000 0000 2000 0000 f000 7a7b 7c7d
0000040  0000 81a0 0000 0000 0000 0000 0000 0000
0000060  0000 0000 0000 0000 0000 0000 0000 0000
*
0020000  0ba2 0000 0040 0001 0000 0000 0000 0104

offset0:0   块类型,可能是用0来表示OS
offset1:a2 块格式,这个代表8k的意思
    Oracle 6,7 : 0x01
      8i~9i:all: 0x02
    10g~12c:2k : 0x62
            4k : 0x82
            8k : 0xa2
           16k : 0xc2
    Redo 6~12c : 0x22

    AIX上控制文件,数据文件,日志文件输出
    # od -x control01.ctl|head -6
    0000000  00c2 0000 ffc0 0000 0000 0000 0000 0000
    0000020  39ea 0000 0000 4000 0000 014e 7a7b 7c7d
    0000040  0000 81a0 0000 0000 0000 0000 0000 0000
    0000060  0000 0000 0000 0000 0000 0000 0000 0000
    *
    0040000  15c2 0000 0000 0001 0000 0000 0000 0104
    # od -x system01.dbf|head -6
    0000000  00a2 0000 ffc0 0000 0000 0000 0000 0000
    0000020  a8c4 0000 0000 2000 0000 f000 7a7b 7c7d
    0000040  0000 81a0 0000 0000 0000 0000 0000 0000
    0000060  0000 0000 0000 0000 0000 0000 0000 0000
    *
    0020000  0ba2 0000 0040 0001 0000 0000 0000 0104
    # od -x temp01.dbf|head -6
    0000000  00a2 0000 ffc0 0000 0000 0000 0000 0000
    0000020  52c4 0000 0000 2000 0000 0a00 7a7b 7c7d
    0000040  0000 81a0 0000 0000 0000 0000 0000 0000
    0000060  0000 0000 0000 0000 0000 0000 0000 0000
    *
    0020000  0ba2 0000 0040 0001 0000 0000 0000 0104
    #  od -x redo01.log|head -6
    0000000  0022 0000 ffc0 0000 0000 0000 0000 0000
    0000020  ea45 0000 0000 0200 0001 9000 7a7b 7c7d
    0000040  0000 81a0 0000 0000 0000 0000 0000 0000
    0000060  0000 0000 0000 0000 0000 0000 0000 0000
    *
    0001000  0122 0000 0000 0001 0000 0017 8000 2936
    # 

    Linux上控制文件,数据文件,日志文件在AIX上的输出,这样做只是为了看着更清晰

    # cd /tmp/linux

    # ls
    control01.ctl  redo01.log     temp01.dbf     users01.dbf
    # od -x control01.ctl |head -6
    0000000  00c2 0000 0000 c0ff 0000 0000 0000 0000
    0000020  34f8 0000 0040 0000 5202 0000 7d7c 7b7a
    0000040  a081 0000 0000 0000 0000 0000 0000 0000
    0000060  0000 0000 0000 0000 0000 0000 0000 0000
    *
    0040000  15c2 0000 0100 0000 0000 0000 0000 0104
    # od -x users01.dbf|head -6
    0000000  00a2 0000 0000 c0ff 0000 0000 0000 0000
    0000020  26fc 0000 0020 0000 4006 0000 7d7c 7b7a
    0000040  a081 0000 0000 0000 0000 0000 0000 0000
    0000060  0000 0000 0000 0000 0000 0000 0000 0000
    *
    0020000  0ba2 0000 0100 0001 0000 0000 0000 0104
    # od -x temp01.dbf|head -6
    0000000  00a2 0000 0000 c0ff 0000 0000 0000 0000
    0000020  e6f4 0000 0020 0000 800e 0000 7d7c 7b7a
    0000040  a081 0000 0000 0000 0000 0000 0000 0000
    0000060  0000 0000 0000 0000 0000 0000 0000 0000
    *
    0020000  0ba2 0000 0100 4000 0000 0000 0000 0104

    # od -x redo01.log|head -6
    0000000  0022 0000 0000 c0ff 0000 0000 0000 0000
    0000020  67c8 0000 0002 0000 0090 0100 7d7c 7b7a
    0000040  a081 0000 0000 0000 0000 0000 0000 0000
    0000060  0000 0000 0000 0000 0000 0000 0000 0000
    *
    0001000  0122 0000 0100 0000 0d00 0000 0080 585d
    # 
   
offset 4~7:ffc00000 按照RDBA的格式来讲,也说得过去,这个值是固定的
AODU> rdba ffc00000
        rdba   : 0xffc00000=4290772992 (dba=1023,0)
        rfile# : 1023
        block# : 0
        Dump Block : alter system dump datafile 1023 block 0;
AODU>

offset 16~17:a8c4 这个是块的校验值,按照块的校验算法,这个值是正确的

可以参考How to calculate checksum(chkval_kcbh)?

offset 22~23:2000 0x2000,10进制是8192,是块的大小
offset 26~27:f000  0xf000,   10进制是61440,是块的个数,可用dbfsize校验
    $ dbfsize /oracle/oradata/orcl/system01.dbf
    Database file: /oracle/oradata/orcl/system01.dbf
    Database file type: file system
    Database file size: 61440 8192 byte blocks
    $

offset 28~31:7a7b7c7d 这个是Magic Number,这个是用来检测是不是Oracle的文件

                   Big-Endian是7A7B7C7D,Little-Endian是7D7C7B7A

offset 34~35:81a0 这个值10g,11g,12c值是一样的,具体是什么意思,还不确定

12c数据文件头部
BBED> map
 File: /oradata/cdb1/system01.dbf (1)
 Block: 1                                     Dba:0x00400001
------------------------------------------------------------
 Data File Header
 struct kcvfh, 1112 bytes                   @0      

 ub4 tailchk                                @8188    

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        0x00400001
   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       0x7a33
   ub2 spare3_kcbh                          @18       0x0000
BBED> 

数据块头部
BBED> p kcbh
struct kcbh, 20 bytes                       @0       
   ub1 type_kcbh                            @0        0x06
   ub1 frmt_kcbh                            @1        0xa2
   ub1 spare1_kcbh                          @2        0x00
   ub1 spare2_kcbh                          @3        0x00
   ub4 rdba_kcbh                            @4        0x01400017
   ub4 bas_kcbh                             @8        0x0012c0e4
   ub2 wrp_kcbh                             @12       0x0000
   ub1 seq_kcbh                             @14       0x01
   ub1 flg_kcbh                             @15       0x06 (KCBHFDLC, KCBHFCKV)
   ub2 chkval_kcbh                          @16       0xfc2a
   ub2 spare3_kcbh                          @18       0x0000
BBED>

AIX,Solaris文件在Linux上是用dbfsize无法被识别的。AIX和Solaris能互相识别,Linux和Windows能互相识别

[oracle@db1 ~]$ dbfsize /home/oracle/ttbs.dbf
/home/oracle/ttbs.dbf: Header block magic number is bad
[oracle@db1 ~]$ dbfsize /tmp/ttbs.dbf

通过RMAN Convert后,文件可被识别
[oracle@db1 ~]$ rman target /
Recovery Manager: Release 12.1.0.2.0 - Production on Fri Mar 18 08:34:31 2016
Copyright (c) 1982, 2014, Oracle and/or its affiliates.  All rights reserved.
connected to target database: CDB1 (DBID=879831934)
RMAN> convert datafile '/home/oracle/ttbs.dbf' FROM PLATFORM 'Solaris[tm] OE (32-bit)' format '/tmp/ttbs.dbf';
Starting conversion at target at 18-MAR-16
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=72 device type=DISK
channel ORA_DISK_1: starting datafile conversion
input file name=/home/oracle/ttbs.dbf
converted datafile=/tmp/ttbs.dbf
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:01
Finished conversion at target at 18-MAR-16

RMAN>

[oracle@db1 ~]$ dbfsize /tmp/ttbs.dbf
Database file: /tmp/ttbs.dbf
Database file type: file system
Database file size: 1280 8192 byte blocks

[oracle@db1 ~]$


通过RMAN转化之后Block 0也是有变化的,下面是在Linux上输出
[oracle@db1 ~]$ od -x /home/oracle/ttbs.dbf |head
0000000 a200 0000 c0ff 0000 0000 0000 0000 0000
0000020 c45d 0000 0000 0020 0000 0005 7b7a 7d7c
0000040 0000 a081 0000 0000 0000 0000 0000 0000
0000060 0000 0000 0000 0000 0000 0000 0000 0000
*
0020000 a20b 0000 8001 0100 0000 0000 0000 0401
0020020 db1f 0000 0000 0000 200b 0000 2a5a f564
0020040 5250 444f 0032 0000 0000 d104 0000 0005
0020060 0000 0020 0600 0300 0000 0000 0000 0000
0020100 4154 3247 3130 3134 3131 5439 3431 3433
[oracle@db1 ~]$ od -x /tmp/ttbs.dbf |head
0000000 a200 0000 0000 ffc0 0000 0000 0000 0000
0000020 ff66 0000 2000 0000 0500 0000 7c7d 7a7b
0000040 81a0 0000 0000 0000 0000 0000 0000 0000
0000060 0000 0000 0000 0000 0000 0000 0000 0000
*
0020000 a20b 0000 0001 0180 0000 0000 0000 0401
0020020 20fb 0000 0000 0000 0000 0b20 64f5 5a2a
0020040 5250 444f 0032 0000 04d1 0000 0500 0000
0020060 2000 0000 0006 0003 0000 0000 0000 0000
0020100 0000 0000 0000 0000 0000 0000 0000 0000
[oracle@db1 ~]$


Reference

Database Backup and Recovery Reference

关键词:block 

相关文章

如何用BBED使Offline的数据文件Online
Interpret The Datafile OS Header/Block Zero
如何计算Oracle Block的校验值
10g,11g,12c X$KCVFH(一)
Top