坏块修复

简介:

坏块分为物理坏块和逻辑坏块,前者是硬件问题产生,后者是oracle内部数据有问题,本次试验针对后者。


需要归档模式,步骤

1create tablespace test 1m (table t1, insert)2 RMAN>backup tablespace test3 模拟坏块4 DBV5 ANALYZE TABLE6 RMAN BACKUP7EXP8 DBMS_REPAIR9 BLOCKRECOVER

1,sys用户下创建表空间

SYS@jsce>create tablespace tbs1 datafile 'e:\tbs1.dbf' size 1m; --大小1M,容易填满(现在突然有疑惑:为什么要填满,才能制造坏块?)

在tbs1中创建表tb1,数据来源是scott.emp

SYS@jsce>create table tb1 tablespace tbs1 as select * from scott.emp;

双倍递增插入表tb1,来源也是其自己

SYS@jsce>insert into tb1 select * from tb1; --这里是select出来的东西插入到表,没有关键字values

已创建15行。

SYS@jsce>insert into tb1 select * from tb1;

已创建30行。

SYS@jsce>insert into tb1 select * from tb1;

已创建60行。



20155810-ac3550484b124bd0a507bd07c1d15e5


在插满之后,不要忘记commit,否则oracle不能shutdown,最后确认一下插入的数据量“15360”

20165843-d885d881973644d7ae36d671eb4e3f9

》给表增加索引,后面查询有坏块之后,坏块带来损失的数据ORPHAN_TABLE;

SYS@jsce>create index i1 on tb1(ename);

索引已创建。

SYS@jsce>alter system checkpoint; --这一步是将插入的数据作检查点写入数据文件,下一步就要通过ultraedit修改数据文件,制造坏块。

系统已更改。

备注:如果表字段没有设置not null必输项,并且表字段很多,那么可以指定字段来插入一部分,比如emp表

insert into emp(empno,ename,sal) values(22,'sumsen',8900);

2,rman备份表空间tbs1,得到优良备份(下面还原使用)

RMAN> backup tablespace tbs1 tag=ok;--增加tag

20160832-b0307b683efa4d628e77b8d7047c1f2

3,shutdown之后,通过ultraedit修改数据文件 --修改的时候不要开头部,那里是数据文件名称,有可能导致oracle启动失败

20162253-d26cb4b940b94cf69d21d22657f9687

修改,保存之后,数据文件目录会多出一个TBS1.DBF.bak,说明修改过了,不知道为何

20162907-891b3525b24c48dabb19f4c5b99c36b

启动oracle再次查询报错,坏块产生 --这里的select 是遇到第一个坏块就报错,因此如果有多个坏块,也是报出一个错误信息,需要用下面的REPAIR_TABLE查询所有的坏块。

20162809-560d5193544b4f958c1780c9b7e1226

4,用dbv检测

20163125-979af1729cbd44d6a01b39a2fef6463

20163624-7b958e936d4f461fa0526bf55d3694f

这里仅仅给出坏块数,没有给出坏块号和文件号

5,使用 ANALYZE TABLE

SYS@jsce>analyze table tb1 validate structure;

20165541-4859dc46233b41e5a81bc51dc1ec58a

6,rman的备份和exp导出有坏块的表空间

exp导出sys下的

20170053-9c009436905d4ba99599fac8fee0239

E:\Documents and Settings\xs>exp userid='sys/sys as sysdba' file=e:\exptbs1.dmp tablespaces=tbs1

导出表空间没有问题

20170546-ef63bd6db25141a0b789ac1731d86a5

导出表有坏块报错

20170914-da0dc2bde2c740fd96198c37158d56e

rman提示超过坏块限制

20171139-a1c9117d73cd454c9dfb823a199c39c

通过设置坏块最大数来继续备份

RMAN> run{set maxcorrupt for datafile 3 to 10;backup tablespace tbs1 tag=bad;} 要写在一块,让rman知道是一个事务

因为最大坏块设置为了10,tbs1有两个坏块,可以通过备份

20171553-0e6f45c629684288a150359eb5878d3

7,包DBMS_REPAIR

exec DBMS_REPAIR.ADMIN_TABLES('REPAIR_TABLE',1,1,'USERS');--表数据

exec DBMS_REPAIR.ADMIN_TABLES('ORPHAN_TABLE',2,1,'USERS');--索引数据

20172237-0cefab213bb94bcf873c438f2acac4c

检查坏块:dbms_repair.check_object , 这里的schema_name是用户,比如我在sys下建立的表空间,这里就是sys,

object_name是表不是表空间(查询的时候报错也是通过select * from tb1)

declare
cc number;
begin
dbms_repair.check_object(schema_name => 'SYS',object_name => 'TB1',corrupt_count => cc); 
dbms_output.put_line(a => to_char(cc)); --这里a=>不明不白,可以去掉
end;

20173348-45cdfbcbf269459babace8e0c2370c0


看到这里用dbms_repair.check,检查的结果corrupt_count=2,有2个块损坏,和dbv的结果一致。 
check完之后,在我们刚在创建的REPAIR_TABLE中查看块损坏详细信息:

SELECTobject_name,       relative_file_id,       block_id,       marked_corrupt,       corrupt_description,       repair_description,       CHECK_TIMESTAMP  from repair_table;

得到4个结果,不过就两个块(33,69),只是时间不一样,不解?

20173907-1c63c237171047d39415783d2b263c4

我们注意看MARKED_CORRUPT的值,这里经过check_object后,已经标识为TRUE了。(

》使用包的skip_corrupt_blocks过程来跳过坏块

exec dbms_repair.skip_corrupt_blocks(schema_name => 'SYS',object_name => 'TB1',flags => 1);

20174246-82602991405348f7ad642e316966d6e

损失了15360-15020=340 条数据

》处理index上的无效键值;dump_orphan_keys

declare
cc number;
begin
dbms_repair.dump_orphan_keys(schema_name => 'SYS',object_name => 'I1',object_type => 2,
repair_table_name => 'REPAIR_TABLE',orphan_table_name => 'ORPHAN_TABLE',key_count => CC);
end;

之后查询数据,我们根据这个结果来考虑是否需要rebuild index(?)

20174634-a349c75f69ef4f48b0356eaca568c11

和上面的损失数目一样

9  BLOCKRECOVER 恢复坏块--前提是坏块事先有备份

RMAN> blockrecover from tag=ok datafile 3 block 33,69;--必须要指定坏块号

20175049-c3edf943e3464ad7b982087414a75f5

之后查询tb1,恢复

20175146-9de485c6a8e848e9b14278a7485925f

这时候dbv检测也为0

20175312-6b0202b7d97b405ebd4071c90f71886


18:10 更新,使用oracle内部事件

再次破坏了数据文件,可是查询时候仍然不报错,想到是前面执行了让oracle跳过坏块的过程

exec dbms_repair.skip_corrupt_blocks(schema_name => 'SYS',object_name => 'TB1',flags => 1);

20182031-489824a8c5b14f7da6958b162ad746b

直接将flag=>2

20182201-a6283fae2720489dbb15d6a961d5443

20182633-f2a44e997fb04c748c7f72713f6b86f

SELECT tablespace_name, segment_type, owner, segment_name
FROM dba_extents
WHERE file_id = 3
and 35 between block_id AND block_id + blocks - 1 --这里 35 between不懂

20190307-469fcd6c7d0240b78896baee76e2efd

ALTER SYSTEM SET EVENTS='10231 trace name context forever,level 10' ;

20190604-8e6f83a4daab4901a457750670e6aa1

20190534-bfc0958fe1d9425fb39f29cf6d9a2c6

之后

SQL> ALTER SYSTEM SET EVENTS='10231 trace name context off' ;

系统已更改。

删除表空间

SYS@jsce>drop tablespace tbs1 including contents and datafiles; --表空间物理文件也被删除

之后导入

演示省略。
















本文转自东方之子736651CTO博客,原文链接:http://blog.51cto.com/ecloud/1225235 ,如需转载请自行联系原作者

相关文章
|
4天前
|
vr&ar
检查和修复文件系统错误 - fsck
【1月更文挑战第12天】
75 0
|
存储 JavaScript 测试技术
rpmdb损坏的修复方法
yum强制终止后,提示rpmdb损坏 error: cannot open providename index using db3 - bad file descriptor
8770 0
|
12月前
|
Oracle 关系型数据库 数据库
自动从备库修复主库的坏块
数据库的坏块经常是一件非常棘手的事情,Oracle数据库从11.2后,使用 Active Data Guard option 时,主库和备库可以自动借用对方的block来修复自身的坏块,这个过程对应用是透明的。
|
数据库 索引 关系型数据库
|
Oracle 关系型数据库 数据库
|
Oracle 关系型数据库 数据库管理
|
SQL Oracle 关系型数据库