http://blog.chinaunix.net/u1/50863/showart_400576.html
试验的目的:
1.查找含坏块的数据的所有的rowid,从而得到损坏的数据量
2.查找损坏表的现在可用的数据量
3.根据1和2得到该表的本来的总的数据量
试验步骤:
1)参照 数据文件出现坏块时之五(如何利用dbms_repair来标记和跳过坏块)的第一步和第二部
建了表空间block,用户test1107,表test,初始化了数据4512行,模拟了数据坏块,
并用dbv得到所有的坏块ID(34~52,68~87)
2)参照 数据文件出现坏快时之三(如何查找坏块所含的数据表名称和数据的rowid)的步骤,查找出所有的坏块包含的rowid
select /*+ index(test1107, i_test)*/ rowid
from test1107.test
where dbms_rowid.rowid_to_absolute_fno(rowid,'TEST1107','TEST')=13
and (dbms_rowid.rowid_block_number(rowid) between 34 and 52 or
dbms_rowid.rowid_block_number(rowid) between 68 and 87);
结果返回了1598行坏记录
3)参照 数据文件出现坏块时之六(设置内部事件使exp跳过坏块)
先exp报错,后来设置了events事件,然后exp出来,显示有 2914行,抓屏幕如下:
C:\Documents and Settings\liguohua>exp test1107/aaaa tables=test file=d:\work\temp\test.dmp
即将导出指定的表通过常规路径 ...
. . 正在导出表 TEST
EXP-00056: 遇到 ORACLE 错误 1578
ORA-01578: ORACLE 数据块损坏(文件号13,块号34)
ORA-01110: 数据文件 13: 'D:\ORACLE\ORADATA\BLOCK.DBF'
导出成功终止,但出现警告。
C:\Documents and Settings\liguohua>alter system set events='10231 trace name context forever,level 10';
C:\Documents and Settings\liguohua>exp test1107/aaaa tables=test file=d:\work\temp\test.dmp
即将导出指定的表通过常规路径 ...
. . 正在导出表 TEST 2914 行被导出
在没有警告的情况下成功终止导出。
结果表示有2914行记录可用
另外一种方法,其实可以用
select count(1) from test1107.test where rowid not in
(
select /*+ index(test1107, i_test)*/ rowid
from test1107.test
where dbms_rowid.rowid_to_absolute_fno(rowid,'TEST1107','TEST')=13
and (dbms_rowid.rowid_block_number(rowid) between 34 and 52 or
dbms_rowid.rowid_block_number(rowid) between 68 and 87)
);
来查询可用的记录数,这样比较简单
4)1598 + 2914 = 4512,正好和原表总记录数吻合!
5)恢复events参数
alter system set events='10231 trace name context off';