在一次查询中,程序报错
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
BBED是Oracle 内部使用的命令,所以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 中第一行16个bytes 的架构:
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 是0x9a6f,requiredchecksum 是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