/*==============================================================
#内容概要:
# 坏快的分类,坏块形成的原因,如何检测坏快,修复坏块,参考文档。
#
#version 1.0
#date:20120124
================================================================*/
#内容概要:
# 坏快的分类,坏块形成的原因,如何检测坏快,修复坏块,参考文档。
#
#version 1.0
#date:20120124
================================================================*/
/*---------------------------------------------------------------
#
#坏块形成的原因
#
-----------------------------------------------------------------*/
#
#坏块形成的原因
#
-----------------------------------------------------------------*/
1)硬件问题
Oracle进程在处理一个数据块时,首先将其读入物理内存空间,在处理完成后,再由特定进程将其写回磁盘;
如果在这个过程中,出现内存故障,CPU计算失误,都会导致内存数据块的内容混乱,最后反映到写回磁盘的数据块内容有误。
同样,如果存储子系统出现异常,数据块损坏也就随之出现了。
2)操作系统BUG
由于Oracle进程对数据块的读写,都是以操作系统内核调用(system call)的方式完成的,如果操作系统在内核调用存在问题,
必然导致Oracle进程写入非法的内容。
3)操作系统的I/O错误或缓冲问题
4)内存或paging问题
5)Oracle软件BUG
Oracle软件特定版本上,可能出现导致数据块的内容出现异常BUG。
6)非Oracle进程扰乱Oracle共享内存区域
如上文所述,在当数据块的内容被读入主机的物理内存时,如果其他非Oracle进程,对Oracle使用的共享内存区域形成了扰乱,
最终导致写回磁盘的数据块内容混乱。
7)异常关机,掉电,终止服务
异常关机,掉电,终止服务使进程异常终止,而破坏数据块的完整性,导致坏块产生。
/*---------------------------------------------------------------
#
#坏块的分类
#
-----------------------------------------------------------------*/
1)坏块定义:
在Oracle数据库的一个或多个数据块(一个数据块的容量在创建数据库时由db_block_size参数指定,缺省为8K)内出现内容混乱的现象。
由于正常的数据块都有固定的合法内容格式,坏块的出现,导致数据库进程无法正常解析数据块的内容,进而使数据库进程报错乃至挂起,
并级联导致整个数据库实例出现异常。坏块分为物理坏块和逻辑坏块。
在Oracle数据库的一个或多个数据块(一个数据块的容量在创建数据库时由db_block_size参数指定,缺省为8K)内出现内容混乱的现象。
由于正常的数据块都有固定的合法内容格式,坏块的出现,导致数据库进程无法正常解析数据块的内容,进而使数据库进程报错乃至挂起,
并级联导致整个数据库实例出现异常。坏块分为物理坏块和逻辑坏块。
2)物理坏块
理坏块(也可以称为介质坏块)指的是块格式本身是坏的,块内的数据没有任何意义。
3)逻辑坏块
逻辑坏块,指的是块内的数据在逻辑是存在问题。
物理坏块和逻辑坏块的分辨方法参见ORACLE DOCUMENT ID 840978.1
/*---------------------------------------------------------------
#
#检查坏块
#简述发现坏块的方法
#
-----------------------------------------------------------------*/
理坏块(也可以称为介质坏块)指的是块格式本身是坏的,块内的数据没有任何意义。
3)逻辑坏块
逻辑坏块,指的是块内的数据在逻辑是存在问题。
物理坏块和逻辑坏块的分辨方法参见ORACLE DOCUMENT ID 840978.1
/*---------------------------------------------------------------
#
#检查坏块
#简述发现坏块的方法
#
-----------------------------------------------------------------*/
1)用户操作发现坏块
在用户进行DML时返回错误消息(eg ORA-01578,Ora-111).
2) 后台alert log 中发现坏块报错(eg ORA-01578: ORACLE数据块损坏(文件号4,块号35)).
2) 后台alert log 中发现坏块报错(eg ORA-01578: ORACLE数据块损坏(文件号4,块号35)).
3) DBV 检查数据库坏块,针对数据库文件。
语法如下:
具体的语法如下:
具体的语法如下:
关键字 说明 (默认)
----------------------------------------------------
FILE 要验证的文件 (无)
START 起始块 (文件的第一个块)
END 结束块 (文件的最后一个块)
BLOCKSIZE 逻辑块大小 (2048)
LOGFILE 输出日志 (无)
FEEDBACK 显示进度 (0)
PARFILE 参数文件 (无)
USERID 用户名/口令 (无)
SEGMENT_ID 段 ID (tsn.relfile.block) (无)
适用条件及例外:
a. 检查物理坏块和逻辑坏块
b. 因为dbv要求file后面跟的必须是一个文件扩展名,所以如果用裸设备存储的,就必须使用ln链接裸设备到一个文件,
然后再用dbv对这个链接文件进行检查.
4) 利用exp工具导出整个数据库可以检测坏块
----------------------------------------------------
FILE 要验证的文件 (无)
START 起始块 (文件的第一个块)
END 结束块 (文件的最后一个块)
BLOCKSIZE 逻辑块大小 (2048)
LOGFILE 输出日志 (无)
FEEDBACK 显示进度 (0)
PARFILE 参数文件 (无)
USERID 用户名/口令 (无)
SEGMENT_ID 段 ID (tsn.relfile.block) (无)
适用条件及例外:
a. 检查物理坏块和逻辑坏块
b. 因为dbv要求file后面跟的必须是一个文件扩展名,所以如果用裸设备存储的,就必须使用ln链接裸设备到一个文件,
然后再用dbv对这个链接文件进行检查.
4) 利用exp工具导出整个数据库可以检测坏块
适用条件及例外:
a. HWM以上的坏块是不会发现的
b. 索引中存在的坏块是不会发现的
c. 数据字典中的坏块是不会发现的
d. 检查物理坏块
a. HWM以上的坏块是不会发现的
b. 索引中存在的坏块是不会发现的
c. 数据字典中的坏块是不会发现的
d. 检查物理坏块
5) ANALYZE
ANALYZE TABLE tablename VALIDATE STRUCTURE CASCADE
它执行坏块的检查,但是不会标记坏块为corrupt,检测的结果保存在USER_DUMP_DEST目录下的用户trace文件中。
适用条件及例外:
a. 检查逻辑坏块
ANALYZE TABLE tablename VALIDATE STRUCTURE CASCADE
它执行坏块的检查,但是不会标记坏块为corrupt,检测的结果保存在USER_DUMP_DEST目录下的用户trace文件中。
适用条件及例外:
a. 检查逻辑坏块
6) rman
rman 可以在数据库、表空间、数据文件级检测 数据库坏块,可以指定检测物理或者逻辑坏块,用起来十分方便。
eg.
BACKUP CHECK LOGICAL VALIDATE DATAFILE n ;(检测逻辑坏块)
BACKUP VALIDATE DATAFILE n ;(检测物理坏块 )
eg.
BACKUP CHECK LOGICAL VALIDATE DATAFILE n ;(检测逻辑坏块)
BACKUP VALIDATE DATAFILE n ;(检测物理坏块 )
/*---------------------------------------------------------------
#
#修复坏块
#根据不同的情况处理数据库坏块。
#
-----------------------------------------------------------------*/
1)通过上面的检测方法检查数据库的坏块,也可以通过查询v$database_currpt_blocks 视图查看数据库现有的坏块情况。
2)用如下SQL检查出现坏快的OBJ.
SELECT tablespace_name, segment_type, owner, segment_name, partition_name FROM dba_extents WHERE file_id = and between block_id AND block_id + blocks – 1;
2)用如下SQL检查出现坏快的OBJ.
SELECT tablespace_name, segment_type, owner, segment_name, partition_name FROM dba_extents WHERE file_id = and between block_id AND block_id + blocks – 1;
3)保存除坏块以外的其他数据
a)利用以上查处的rowid 建备份表保存数据。
A)先取得坏块中ROW ID的最小值,执行以下的语句:
SELECT dbms_rowid.rowid_create(1,,,,0) from DUAL;
B)取得坏块中的ROW ID的最大值,执行以下的语句:
SELECT dbms_rowid.rowid_create(1,,,+1,0) from DUAL;
C)保存数据
INSERT INTO salvage_table SELECT /*+ ROWID(A) */ * FROM A WHERE rowid < '';
INSERT INTO salvage_table SELECT /*+ ROWID(A) */ * FROM A WHERE rowid >= '‘;
b)通过设置 ALTER SESSION SET EVENTS '10231 TRACE NAME CONTEXT FOREVER, LEVEL 10'; 在session 级别跳过坏块,建立备份表。
create table salvage_table as select * from owner.tablename.
通过设置alter session set events='10231 trace name context off' 终止event.
10231 trace 也可以在系统级设置,整个系统都会忽略坏块。
c)通过调用 DBMS_REPAIR 包来标记坏块并跳过坏块
A) exec DBMS_REPAIR.ADMIN_TABLES('REPAIR_TABLE',1,1,'USERS');
exec DBMS_REPAIR.ADMIN_TABLES('ORPHAN_TABLE',2,1,'USERS');
B)
Set serveroutput on;
DECLARE
cc NUMBER;
BEGIN
DBMS_REPAIR.check_object(schema_name=>'SYS',--注意此处是用户名
object_name =>'DMM',
corrupt_count =>cc);
DBMS_OUTPUT.put_line(TO_CHAR(cc));
END;
C)
DECLARE cc NUMBER;
BEGIN
DBMS_REPAIR.fix_corrupt_blocks(schema_name =>'SYS',
object_name =>'DMM',
fix_count =>cc);
DBMS_OUTPUT.put_line(a=>TO_CHAR(cc));
END;
D)execdbms_repair.skip_corrupt_blocks(schema_name=>'SYS',object_name=>'DMM',flags=>1);
create table salvage_table as select * from owner.tablename.
4)修复坏块
a)有恢复整个文件,备份和LOG,数据库在归档模式。
A) 先offline受影响的数据文件,执行以下的语句:
create table salvage_table as select * from owner.tablename.
4)修复坏块
a)有恢复整个文件,备份和LOG,数据库在归档模式。
A) 先offline受影响的数据文件,执行以下的语句:
ALTER DATABASE DATAFILE 'name_file' OFFLINE;
B) 保留有坏块的数据文件,然后拷贝备份的数据文件。如果恢复的数据文件要求路径不同,执行以下的语句:
ALTER DATABASE RENAME FILE 'old_name' TO 'new_name';
C) 恢复数据文件,执行以下语句:
RECOVER DATAFILE 'name_of_file';
D) Online恢复后的数据文件,执行以下的语句:
D) Online恢复后的数据文件,执行以下的语句:
ALTER DATABASE DATAFILE 'name_of_file' ONLINE;
b)只恢复单个块,要求数据库版本是9.2.0以上,要求配置了Rman的catalog数据库,数据库为归档方式,并且有完整的物理备份。
Rman>run{blockrecover datafile 5 block 11,16;}
c)没有备份和归档,丢失损坏的数据。如果业务能通过别的途径找出丢失的数据也可以恢复。
A) truncate 该表,再用保存的这个表的其他数据重建这张表。
truncate table owner.table_name
create tabale owner.table_name as select * from owner.table_name_bak.
B)如果是索引在重建之前需要备份索引的统计信息,重建之后恢复统计信息。
exec dbms_stats.create_stat_table(ownname => 'YYYY',stattab => 'temp_stat_table_20120115');
b)只恢复单个块,要求数据库版本是9.2.0以上,要求配置了Rman的catalog数据库,数据库为归档方式,并且有完整的物理备份。
Rman>run{blockrecover datafile 5 block 11,16;}
c)没有备份和归档,丢失损坏的数据。如果业务能通过别的途径找出丢失的数据也可以恢复。
A) truncate 该表,再用保存的这个表的其他数据重建这张表。
truncate table owner.table_name
create tabale owner.table_name as select * from owner.table_name_bak.
B)如果是索引在重建之前需要备份索引的统计信息,重建之后恢复统计信息。
exec dbms_stats.create_stat_table(ownname => 'YYYY',stattab => 'temp_stat_table_20120115');
exec dbms_stats.export_index_stats(ownname => 'YYYY',indname => 'IND_GM_PREM_NAS_POLNO',stattab => 'temp_stat_table_20120115',statown => 'YYYY');
ALTER INDEX YYYY.IND_GM_PREM_NAS_POLNO REBUILD parallel 12;
exec dbms_stats.import_index_stats(ownname => 'YYYY',indname => 'IND_GM_PREM_NAS_POLNO',stattab => 'temp_stat_table_20120115',statown => 'YYYY',no_invalidate => true,force => true);
ALTER INDEX YYYY.IND_GM_PREM_NAS_POLNO REBUILD parallel 12;
exec dbms_stats.import_index_stats(ownname => 'YYYY',indname => 'IND_GM_PREM_NAS_POLNO',stattab => 'temp_stat_table_20120115',statown => 'YYYY',no_invalidate => true,force => true);
---------------参考文档
http://xuqingwei.itpub.net/post/37188/500757
http://space.itpub.net/25472150/viewspace-688629
http://www.oracledatabase12g.com/archives/rman-validate-check-logical-database-corrupted-block.html
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10113559/viewspace-715223/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/10113559/viewspace-715223/