ORACLE如何验证是否损坏:
1. Checksum:将data block上存储内容通过算法算出值,存放在block头上,每次读写是验证是否一致
功能查看:show parameter db_block_checksum;
默认:true
2. Checking:在内存中验证datablock address(DBA)值是否一致
功能查看:show parameter db_block_checking;
默认:false
如果开启该功能,对系统性能影响10%
3. block version:验证block的system change number(SCN)
手工测试block损坏及修复:
1. 备份你需要损坏的数据文件;
手工产生block损坏:
1. 选择某个表空间中创建表:create table corrup tablespace users as select * from employees;
2. 插入一定数量的数据:insert into corrup select * from corrup;
记录总数据量:select count(*) from corrup; --> 27392
3. 找需要破坏的block:select * from dba_extents where segment_name='CORRUP';
4. 因为segment中间存放数据,所以尽量选择中间的block -->420, 421
5. 创建block破坏程序:(该脚本会连续破坏两个block)
#!/bin/bash
# For training purpose ONLY
# Corrupts 2 consequetive blocks.
# make sure the table is in 2 consequetive blocks
FILE=${1:?'Parameter 1 should be set to file name'}
BLOCK=${2:?'Parameter 2 should be set to the block to be corrupted'}
BLOCKSIZE=${3:?'Parameter 3 should be set to the database block size'}
dd f=$FILE bs=$BLOCKSIZE conv=notrunc seek=$BLOCK
dd f=$FILE bs=$BLOCKSIZE conv=notrunc seek=`expr 1 + $BLOCK`
6. 刷新buffer cache:alter system flush buffer_cache;
7. 运行脚本,进行破坏:
格式:./bc_corrupt.sh "数据文件路径/文件名" 破坏block编号 block_size
例如:./bc_corrupt.sh "/u01/app/oracle/oradata/orcl/users01.dbf" 420 8192
发现block损坏:
1. 设置显示:set autot trace
2. 查询表格:select * from corrup;
定位block损坏:
方法一:dbv file=文件名 blocksize=block_size
例如:(OS中)
cd $ORCLE_BASE/oradata/$ORACLE_SID/
dbv file=users01.dbf blocksize=8192;
方法二:analyze table 表名 validate structure;
例如:(数据库中)
analyze table hr.corrup validate structure;
方法三:使用datapump的exp导出表:exp hr/hr tables=corrup;
注意:expdp导出是不会报错,因为expdp直接读取数据,不验证:expdp hr/hr tables=corrup directory=datamove dumpfile=1.dmp;
方法四:使用RMAN:
检查:RMAN>backup validate tablespace users;
查询检查结果:select * from v$backup_corruption;
方法五:DBVERIFY
作用:dbv工具可以用来验证数据文件的有效性,在数据库恢复之前可以使用该命令对备份文件进行有效性检查,防止因备份文件本身的问题导致数据库无法恢复。当然,dbv命令也可以对在线的数据文件进行检查。
使用:SQL> !dbv file=/oracle/ora11gR2/oradata/secooler/users01.dbf
修复block损坏:
1. 彻底修复:RMAN (datafile编号:select * from dba_data_files;)
RMAN>blockrecover datafile 5 block 420,421;
前提条件是之前有备份
2. 不修复,标记:DBMS_REPAIR
可以标记表和索引,如果是索引,key和rowid都坏,就直接skip;如果只是rowid坏,可以将key dump出来
a. sysdba连接:conn / as sysdba
b. 创建记录表:
BEGIN
DBMS_REPAIR.ADMIN_TABLES (
TABLE_NAME => 'REPAIR_TABLE',
TABLE_TYPE => dbms_repair.repair_table,
ACTION => dbms_repair.create_action,
TABLESPACE => '&tablespace_name');
END;
/
c. 查询block:
set serveroutput on
DECLARE num_corrupt INT;
BEGIN
num_corrupt := 0;
DBMS_REPAIR.CHECK_OBJECT (
SCHEMA_NAME => '&schema_name',
OBJECT_NAME => '&object_name',
REPAIR_TABLE_NAME => 'REPAIR_TABLE',
corrupt_count => num_corrupt);
DBMS_OUTPUT.PUT_LINE('number corrupt: ' || TO_CHAR (num_corrupt));
END;
/
检查结果:select BLOCK_ID, CORRUPT_TYPE, CORRUPT_DESCRIPTION from REPAIR_TABLE;
d. 标记错误block:(DML会自动绕开这些block)
BEGIN
DBMS_REPAIR.SKIP_CORRUPT_BLOCKS (
SCHEMA_NAME => '&schema_name',
OBJECT_NAME => '&object_name',
OBJECT_TYPE => dbms_repair.table_object,
FLAGS => dbms_repair.SKIP_FLAG);
END;
/
e. 修复后,表可以查询,但是记录数减少
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/24751738/viewspace-707175/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/24751738/viewspace-707175/