设为首页 收藏本站
查看: 335|回复: 0

[经验分享] Oracle怎样标记坏块及一次数据恢复

[复制链接]
YunVN网友  发表于 2016-8-14 07:06:23 |阅读模式
  Oracle数据文件的坏块,可分为物理坏块和逻辑坏块。物理坏块(也可以称为介质坏块)指的是块格式本身是坏的,块内的数据没有任何意义。而逻辑坏块,指的是块内的数据在逻辑是存在问题。比如说索引块的索引值没有按从小到大排列。物理坏块一般是由于内存问题、OS问题、IO子系统问题和硬件引起,逻辑坏块一般是是由于Oracle Bug等原因引起。
  Oracle数据文件的每个块,其块头为20字节。其定义如下:(来自于DSI401)
  structkcbh
{
ub1type_kcbh;/*blocktype*/
ub2frmt_kcbh;
ub1spare1_kcbh;
ub1spare2_kcbh;
krdbardba_kcbh;/*relativeDBA*/
ub4bas_kcbh;/*baseofSCN*/
ub2wrp_kcbh;/*wrapofSCN*/
ub1seq_kcbh;/*sequence#ofchangesatthesamescn*/
ub1flg_kcbh;
ub2chkval_kcbh;
};

  在块头中,seq_kcbh(占用1字节,块头偏移14)有着特殊的含义,如果该值为0xff,则表示该块被标记为corruption
  下面我们做一个测试:
  SQL> create table test.t1 as select * from dba_objects;
  表已创建。
  SQL> select header_file,header_block from dba_segments where segment_name=’T1′ and owner=’TEST’;
  HEADER_FILEHEADER_BLOCK
-----------------------
101445
  修改db_block_checksum参数值为TRUE,关闭数据库,我们用ultraedit修改10号文件的1447块的check sum(一个随便>0的数)及flag=0×04。然后再打开数据库。再执行下面的查询:
  SQL> select count(*) from test.t1;
select count(*) from test.t1
*
ERROR 位于第 1 行:
ORA-01578: ORACLE 数据块损坏(文件号10,块号1447)
ORA-01110: 数据文件 10: ‘D:\ORACLE\ORADATA\XJ\TEST01.DBF’
  由于非系统表空间在db_block_checksum参数设为FALSE时,会忽略checksum的检查。所以这里为了测试的方便设置为TRUE。
从上面的错误信息来看,块号1447这个块已经坏了,报的错误是经典的ORA-01578错误。

我们用dbv检查一下这个文件:
  D:\oracle\oradata\XJ>dbv file=TEST01.dbf blocksize=2048
  DBVERIFY: Release 9.2.0.1.0 - Production on 星期一 2月 23 17:20:43 2009
  Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
  DBVERIFY - 验证正在开始 : FILE = TEST01.dbf
标记为损坏的页1447
***
Corrupt block relative dba: 0×028005a7 (file 10, block 1447)
Bad check value found during dbv:
Data in bad block -
type: 6 format: 2 rdba: 0×028005a7
last change scn: 0×0000.0023b43e seq: 0×2 flg: 0×04
consistency value in tail: 0xb43e0602
check value in block header: 0xf0f0, computed block checksum: 0×3a4f
spare1: 0×0, spare2: 0×0, spare3: 0×0
***
  DBVERIFY-验证完成
  检查的页总数:56660
处理的页总数(数据):53947
失败的页总数(数据):0
处理的页总数(索引):30
失败的页总数(索引):0
处理的页总数(其它):2669
处理的总页数(段):0
失败的总页数(段):0
空的页总数:13
标记为损坏的总页数:1
汇入的页总数:0
  dbv检查发现了坏块(check错误)。
而如果用analyze命令检查也会发现有坏块:
  SQL> analyze table test.t1 validate structure;
analyze table test.t1 validate structure
*
ERROR 位于第 1 行:
ORA-01578: ORACLE 数据块损坏(文件号10,块号1447)
ORA-01110: 数据文件 10: ‘D:\ORACLE\ORADATA\XJ\TEST01.DBF’
  我们用dbms_repair来处理这个坏块(实际上如果只是checksum坏了,可以修改checksum为正确的值。但实际情况下,checksum坏了往往意味着坏内的数据已经坏了,大多数情况下只能丢弃):
  SQL>>begin
2dbms_repair.admin_tables(
3table_name=>’REPAIR_TABLE’,
4table_type=>dbms_repair.repair_table,
5action=>dbms_repair.create_action,
6tablespace=>’SYSTEM’);
7end;
8/
  PL/SQL 过程已成功完成。
SQL> set serveroutput on
SQL>declare
2rpr_countint;
3begin
4rpr_count:=0;
5dbms_repair.check_object(
6schema_name=>’TEST’,
7object_name=>’T1′,
8repair_table_name=>’REPAIR_TABLE’,
9corrupt_count=>rpr_count);
10dbms_output.put_line(’repaircount:’||to_char(rpr_count));
11end;
12/
repair count: 1
  PL/SQL 过程已成功完成。
SQL> select object_name, block_id, corrupt_type, marked_corrupt,corrupt_description,
2 repair_description from repair_table;
  OBJECT_NAMEBLOCK_IDCORRUPT_TYPEMARKED_CORCORRUPT_DESCRIPTIONREPAIR_DESCRIPTION
-------------------------------------------------------------------------------------
T114476148TRUEmarkblocksoftware
corrupt
  T114476148TRUEmarkblocksoftware
corrupt
SQL>declare
2fix_countint;
3begin
4fix_count:=0;
5dbms_repair.fix_corrupt_blocks(
6schema_name=>’TEST’,
7object_name=>’T1′,
8object_type=>dbms_repair.table_object,
9repair_table_name=>’REPAIR_TABLE’,
10fix_count=>fix_count);
11dbms_output.put_line(’fixcount:’||to_char(fix_count));
12end;
13/
fixcount:0
  PL/SQL过程已成功完成。
SQL>begin
2dbms_repair.skip_corrupt_blocks(
3schema_name=>’TEST’,
4object_name=>’T1′,
5object_type=>dbms_repair.table_object,
6flags=>dbms_repair.skip_flag);
7end;
8/
  PL/SQL过程已成功完成。
  SQL>selecttable_name,skip_corruptfromdba_tableswheretable_name=’T1′andowner=’TEST’;
  TABLE_NAMESKIP_COR
--------------------------------------
T1ENABLED
  SQL>selectcount(*)fromtest.t1;
  COUNT(*)
----------
28762
  SQL> alter system checkpoint;
  系统已更改。
  从上面可以看到,dbms_repair.fix_corrupt_blocks并不修复checksum错误,也不做坏块标记。通过dbv和用ultraedit检查块头,没有发现任何变化。但是通过dbms_repair.skip_corrupt_blocks过程在数据字典中将表设置为跳过坏块,则在查询时会跳过该块。
  如果用RMAN备份该文件,而后还原该文件后,则这个坏块的seq_kcbh则被设为0xff。而此时用dbv检查该文件则显示的错误信息则为:
  DBVERIFY - 验证正在开始 : FILE = TEST01.dbf
  DBV-00200: 块, dba 41944487, 已经标记为崩溃
  DBVERIFY - 验证完成
  检查的页总数 :56655
处理的页总数(数据):53948
失败的页总数(数据):0
处理的页总数(索引):30
失败的页总数(索引):0
处理的页总数(其它):2669
处理的总页数 (段) : 0
失败的总页数 (段) : 0
空的页总数 :8
标记为损坏的总页数:0
汇入的页总数 :0
  注意这里“标记为损坏的总页数”跟前一次检查的不一样,这里为“0”。
  注意,使用skip_corrupt_blocks只能使oracle跳过Oracle能够读出的块,而如果在操作系统层read调用就失败的,则不能跳过该过。甚至于该会话也可能会被中断。遇到这样的情况,使用dd命令或操作系统的copy(cp)命令都不能复制该文件,rman也不能备份该文件,遇到这样的问题,如果数据文件没有备份怎么办?
  在前几天我们的一个客户就遇上了这样的问题,windows系统,2节点RAC,使用了OCFS,由于存储及硬盘出现问题,1个数据文件出现坏块,连操作系统都不能复制出该文件。这样的情况在前几个月也遇到过,不过那个系统是Linux系统下的RAC(难不成OCFS的问题?二者都用了OCFS)。由于存储出了问题,硬盘亮了黄灯,换盘之后故障仍然存在。需要紧急备份这个库,但是那个文件始终无法复制出来。
  遇到这样的情况,写个脚本把数据插入到另一个表?然后exp出来?到现场发现,那个坏块所在的表,居然有200G以上。有没有更简单的方法?到了客户那里,我利用大约20多分钟的时间,写了个简单的程序来复制这个不能利用操作系统工具复制出来的文件。其原理就是以块为单位读取数据,写入一个新的文件中,遇到读不出来的块,就写个一坏块(seq_kcbh设为0xff,flag_kcbh设为0×04,checksum就随便写入一个值,其他全为0)到新文件中。这样就复制出来了文件,幸运的是,整个文件复制其坏块只有2个。经过测试该文件完全可用。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-257419-1-1.html 上篇帖子: Oracle arraysize 和 fetch size 参数 与 性能优化 说明 下篇帖子: 如何直接阅读Oracle中的trace文件(原创)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表