1.前言
Oracle 数据库的运行不可避免的会遇到各种各样的错误,就比如数据表出现坏块,此时,你这张表的数据就无法访问了,有什么好的办法可以恢复呢?
2.介绍
对于oracle数据块物理损坏的情形,通常可以分为两种情况:
- 有备份,通过RMAN恢复
- 无备份,通过DBMS_REPAIR修复
3.RMAN方法
有备份的情况下,这是很理想的情况,我们可以直接通过RMAN块介质恢复(block media recovery)功能来完成受损块的恢复
这里不建议恢复整个数据库或者数据文件来修复这些少量受损的数据块,有点浪费时间
可参考官方文档:Block Media Recovery with RMAN
4.DBMS_REPAIR
如果没有任何备份怎么办呢?这里可以使用oracle自带的DBMS_REPAIR包来修复
注意使用DBMS_REPAIR包来修复,并非是完全恢复,而是标记坏块,然后不对其进行访问,这部分被标记的数据也就丢失了,这是无法避免的。
可参看MOS文档:DBMS_REPAIR SCRIPT(Doc ID 556733.1)
5.坏块检查
下面在再介绍几种发现坏块的方式:
1.使用DBV检查当前文件的坏块:
dbv file=/oradata/orcl/eason.dbf blocksize=8192;
2.使用rman检查数据库坏块:
##检查对应的数据文件 backup check logical validate datafile 5; ##检查当前数据库 backup validate check logical database;
RMAN> backup check logical validate datafile 6; Starting backup at 19-DEC-21 using target database control file instead of recovery catalog allocated channel: ORA_DISK_1 channel ORA_DISK_1: SID=22 device type=DISK channel ORA_DISK_1: starting full datafile backup set channel ORA_DISK_1: specifying datafile(s) in backup set input datafile file number=00006 name=/data/oracle/oradata/orcl/test01.dbf channel ORA_DISK_1: backup set complete, elapsed time: 00:00:15 List of Datafiles ================= File Status Marked Corrupt Empty Blocks Blocks Examined High SCN ---- ------ -------------- ------------ --------------- ---------- 6 FAILED 0 791 1280 2844729 File Name: /data/oracle/oradata/orcl/test01.dbf Block Type Blocks Failing Blocks Processed ---------- -------------- ---------------- Data 0 103 Index 0 0 Other 247 386 validate found one or more corrupt blocks See trace file /data/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_43010.trc for details Finished backup at 19-DEC-21
结合v$database_block_corruption 视图查看,更方便。
SQL> select * from v$database_block_corruption; FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTION_TYPE ---------- ---------- ---------- ------------------ ------------------ 6 1035 246 0 CORRUPT 6 1034 1 0 FRACTURED
3.通过数据库的告警日志也可以发现报错
4.通过报错信息快速查找对应的坏表,依次填写数据文件ID和坏块id
SELECT tablespace_name, segment_type, owner, segment_name FROM dba_extents WHERE file_id = &fileid and &blockid between block_id AND block_id + blocks - 1;
5.RMAN备份
首先,我们先做一个全备份,用来演示RMAN修复坏块
run { allocate channel c1 device type disk; allocate channel c2 device type disk; crosscheck backup; crosscheck archivelog all; sql"alter system switch logfile"; delete noprompt expired backup; delete noprompt obsolete device type disk; backup database include current controlfile format '/backup/backlv_%d_%T_%t_%s_%p'; backup archivelog all DELETE INPUT; release channel c1; release channel c2; }
6.用RMAN修复
由于之前我们已经备份了,因此直接使用备份来恢复坏块
blockrecover datafile 5 block 1468;
修复完成之后,我们再用如下命令检查:
select * from v$database_block_corruption;
7.DBMS_REPAIR修复
1.创建repaire表,用于记录需要被修复的表:
begin dbms_repair.admin_tables ( table_name => 'REPAIR_TABLE', table_type => dbms_repair.repair_table, action => dbms_repair.create_action, tablespace => 'USERS'); end; /
2.创建Orphan key表,用与记录在表块损坏后那些孤立索引,也就是指向坏块的那些索引
begin dbms_repair.admin_tables ( table_name => 'ORPHAN_KEY_TABLE', table_type => dbms_repair.orphan_table, action => dbms_repair.create_action, tablespace => 'USERS'); end; /
3.检查坏块,检查对象上受损的情形,并返回受损块数为3:
declare num_corrupt int; begin num_corrupt := 0; DBMS_REPAIR.CHECK_OBJECT ( schema_name =>'EASON', object_name =>'HYJ', repair_table_name =>'REPAIR_TABLE', corrupt_count =>num_corrupt); dbms_output.put_line('number corrupt:' || to_char(num_corrupt)); end; /
4.查看受损的块的信息:
select object_name, block_id, corrupt_type, marked_corrupt, repair_description from repair_table;
这里marked_corrupt被标记为TRUE,应该是系统在执行check_OBJECt过程中自动完成了FIX_CORRUPT_BLOCKS。如果被标记为 FALSE,需要再运行 FIX_CORRUPT_BLOCKS
来完成坏块的标记工作
未完:
转载于: https://mp.weixin.qq.com/s/4219yZn1Q5tGxuy2sSOq6Q