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数据库的后备和恢复————关于检查点的一些知识
当我们使用一个数据库时,总希望数据库的内容是可靠的.正确的,但由于计算机系统的故障(硬件故障.软件故障.网络故障.进程故障和系统故障)影响数据库系统的操作,影响数据库中数据的正确性,甚至破坏数据库,使 ...
随机推荐
- MySQL 拷贝数据库表方式备份,还原后提示 table xxx '' doesn`t exist
MySQL很强大,支持直接拷贝数据库文件快速备份,那数据库文件在哪里呢? 打开MySQL的配置文件 my.ini,找到 datadir 节点,如 datadir="D:/Program Fi ...
- /etc/rc.d/rc与/etc/rc.d/init.d的关系
在这里先解释一下 /etc/rc.d/init.d 里面放的都是什么东西.这个目录存放的是一些脚本,一般是Linux以rpm包安装时设定的一些服务的启动/关闭脚本.系统在安装时装了好多rpm包,这里面 ...
- C和指针 第七章 习题
7.1 hermite递归函数 int hermite(int n, int x) { if (n <= 0) { return 1; } if (n == 1) { return 2 * x; ...
- Java Native Interface 编程系列一
本文是<Java Native Interface Programmer's Guide and Specification>的读书笔记 Java Native Interface可以让编 ...
- 核型SVM
(本文内容和图片来自林轩田老师<机器学习技法>) 1. 核技巧引入 如果要用SVM来做非线性的分类,我们采用的方法是将原来的特征空间映射到另一个更高维的空间,在这个更高维的空间做线性的SV ...
- 理解记忆三种常见字符编码:ASCII, Unicode,UTF-8
理解什么是字符编码? 计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是25 ...
- what's cloud computing? IaaS
Cloud computing has changed the ITC industry. Companies like Amazon, Google and Microsoft have built ...
- Openstack4j 在 Maven 中的构建
什么是 Openstack4j ? OpenStack的官方SDK是基于Python语言的,对于Java程序猿来说,将Python翻译过来未免麻烦.在Openstack官方的Wiki中(戳我直达),我 ...
- 《利用Python进行数据分析: Python for Data Analysis 》学习随笔
NoteBook of <Data Analysis with Python> 3.IPython基础 Tab自动补齐 变量名 变量方法 路径 解释 ?解释, ??显示函数源码 ?搜索命名 ...
- ****CI框架源码阅读笔记7 配置管理组件 Config.php
http://blog.csdn.net/ohmygirl/article/details/41041597 一个灵活可控的应用程序中,必然会存在大量的可控参数(我们称为配置),例如在CI的主配置文件 ...