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)内容,这个块也符合块的校验算法
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
# lscontrol01.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 ~]$
[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