1、全库备份是否是将备份好的dump文件又进行了压缩呢,或者是导出时使用了压缩参数,
2、全库备份是否使用了rman备份,因为rman备份会跳过数据库高水位线以上的部分,从而减少了需要备份的存储,或者你的服务器上存在坏块现象,rman会跳过这些坏块,这些在数据泵中都无法避免,且rman参数中也有压缩备份文件的设置,
希望我的回答能够对你有所帮助
修复数据库坏块dbv
你也可以用dbv工具看一下你现在其他的数据文件有没有还有坏块的
dbv file='yourfilename'
恢复方法:
当Oracle数据库出现坏块时,Oracle会在警告日志文件(alert_SID.log)中记录坏块的信息:
ORA-01578: ORACLE data block corrupted (file # 7, block # )
ORA-01110: data file : '/oracle1/oradata/V920/oradata/V816/users01.dbf'
其中,<AFN>代表坏块所在数据文件的绝对文件号,代表坏块是数据文件上的第几个数据块
出现这种情况时,应该首先检查是否是硬件及 *** 作系统上的故障导致Oracle数据库出现坏块。在排除了数据库以外的原因后,再对发生坏块的数据库对象进行处理。
1.确定发生坏块的数据库对象
SELECT tablespace_name,
segment_type,
owner,
segment_name
FROM dba_extents
WHERE file_id =
AND between block_id AND block_id+blocks-1
2.决定修复方法
如果发生坏块的对象是一个索引,那么可以直接把索引DROP掉后,再根据表里的记录进行重建;
如果发生坏块的表的记录可以根据其它表的记录生成的话,那么可以直接把这个表DROP掉后重建;
如果有数据库的备份,则恢复数据库的方法来进行修复;
如果表里的记录没有其它办法恢复,那么坏块上的记录就丢失了,只能把表中其它数据坏上的记录取出来,然后对这个表进行重建。
3.用Oracle提供的DBMS_REPAIR包标记出坏块
exec DBMS_REPAIR.SKIP_CORRUPT_BLOCKS('','')
4.使用Create table as select命令将表中其它块上的记录保存到另一张表上
create table corrupt_table_bak
as
select * from corrupt_table
5.用DROP TABLE命令删除有坏块的表
drop table corrupt_table
6.用alter table rename命令恢复原来的表
alter table corrupt_table_bak
rename to corrupt_table
7.如果表上存在索引,则要重建表上的索引
PART2
2014.7.22研究恢复数据库坏块:
Oracle调用标准C的系统函数,对数据块进行读写 *** 作,因此,坏块是有可能由以下几种原因产生:
硬件的I/O错误
*** 作系统的I/O错误或缓冲问题
内存或paging问题
磁盘修复工具
一个数据文件的一部分正在被覆盖
Oracle试图访问一个未被格式化的系统块失败
数据文件部分溢出
Oracle或者 *** 作系统的bug
遇到“ORA-01578:ORACLE data block corrupted”错误
处理方法:1.rman的recover命令可以在数据库保持open状态下只恢复受损的数据块
2.如果没有备份,万不得已之下也可以采用DBMS_REPAIR包的存储过程将受损坏块隔离,同时尽可能地挽救部分数据。
rman backup命令也是检查坏数据块的好工具 一旦读取ORA-19566 即可有问题
此时可用backup validate tablespace user观察详细的信息,可查看到坏块数与跟踪文件
grep‘corrupt’/u01/app/oracle/diag/rdbms/br/br/trace/**.trc
恢复数据块:rman》recover datafile 5 block 203;
批量恢复受损的数据块:recover corruption list
数据块坏块一号坏块,需要做:
run{
sql 'alter database datafile 5 offline'
restore datafile 5
recover datafile 5
sql'alter database datafile 5 online'
}
使用exp/imp恢复
在这种情况下肯定会造成数据的丢失,在这种情况下应采取将数据导出然后重建表再进行导入的方法,来尽量恢复损坏数据块中的数据,但是在有坏块的情况下是不允许导出的,如下命令:Exp test/test file=t.dmp tables=t
导出命令在执行中会报ORA-01578错误,在这错误提示中会提示那个文件号的文件以及这个文件中的哪个块被损坏,如:ORA—01578:ORACLE 数据块损坏(文件号 4,块号 35)
针对以上的提示首先查询那些对象被损坏:
Select tablespace_name,segment_type,owner,segment_name From dba_extents Where file_id=4 and 35 between block_id and block_id+blocks-1
如果被损坏的块是索引,通常可以通过索引重建来解决,如果损坏的是数据(segment_type为table),那么通过设置如下内部事件使得Exp *** 作跳过坏块。
Alter session set events=’10231 trace name context forever,level 10’
然后重新执行导出命令,导出相关的表,然后执行Drop Table命令删除相关表,之后重建表最后导入数据。
使用DBMS_REPAIR恢复
用DBMS_REPAIR当然也会丢失数据。这里不做详细的介绍,有兴趣的可以查看oracle的在线文
3、使用dbms_repair包进行坏块处理
1)首先建立repair_table,用于存放dbms_repair.check_object检测出来的坏块信息
SQL>declare
2begin
3dbms_repair.admin_tables
4(table_name =>'REPAIR_TABLE',--表名
5table_type =>dbms_repair.repair_table,
6action =>dbms_repair.create_action,
7tablespace =>'USERS')--用于指定该表存放的表空间
8end
9/
PL/SQL 过程已成功完成。
SQL>col owner format a10
SQL>col object_name format a20
SQL>col object_type format a20
SQL>select owner, object_name, object_type
2from dba_objects
3where object_name like '%REPAIR_TABLE'
OWNEROBJECT_NAMEOBJECT_TYPE
---------- -------------------- --------------------
SYSREPAIR_TABLETABLE
SYSDBA_REPAIR_TABLEVIEW
Oracle自动创建了一个DBA_REPAIR_TABLE视图。
2)使用dbms_repair.check_object进行坏块检测
SQL>set serveroutput on size 100000
SQL>declare
2rpr_count int
3begin
4rpr_count := 0
5dbms_repair.check_object(
6schema_name =>'SYS',--指定对象模式,也就是对象的所有者
7object_name =>'TEST',--指定对象名,也就是表名
8repair_table_name =>'REPAIR_TABLE',
9corrupt_count =>rpr_count)
10dbms_output.put_line('repair block count: '
11||to_char(rpr_count))
12end
13/
repair block count: 4
PL/SQL 过程已成功完成。
SQL>select object_name, block_id, corrupt_type, marked_corrupt,
2corrupt_description, repair_description
3from repair_table
OBJECT_NAMEBLOCK_ID CORRUPT_TYPE MARKED_COR
-------------------- ---------- ------------ ----------
CORRUPT_DESCRIPTION
-------------------------------------------------------------------------------
REPAIR_DESCRIPTION
-------------------------------------------------------------------------------
TEST196148 TRUE
mark block software corrupt
TEST206148 TRUE
mark block software corrupt
TEST236148 TRUE
mark block software corrupt
TEST316148 TRUE
mark block software corrupt
通过运行dbms_repair.check_object,将坏块信息存放到了repair_table表中,其中有个字段marked_corrupt,用于标识该块是否被标识为坏块,当被标识为true时,即该块被标识为坏块。其中这一步跟oracle文档中的描述有点进入,根据oracle文档,当执行完dbms_repair.check_object时,并不会进行坏块标识,也就是marked_corrupt列的值应该为false,而只有当执行dbms_repair.fix_corrupt_blocks过程后才会进行坏块标识。
3)使用dbms_repair.fix_corrupt_blocks进行坏块标识
SQL>declare
2fix_block_count int
3begin
4fix_block_count := 0
5dbms_repair.fix_corrupt_blocks (
6schema_name =>'SYS',
7object_name =>'TEST',
8object_type =>dbms_repair.table_object,
9repair_table_name =>'REPAIR_TABLE',
10fix_count =>fix_block_count)
11dbms_output.put_line('fix blocks count: ' ||
12to_char(fix_block_count))
13end
14/
fix blocks count: 0
PL/SQL 过程已成功完成。
我们可以见到到fix blocks count=0,即在上一步进行check_object时已经进行了坏块标识了,这一步其实可以省略。(不过没有测试过!)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)