dbv 检查数据文件是否有坏块

oracle用户下执行dbv file='/var/oradata/test/system01.dbf'  检查这个文件是否有坏块

示例如下:

1.获取所有数据文件的检查脚本

select 'dbv file='||''''||name||'''' from v$datafile;  --得出所有数据文件的检查脚本

dbv file='/var/oradata/test/system01.dbf'
dbv file='/var/oradata/test/TEST_D_TEST86_TEMP2.dbf'
dbv file='/var/oradata/test/sysaux01.dbf'
dbv file='/var/oradata/test/undotbs01.dbf'

2.将以上都放到1.sh文件中

vi 1.sh

dbv file='/var/oradata/test/system01.dbf'
dbv file='/var/oradata/test/TEST_D_TEST86_TEMP2.dbf'
dbv file='/var/oradata/test/sysaux01.dbf'
dbv file='/var/oradata/test/undotbs01.dbf'

3.执行脚本sh 1.sh > 1.log >2&1

4.最后查看结果

cat 1.log | egrep "FILE|Total Pages Marked Corrupt"

如果每个文件的Total Pages Marked Corrupt这一列都是0的话证明没有坏块。

补充说明:sql语句的拼接。

select 'dbv file='||''''||name||'''' from v$datafile;

用||进行拼接,其他字符串需要使用两个单引号括起来,特殊字符也需要用单引号进行转义。

select tablespace_name,segment_type,owner,segment_name from dba_extents where file_id=28 and 3085095 between block_id AND block_id + blocks - 1;

如果以上查出来的是lob字段的话,则需要通过如下语句查出是哪个表上的lob字段

select table_name from dba_lobs where segment_name=''

案例分享:

用dbv扫的时候发现某个文件坏了4个块:

dbv扫描之后,视图V$DATABASE_BLOCK_CORRUPTION为空,不确定是哪个块号有问题。

于是用如下的语句找出具体哪个文件的块坏了

发现是69号文件的1772816,1772885,1773338,1773402这4个块坏了。

 具体语句如下:(因为是from dual,所以随便查那个库都可以)

select dbms_utility.data_block_address_file(291179792),dbms_utility.data_block_address_block(291179792),

dbms_utility.data_block_address_file(291179861),dbms_utility.data_block_address_block(291179861),      dbms_utility.data_block_address_file(291180314),dbms_utility.data_block_address_block(291180314),      dbms_utility.data_block_address_file(291180378),dbms_utility.data_block_address_block(291180378)    

from dual;

再根据如下语句查这些块对应的对象是哪个

SELECT segment_type, owner, segment_name
  FROM dba_extents
 WHERE (file_id = 69 and 1772816 between block_id AND block_id + blocks - 1)
    or
       (file_id = 69 and 1772885 between block_id AND block_id + blocks - 1)
    or  
       (file_id = 69 and 1773338 between block_id AND block_id + blocks - 1)
    or
       (file_id = 69 and 1773402 between block_id AND block_id + blocks - 1)

如果对应的对象是lob对象的话,再查这个lob是属于哪个表

select e.owner, l.table_name, l.segment_name
        from dba_extents e, dba_lobs l
       where e.owner = l.owner
         and e.segment_name = l.segment_name
         and e.segment_type = 'LOBSEGMENT'
         and l.segment_name='SYS_LOB0001459936C00001$$';

停业务,重建表

如果是表的lob字段损坏的话,可以考虑重建这个表,如果表的数据量不大的话,可以先执行

alter system set events='10231 trace name context forever,level 10';

然后在create table as select * from 表这种方式重建表,重建索引,然后alter system set events '10231 trace name errorstack off'; 关闭跟踪。

如果表很大的话,可以先执行alter system set events='10231 trace name context forever,level 10';然后用数据泵导出导入表。然后alter system set events '10231 trace name errorstack off'; 关闭跟踪。(检查索引有效性)

如果业务不能停的话可以先将表重命名再重建或在导。

当时重建表的时候有这个报错

(create table T_CSL_CLSREPORT_bak0731 as select * from T_CSL_CLSREPORT不会报错,但是create table T_CSL_CLSREPORT as select * from T_CSL_CLSREPORT_bak0731 再建回去的时候会报下面的错)

解决方法可以参考链接:CSDNhttps://mp.csdn.net/mp_blog/creation/editor/126119132

最后记得索引要重新建上,关闭跟踪

如果数据库中多个数据文件都存在坏块的情况(包括system系统文件) 建议找时间停应用服务之后 再在数据库服务器上执行 sqlplus / as sysdba

alter system set events='10231 trace name context forever,level 10';

然后expdp导出数据,dbca新建一个数据库(不能在用原来的数据库实例了),

再impdp导入到新的数据库中。 最后再在应用服务器连接新的这个数据数据库给用户使用。


 


 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值