Oracle数据库坏块的恢复
模拟数据块坏块:
对于发生数据块不一致的数据块,如果当前数据库有备份且处于归档模式,那么就可以利用rman工具数据块恢复功能 对数据块进行恢复,这种方法最简单有效,而且可以在数据文件在线时进行,不会发生数据丢失。对于被有备份的数据库 发生数据块损坏,可能会发生数据的丢失或数据不丢失,这要根据发生坏块的所在的对象决定的,如索引块发生损坏,数据 就不会丢失,重建索引就可以了,发生数据丢失的多发生在表或分区表数据块上。
1.不丢数据的恢复方法
---使用rman工具的 blockrecover blockrecover datafile xx block xx;--修复单个坏块
blockrecover corruption list;--修复全部坏块 SQL> select * from livan.test;
select * from livan.test
*
ERROR at line :
ORA-: ORACLE data block corrupted (file # , block # )
ORA-: data file : '/u02/app/oradata/PSDB/livan_tbs01.dbf'
[oracle@std u02]$ rman target / Recovery Manager: Release 10.2.0.4. - Production on Thu Feb :: Copyright (c) , , Oracle. All rights reserved. connected to target database: PSDB (DBID=) RMAN> blockrecover datafile block ; Starting blockrecover at -FEB-
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid= devtype=DISK channel ORA_DISK_1: restoring block(s)
channel ORA_DISK_1: specifying block(s) to restore from backup set
restoring blocks of datafile
channel ORA_DISK_1: reading from backup piece /u02/PSDB_BACKUP/full_PSDB_870868610
channel ORA_DISK_1: restored block(s) from backup piece
piece handle=/u02/PSDB_BACKUP/full_PSDB_870868610 tag=TAG20150205T115650
channel ORA_DISK_1: block restore complete, elapsed time: :: starting media recovery
media recovery complete, elapsed time: :: Finished blockrecover at -FEB-
[oracle@std u02]$ sqlplus '/as sysdba' SQL*Plus: Release 10.2.0.4. - Production on Thu Feb :: Copyright (c) , , Oracle. All Rights Reserved. Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4. - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options SQL> select * from livan.test; ID NAME
---------- ------------------------------
beijing
shanghai
shandong
如果坏块上的表最近都没有更新,还可以利用bbed的copy命令来从一个最近的备份中copy过来一个数据块恢复,具体不演示。
2.有可能存在数据丢失的恢复(在没有备份没有归档的情况下)
---用户表数据损坏
<1>正常情况下数据条目数
SQL> select count(*) from test; COUNT(*)
----------
<2>制作一个坏块
select rowid,
dbms_rowid.rowid_relative_fno(rowid) rel_fno,
dbms_rowid.rowid_block_number(rowid) blockno,
dbms_rowid.rowid_row_number(rowid) rowno
from livan.test; BBED> set dba ,
DBA 0x0180004c ( ,) BBED> d /v dba , offset
File: /u02/app/oradata/PSDB/livan_tbs01.dbf ()
Block: Offsets: to Dba:0x0180004c
-------------------------------------------------------
06a20000 4c008001 d3220800 l .?.L...?......
b8510000 ddce0000 b4220800 l 窺......菸..?..
ffff0000 l .......A.......
l ................
b4220800 l ?..............
l ................
l ................
l ................ < bytes per line> BBED> modify /x dba , offset
File: /u02/app/oradata/PSDB/livan_tbs01.dbf ()
Block: Offsets: to Dba:0x0180004c
------------------------------------------------------------------------
4c008001 d3220800 b8510000 ddce0000 b4220800
ffff0000
b4220800 < bytes per line> BBED> sum play
BBED-: invalid parameter (play) BBED> sum apply
Check value for File , Block :
current = 0xd0fa, required = 0xd0fa SQL> alter system flush buffer_cache; System altered. SQL> select count(*) from test;
select count(*) from test
*
ERROR at line :
ORA-: ORACLE data block corrupted (file # , block # )
ORA-: data file : '/u02/app/oradata/PSDB/livan_tbs01.dbf'
发现我们第6个文件第76号数据块损坏,报ORA-0178错误,我们知掉只要数据库报ORA-01578错误,
说明该数据块已经被标识为:"software corrupt"
<3>确认坏块的类型
SQL> select segment_name,partition_name,segment_type,owner,tablespace_name
from sys.dba_extents
where file_id=&AFN
and &bad_block_id between block_id and block_id + blocks-;
Enter value for afn:
old : where file_id=&AFN
new : where file_id=
Enter value for bad_block_id:
old : and &bad_block_id between block_id and block_id + blocks-
new : and between block_id and block_id + blocks- SEGMENT_NAME PARTITION_NAME SEGMENT_TYPE OWNER TABLESPACE_NAME
--------------- -------------------- ------------------ ---------- ------------------------------
TEST TABLE LIVAN LIVAN_TBS
经查我们的数据损坏坏位于我们的用户表上,无备份数据会丢失。
<4>标记坏块为"software corrupt"
在第2步的时候全表扫描时已经报ORA-01578错误,说明该数据块已经被标识为:"software corrupt", 正常情况下可以跳过这步。 我们使用dbms_repair包演示标记坏块为"software corrupt"
使用dbms_repair包可参考:http://blog.itpub.net/8494287/viewspace-1357457/
--利用dbms_repair包必须先创建repair table两个表:
SQL> begin
dbms_repair.admin_tables(
table_name=>'REPAIR_TABLE',
table_type=>dbms_repair.repair_table,
action=>dbms_repair.create_action,
tablespace=>'LIVAN_TBS');
end;
/ PL/SQL procedure successfully completed. SQL> col object_name for a20
SQL> select owner,object_name,object_type
from dba_objects
where object_name like '%REPAIR_TABLE%'; OWNER OBJECT_NAME OBJECT_TYPE
------------------------------ -------------------- -------------------
SYS REPAIR_TABLE TABLE
SYS DBA_REPAIR_TABLE VIEW
--再创建orphan key table
SQL> begin
dbms_repair.admin_tables(
table_type=>dbms_repair.orphan_table,
action=>dbms_repair.create_action,
tablespace=>'LIVAN_TBS');
end;
/ PL/SQL procedure successfully completed. SQL> select owner,object_name,object_type
from dba_objects
where object_name like '%ORPHAN_KEY_TABLE%'; OWNER OBJECT_NAME OBJECT_TYPE
------------------------------ -------------------- -------------------
SYS ORPHAN_KEY_TABLE TABLE
SYS DBA_ORPHAN_KEY_TABLE VIEW
--检查对象,检查结果会放到我们之前创建的repair_table中
SQL> set serveroutput on
SQL> declare
rpr_count int;
begin
rpr_count:=;
dbms_repair.check_object(
schema_name=>'LIVAN',
object_name=>'TEST',
repair_table_name=>'REPAIR_TABLE',
corrupt_count=>rpr_count);
dbms_output.put_line('repair count:'||to_char(rpr_count));
end;
/
repair count: PL/SQL procedure successfully completed.
检查出有1个坏块
--检查校验的坏块结果
SQL> select object_name,block_id,corrupt_type,marked_corrupt,
corrupt_description,repair_description
from repair_table; OBJECT_NAM BLOCK_ID CORRUPT_TYPE MARKED_COR CORRUPT_DESCRIP REPAIR_DESCRIPTION
---------- ---------- ------------ ---------- --------------- ------------------------------
TEST TRUE mark block software corrupt
我们知道当marked_corrupt为TRUE时,标识这个数据块已经被标识过software corrupt
---标识坏块为software corrupt(重新演示一下)
SQL> declare
fix_count int;
begin
fix_count:=;
dbms_repair.fix_corrupt_blocks(
schema_name=>'LIVAN',
object_name=>'TEST',
object_type=>dbms_repair.table_object,
repair_table_name=>'REPAIR_TABLE',
fix_count=>fix_count);
dbms_output.put_line('fix count:'||to_char(fix_count));
end;
/
fix count: PL/SQL procedure successfully completed.
--再次检查,因为已经被标志为software corrupt,所以在此标志也没什么变化
SQL> select object_name,block_id,corrupt_type,marked_corrupt,
corrupt_description,repair_description
from repair_table; OBJECT_NAM BLOCK_ID CORRUPT_TYPE MARKED_COR CORRUPT_DESCRIP REPAIR_DESCRIPTION
---------- ---------- ------------ ---------- --------------- ------------------------------
TEST TRUE mark block software corrupt
未被标志为oftware corrupt ,marked_corrupt列会显示FALSE
<5>检查其他关联对象
检查有多少个索引项指向了坏块的记录
SQL> select index_name from dba_indexes
where table_name in (select distinct object_name from repair_table); INDEX_NAME
------------------------------
INDEX_TEST
查询发现有一个索引指向这个坏块
--检查都有多少索引数据
SQL> set serveroutput on
SQL> declare
key_count int;
begin
key_count:=;
dbms_repair.dump_orphan_keys(
schema_name=>'LIVAN',
object_name=>'INDEX_TEST',
object_type=>dbms_repair.index_object,
repair_table_name=>'REPAIR_TABLE',
orphan_table_name=>'ORPHAN_KEY_TABLE',
key_count=>key_count);
dbms_output.put_line('orphan key count:'||to_char(key_count));
end;
/
orphan key count: PL/SQL procedure successfully completed. SQL> select index_name,count(*) from orphan_key_table
group by index_name; INDEX_NAME COUNT(*)
------------------------------ ----------
INDEX_TEST
可以看到有146条数据指向坏块
<6>使用dbms_repair.skip_corrupt_blocks或10231事件方式跳过坏块
SQL> select count(*) from livan.test;
select count(*) from livan.test
*
ERROR at line :
ORA-: ORACLE data block corrupted (file # , block # )
ORA-: data file : '/u02/app/oradata/PSDB/livan_tbs01.dbf' SQL> begin
dbms_repair.skip_corrupt_blocks(
schema_name=>'LIVAN',
object_name=>'TEST',
object_type=>dbms_repair.table_object,
flags=>dbms_repair.skip_flag);
end;
/ PL/SQL procedure successfully completed. SQL> select count(*) from livan.test; COUNT(*)
----------
可以看到当执行完dbms_repair.skip_corrupt_blocks数据可以正常访问了,只是统计出来的数据比原先
少了146条(50604-50458),也就是我们坏块上的数据没有统计,被跳过了。
---使用10231事件跳过
SQL> select count(*) from livan.test; COUNT(*)
---------- SQL> begin
dbms_repair.skip_corrupt_blocks(
schema_name=>'LIVAN',
object_name=>'TEST',
object_type=>dbms_repair.table_object,
flags=>dbms_repair.noskip_flag);
end;
/ PL/SQL procedure successfully completed. SQL> select count(*) from livan.test;
select count(*) from livan.test
*
ERROR at line :
ORA-: ORACLE data block corrupted (file # , block # )
ORA-: data file : '/u02/app/oradata/PSDB/livan_tbs01.dbf' SQL> alter session set events '10231 trace name context forever,level 10'; Session altered. SQL> select count(*) from livan.test; COUNT(*)
---------- SQL> alter session set events '10231 trace name context off'; Session altered.
<7>使用CTAS方式重建表及索引
SQL> create table test_bak as select * from test; Table created. SQL> create index idx_test_bak on test_bak(object_id); Index created. --重建索引语句
SQL> alter index index_test rebuild online; Index altered.
<8>使用重建对象的freelists方式修复原表
使用这种方式防止坏块以后被加入到freelists中 注意这个方法只适用于段空间手动管理的表空间(SEGMENT SPACE MANAGEMENT MANUAL), 否则会报ORA-10614: Operation not allowed on this segment 错误
SQL> begin
dbms_repair.rebuild_freelists(
schema_name=>'LIVAN',
object_name=>'TEST',
object_type=>dbms_repair.table_object);
end;
/
begin
*
ERROR at line :
ORA-: Operation not allowed on this segment
ORA-: at "SYS.DBMS_REPAIR", line
ORA-: at line
<9>坏块中的数据
如果坏块中的数据不可丢失,只能尝试其他方法从恢复坏块内容,这其中也有一些第三方付费工具可使用, 也可进行以下尝试:
*尝试从索引内容中恢复出索引列的内容
*尝试使用logminer,从日志中挖掘
*联系Oracle Support,会有些工具解释数据块中的内容。
Oracle数据库坏块的恢复的更多相关文章
- undo丢失恢复异常恢复,运维DBA反映Oracle数据库无法启动报错ORA-01157 ORA-01110,分析原因为Oracle数据库坏块导致
本文转自 惜纷飞 大师. 模拟基表事务未提交数据库crash,undo丢失恢复异常恢复,运维DBA反映Oracle数据库无法启动报错ORA-01157 ORA-01110,分析原因为Oracle数据库 ...
- 12 oracle 数据库坏块--物理坏块-ORA-01578/ORA-01110
oracle 数据库坏块--物理坏块 数据坏块的类型物理坏块:通常是由于硬件损坏如磁盘异常导致.内存有问题.存储链有问题. IO有问题.文件系统有问题. Oracle本身的问题等逻辑坏块:可能都是软件 ...
- 13 oracle数据库坏块-逻辑坏块(模拟/修复)
13 oracle数据库坏块-逻辑坏块 逻辑数据坏块的场景1)oracle bug也可能导致逻辑坏块的产生. 特别是parallel dml. 例如:Bug 5621677 Logical corru ...
- 对Oracle数据库坏块的理解
1.物理坏块和逻辑坏块 在数据库中有一个概念叫做数据块的一致性,Oracle的数据块的一致性包括了两个层次:物理一致性和逻辑一致性,如果一个数据块在这两个层次上存在不一致性,那就对应到了我们今天要要说 ...
- 使用BBED模拟Oracle数据库坏块
BBED(OracleBlockBrowerandEDitor Tool),用来直接查看和修改数据文件数据的一个工具,是Oracle一款内部工具,可以直接修改Oracle数据文件块的内容,在一些极端恢 ...
- 使用不同用户对Oracle数据库进行异机恢复,失败,错误:Backup file not found in NetBackup catalog
最近做某数据库恢复演练,数据库版本是10.2.0.4,恢复控制文件一直报错,报错如下,经过反复折腾,原来恢复机上oracle用户不是oracle导致(我的是oraclev4),查看源库oracle用户 ...
- 【转】基于RMAN实现坏块介质恢复(blockrecover)
本文转自:乐沙弥的世界 对于物理损坏的数据块,我们可以通过RMAN块介质恢复(BLOCK MEDIA RECOVERY)功能来完成受损块的恢复,而不需要恢复整个数据库或所有文件来修复这些少量受损的数据 ...
- Oracle 处理坏块
本文主要介绍如何去处理在Oracle数据库中出现坏块的问题,对于坏块产生在不同的对象上,处理的方法会有所不同,本文将大致对这些方法做一些介绍.因为数据库运行时间长了,由于硬件设备的老化,出现坏块的几率 ...
- Oracle数据库的后备和恢复————关于检查点的一些知识
当我们使用一个数据库时,总希望数据库的内容是可靠的.正确的,但由于计算机系统的故障(硬件故障.软件故障.网络故障.进程故障和系统故障)影响数据库系统的操作,影响数据库中数据的正确性,甚至破坏数据库,使 ...
随机推荐
- UIScrollView的其他属性
@property(nonatomic) BOOL bounces; 设置UIScrollView是否需要弹簧效果 @property(nonatomic,getter=isScrollEnabled ...
- IOS系统基础知识
在iOS应用中,每个程序得main函数中都调用了UIApplicationMain函数. 1 2 3 4 5 6 int main(int argc, char *argv[]) { @a ...
- PHP计算一年有多少周,每周开始日期和结束日期
一年有多个周,每周的开始日期和结束日期 参考代码一:[正在使用的版本] <?php header("Content-type:text/html;charset=utf-8" ...
- 编程之美读书笔记之 -寻找出现次数为1的ID的问题
问题描述: 在一张表里面保存了N个ID,有N-1个ID是出现了两次的,只有一个ID只出现了一次,现在要你把这个ID找出来.如果是两个呢? 解法一: 我们先来解决一个的.假如ID的值的范围是1-k, ...
- word201612012
I/O (input/output) port / 输入/输出端口 IAS, Internet Authentication Service / Internet 验证服务 ICMP, Interne ...
- StartUML反向(逆向)Java工程通过代码生成类图
在软件工程中,通过都是先了详细设计,然后按照详细设计来进行开发.在编写详细设计的时候,通常都会画一些类图.时序图.流程图等等UML设计,然后通过uml类图生成代码,这个属于正向工程生成代码,然而在实 ...
- js跨域解决方案(转载)
1.什么是跨域 我们经常会在页面上使用ajax请求访问其他服务器的数据,此时,客户端会出现跨域问题. 跨域问题是由于javascript语言安全限制中的同源策略造成的. 简单来说,同源策略是指一段脚本 ...
- linux c 笔记-2 Hello World & main函数
按照惯例撸一个hello_world.c #include <stdio.h> int main(int argc, char * argv[]) { printf("hello ...
- redis cluster php 客户端 predis
php有redis的扩展,目前来说,还不支持redis cluster,推荐一下predis,功能比较全,从单个,到主从,到cluster都是支持的.效率怎么样,要靠自己去测试一下. 1,下载pred ...
- spring jpa 实体互相引用返回restful数据循环引用报错的问题
spring jpa 实体互相引用返回restful数据循环引用报错的问题 Java实体里两个对象有关联关系,互相引用,比如,在一对多的关联关系里 Problem对象,引用了标签列表ProblemLa ...