ORACLE block损坏

 

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 EOF
dd f=$FILE bs=$BLOCKSIZE conv=notrunc seek=`expr 1 + $BLOCK` EOF

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/

你可能感兴趣的