1. 首先创建测试用的表空间
SQL> create tablespace test
2 datafile 'D:\10g\product\10.2.0\oradata\orcl\test.dbf' size 1M;
表空间已创建。
2. 创建测试用用户
SQL> create user test identified by test
2 default tablespace test;
用户已创建。
3. 授予权限
SQL> grant connect,resource,create table,exp_full_database to test;
授权成功。
4. 设置限额
SQL> alter user test quota unlimited on test;
用户已更改。
5. 切换用户创建测试用表,并插入语句
SQL> create table test
2 (i int,
3 a number);
表已创建。
SQL> insert into test values (2,3);
已创建 1 行。
SQL> insert into test select * from test;
已创建 1 行。
SQL> /
已创建2行。
SQL> /
已创建4行。
SQL> /
已创建8行。
SQL> /
已创建16行。
SQL> /
已创建32行。
SQL> /
已创建64行。
SQL> /
已创建128行。
SQL> /
已创建256行。
SQL> /
已创建512行。
SQL> /
已创建1024行。
SQL> /
已创建2048行。
SQL> /
已创建4096行。
SQL> /
已创建8192行。
SQL> /
已创建16384行。
SQL> /
已创建32768行。
SQL> /
insert into test select * from test
*
第 1 行出现错误:
ORA-01653: 表 TEST.TEST 无法通过 8 (在表空间 TEST 中) 扩展
塞满为止
6. 先做一个查询
SQL> select count(*) from test;
COUNT(*)
----------
65536
7. 关库,冷备份数据文件
SQL> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
8. 使用UE编辑器对数据文件进行编译,随便修改几个数据,造成坏块即可
9. OK,成功出现坏块
SQL> select count(*) from test;
select count(*) from test
*
第 1 行出现错误:
ORA-01578: ORACLE 数据块损坏 (文件号 5, 块号 79)
ORA-01110: 数据文件 5: 'D:\10G\PRODUCT\10.2.0\ORADATA\ORCL\TEST.DBF'
告警日志显示:
Reread of rdba: 0x0140004f (file 5, block 79) found same corrupted data
Thu Aug 30 10:03:44 2012
Corrupt Block Found
TSN = 7, TSNAME = TEST
RFN = 5, BLK = 79, RDBA = 20971599
BJN = 52706, BJD = 52706, BJECT = TEST, SUBOBJECT =
SEGMENT WNER = TEST, SEGMENT TYPE = Table Segment
当然此时如果使用exp进行数据导出也是会出现错误
即将导出 TEST 的对象...
. 正在导出数据库链接
. 正在导出序号
. 正在导出簇定义
. 即将导出 TEST 的表通过常规路径...
. . 正在导出表 TEST
EXP-00056: 遇到 ORACLE 错误 1578
ORA-01578: ORACLE 数据块损坏 (文件号 5, 块号 79)
ORA-01110: 数据文件 5: 'D:\10G\PRODUCT\10.2.0\ORADATA\ORCL\TEST.DBF'
10. 因为OBJD为52706,我们可以进一步确定坏块类型,如果是索引坏块则删除重建即可,表坏块则需要进行修复
SQL> select owner,object_name,object_type from dba_objects where object_id=52706
;
OWNER
------------------------------
OBJECT_NAME
--------------------------------------------------
OBJECT_TYPE
-------------------
TEST
TEST
TABLE
11. 使用DBV工具分析
C:\Documents and Settings\Administrator>dbv file='D:\10G\PRODUCT\10.2.0\ORADATA
12. ORCL\TEST.DBF'
13.
14. DBVERIFY: Release 10.2.0.1.0 - Production on 星期四 8月 30 10:04:44 2012
15.
16. Copyright (c) 1982, 2005, Oracle. All rights reserved.
17.
18. DBVERIFY - 开始验证: FILE = D:\10G\PRODUCT\10.2.0\ORADATA\ORCL\TEST.DBF
19. 页 79 标记为损坏
20. Corrupt block relative dba: 0x0140004f (file 5, block 79)
21. Bad check value found during dbv:
22. Data in bad block:
23. type: 6 format: 2 rdba: 0x0140004f
24. last change scn: 0x0000.003848a4 seq: 0x1 flg: 0x06
25. spare1: 0x0 spare2: 0x0 spare3: 0x0
26. consistency value in tail: 0x48a40601
27. check value in block header: 0xa4cc
28. computed block checksum: 0x509
29.
30.
31.
32. DBVERIFY - 验证完成
33.
34. 检查的页总数: 128
35. 处理的页总数 (数据): 109
36. 失败的页总数 (数据): 0
37. 处理的页总数 (索引): 0
38. 失败的页总数 (索引): 0
39. 处理的页总数 (其它): 18
40. 处理的总页数 (段) : 0
41. 失败的总页数 (段) : 0
42. 空的页总数: 0
43. 标记为损坏的总页数: 1
44. 流入的页总数: 0
45. 最高块 SCN : 3688974 (0.3688974)数据文件
46. 使用dbms_repair包进行坏块标记
创建REPAIR_CORRUPT_TAB表
SQL> exec dbms_repair.admin_tables(-
> table_name=>'REPAIR_CORRUPT_TAB',-
> table_type=>dbms_repair.repair_table,-
> action=>dbms_repair.create_action);
PL/SQL 过程已成功完成。
检测坏块,信息存入表中
declare num_corrupt int;
begin
num_corrupt:=0;
dbms_repair.check_object(
schema_name=>'TEST',
object_name=>'TEST',
repair_table_name=>'REPAIR_CORRUPT_TAB',
corrupt_count=>num_corrupt);
dbms_output.put_line(num_corrupt);
end;
/
PL/SQL 过程已成功完成。
SQL> select schema_name,object_name,relative_file_id,block_id,repair_description
from repair_corrupt_tab;
上面的sql语句可以显示坏块的信息,由于太长就别一一贴出来了。
标记坏块
declare num_fix int;
begin
num_fix:=0;
dbms_repair.fix_corrupt_blocks(
schema_name=>'TEST',
object_name=>'TEST',
object_type=>DBMS_REPAIR.TABLE_OBJECT,
repair_table_name=>'REPAIR_CORRUPT_TAB',
fix_count=>num_fix);
end;
/
PL/SQL 过程已成功完成
给坏块打完标签之后,我们sikp这些坏块
SQL> exec dbms_repair.skip_corrupt_blocks('TEST','TEST');
PL/SQL 过程已成功完成。
47. 再来查询下看看
SQL> show user;
USER 为 "SYS"
SQL> conn test/test
已连接。
SQL> select count(*) from test;
COUNT(*)
----------
64876
65536-64876=660 损失了660条数据
再来看下exp
即将导出 TEST 的表通过常规路径...
. 正在导出表 TEST导出了 64876 行
正在导出同义词
正在导出视图
正在导出存储过程
正在导出运算符
正在导出引用完整性约束条件
正在导出触发器
正在导出索引类型
正在导出位图, 功能性索引和可扩展索引
正在导出后期表活动
正在导出实体化视图
正在导出快照日志
正在导出作业队列
正在导出刷新组和子组
正在导出维
正在导出 post-schema 过程对象和操作
正在导出统计信息
成功终止导出, 没有出现警告。
已经可以成功导出
总结:此种方法可以在有数据坏块的情况下进行标记坏块跳过坏块导出数据,但是会一定程度上丢失数据。具体采用何种方法还要看业务的需求和数据的重要性。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/21416913/viewspace-742242/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/21416913/viewspace-742242/