在一次查询中,程序报错

ORA-01578: ORACLE data block corrupted (file # 6, block # 11)

ORA-01110: data file 6: u01/app/oracle/oradata/orcl/tbs01.dbf'

网上查询,发现可能是oracle数据文件产生坏块

 

现模拟产生坏块的环境,并进行了相关实验。

使用平台为虚拟机linux 5.3+Oracle 10.2.0.1

 

1.       使用模拟oracle坏块

 

1.1生成bbed工具

 

使用bbed工具对数据文件进行编辑,强制产生坏块。(生产环境不要使用)

BBED(Oracle Block Browerand EDitor Tool),用来直接查看和修改数据文件数据的一个工具,是Oracle一款内部工具,可以直接修改Oracle数据文件块的内容,在一些极端恢复场景下比较有用。该工具不受Oracle支持,所以默认是没有生成可执行文件的,在使用前需要重新连接。linux平台上需要手动编译生成。

 

cd$ORACLE_HOME/rdbms/lib

make -f ins_rdbms.mk  BBED=$ORACLE_HOME/bin/bbed  $ORACLE_HOME/bin/bbed

 

BBEDOracle 内部使用的命令,所以Oracle 不提供技术支持。 为了安全,BBED设置了口令保护,默认密码为blockedit

 

先获取datafile 的信息

       datafile 的信息写入一个文件,格式为:文件编号  文件名字 文件大小。可以通过如下SQL   获取:

 

SQL> select file#||' '||name||' '||bytes from v$datafile ;

 

FILE#||''||NAME||''||BYTES

--------------------------------------------------------------------------------

1 /home/oracle/oradata/orcl/system01.dbf 1073741824

2 /home/oracle/oradata/orcl/undotbs01.dbf 1073741824

3 /home/oracle/oradata/orcl/sysaux01.dbf 272629760

4 /home/oracle/oradata/orcl/users01.dbf 1073741824

5 /home/oracle/oradata/orcl/test101.dat 10485760

6 /home/oracle/oradata/orcl/block.dat 5242880

 

6 rows selected.       注意,这里的file id 我们这里的file id oracle 系统内部的file id 相同。 当然这个id 我们也可以自己指定。 当我们在bbed 里设置file id 时,就是根据这个参数文件中的的设置来的。 最好设置为相同,不然以后可能会混淆。

 

将上面查询出来的datafile信息保存到文本里。

 

oracle@AS5TEST_/home/oracle/bbed$ cat file.list

1 /home/oracle/oradata/orcl/system01.dbf 1073741824

2 /home/oracle/oradata/orcl/undotbs01.dbf 1073741824

3 /home/oracle/oradata/orcl/sysaux01.dbf 262144000

4 /home/oracle/oradata/orcl/users01.dbf 1073741824

5 /home/oracle/oradata/orcl/test101.dat 104857600

 

创建parameter file

oracle@AS5TEST_/home/oracle/bbed$ cat bbed.par

blocksize=8192

listfile=/home/oracle/bbed/file.list

mode=edit

使用parameter file 连接bbed

 oracle@AS5TEST_/home/oracle/bbed$ bbed parfile=bbed.par

Password:

 

BBED: Release 2.0.0.0.0 - Limited Production on Mon Nov 19 20:38:01 2012

 

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

 

************* !!! For Oracle Internal Use only !!! ***************

 

BBED>

BBED> show

        FILE#           1

        BLOCK#          1

        OFFSET          0

        DBA             0x00400001 (4194305 1,1)

        FILENAME        /home/oracle/oradata/orcl/system01.dbf

        BIFILE          bifile.bbd

        LISTFILE        /home/oracle/bbed/file.list

        BLOCKSIZE       8192

        MODE            Edit

        EDIT            Unrecoverable

        IBASE           Dec

        OBASE           Dec

        WIDTH           80

        COUNT           512

        LOGFILE         log.bbd

        SPOOL           No

 

BBED>

 

1.2模拟生成坏块

 

事先在测试库建立表空间test1 数据文件为datafile 5

建立测试用户

create user dw identified by oracle default tablespace test1 temporary tablespace temp;

grant connect ,resource to dw identified by dw;

用户创建测试表

create table dw.testtp(name varchar2(100),sex varchar2(100));

插入数据

insert into dw.testtp(name,sex) values('a','aa');

insert into dw.testtp(name,sex) values('b','bb');

insert into dw.testtp(name,sex) values('c','cc');

insert into dw.testtp(name,sex) values('d','dd');

insert into dw.testtp(name,sex) values('e','ee');

insert into dw.testtp(name,sex) values('f','ff');

insert into dw.testtp(name,sex) values('g','gg');

insert into dw.testtp(name,sex) values('hh','hh');

insert into dw.testtp(name,sex) values('i','ii');

insert into dw.testtp(name,sex) values('j','jj');

insert into dw.testtp(name,sex) values('k','kk');

建立测试索引

create index index_name on testtp(name);

 

确定建立的表的行数

SQL> select count(1) from dw.testtp;

  COUNT(1)

----------

        11

确定生成的数据的block位置

SQL> Select rowid,

  2  dbms_rowid.rowid_relative_fno(rowid)rel_fno,

  3  dbms_rowid.rowid_block_number(rowid)blockno,

  4  dbms_rowid.rowid_row_number(rowid) rowno

  5  from dw.testtp;

 

 

ROWID                 REL_FNO    BLOCKNO      ROWNO

------------------ ---------- ---------- ----------

AAAMmfAAFAAAAAOAAA          5         14          0

AAAMmfAAFAAAAAOAAB          5         14          1

AAAMmfAAFAAAAAOAAC          5         14          2

AAAMmfAAFAAAAAOAAD          5         14          3

AAAMmfAAFAAAAAOAAE          5         14          4

AAAMmfAAFAAAAAOAAF          5         14          5

AAAMmfAAFAAAAAOAAG          5         14          6

AAAMmfAAFAAAAAOAAH          5         14          7

AAAMmfAAFAAAAAOAAI          5         14          8

AAAMmfAAFAAAAAOAAJ          5         14          9

AAAMmfAAFAAAAAOAAK          5         14         10

 

11 rows selected.

 

BBED> dump /v dba 5,14 offset 0 count 128

 File: /home/oracle/oradata/orcl/test101.dat (5)

 Block: 14      Offsets:    0 to  127  Dba:0x0140000e

-------------------------------------------------------

 06a20000 0e004001 810b0700 00000d06 l ......@.........

 6f9a0000 01000000 9fc90000 0d0b0700 l o...............

 00000000 02003200 09004001 01002a00 l ......2...@...*.

 0f010000 f34e8000 52001200 0b200000 l .....N..R.... ..

 810b0700 00000000 00000000 00000000 l ................

 00000000 00000000 00000000 00000000 l ................

 00000000 00010b00 ffff2800 3f1f0d1f l ..........(.?...

 0d1f0000 0b00901f 881f801f 781f701f l ............x.p.

 

 <16 bytes per line>

 

 

blockheader 中第一行16bytes 的架构:

 

Type

Format

Unused

RDBA

SCN Base

SCN Wrap

Seq

Flag

06

a2

0000

0e004001

810b0700

0000

0d

61

 

 

手动将该表的结构修改

(修改后不要退出bbed,实验完后可以使用命令revert dba 5,14恢复修改

 

BBED> modify /c 777 dba 5,14 offset 0

Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y

 File: /home/oracle/oradata/orcl/test101.dat (5)

 Block: 14               Offsets:    0 to  127           Dba:0x0140000e

------------------------------------------------------------------------

 37373700 0e004001 810b0700 00000d06 6f9a0000 01000000 9fc90000 0d0b0700

 00000000 02003200 09004001 01002a00 0f010000 f34e8000 52001200 0b200000

 810b0700 00000000 00000000 00000000 00000000 00000000 00000000 00000000

 00000000 00010b00 ffff2800 3f1f0d1f 0d1f0000 0b00901f 881f801f 781f701f

 

 <32 bytes per line>

应用修改

BBED> sum dba 5,14 

Check value for File 5, Block 14:

current = 0x9a6f, required = 0x0f69

此时 current checksum 0x9a6frequiredchecksum 0x0f69

BBED> sum dba 5,14 apply

Check value for File 5, Block 14:

current = 0x0f69, required = 0x0f69

加上apply参数,使checksum一致。即之前的修改生效。

 

这时在数据库刷新缓存,重新查询数据

SQL> alter system flush buffer_cache;

System altered.

SQL> select name from dw.testtp;

select name from dw.testtp

                    *

ERROR at line 1:

ORA-01578: ORACLE data block corrupted (file # 5, block # 14)

ORA-01110: data file 5: '/home/oracle/oradata/orcl/test101.dat'

 

实验参考链接

bbed使用说明

http://blog.csdn.net/tianlesoftware/article/details/5006580