欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Oracle 数据库对象坏块处理思路ORA-01578

程序员文章站 2022-03-24 09:05:22
业务对象上的坏块通常不会导致数据库宕机。假设数据库没有备份,数据库对象坏块的处理思路如下:(1) 可以使用dbv RMAN的backup valiadate 或者 validate命令校验数据库的坏块数量。(2)根据坏块的文件号块号确定坏块对象。&nbs...

      业务对象上的坏块通常不会导致数据库宕机。假设数据库没有备份,数据库对象坏块的处理思路如下:
      (1) 可以使用dbv RMAN的backup valiadate 或者 validate命令校验数据库的坏块数量。
      (2)根据坏块的文件号块号确定坏块对象。
      (3)如果索引出现坏块,则考虑删除并重建索引.
      (4)如果表出现坏块,则设置10231事件或使用dbms_repair包跳过坏块扫描,后续将表导出再导入或者使用CTS创建新表后重命名,
      (5)使用bbed工具尝试修复坏块.

一:使用BBED制造坏块:

创建测试表空间:
SQL>create tablespace test datafile '/oracle/app/oradata/prod/test01.dbf' size 50M;

创建测试表:
SQL>create table test tablespace test as select * from dba_objects;

SQL> select count(*) from test;
  COUNT(*)
----------
     86957

查询表所占用数据块信息:
SQL> select SEGMENT_NAME,HEADER_FILE,HEADER_BLOCK,BLOCKS from dba_segments where SEGMENT_NAME='TEST' and OWNER='SYS';
SEGMENT_NAME     HEADER_FILE HEADER_BLOCK     BLOCKS
----------------------------------- -----------  --------------------- -------------------
TEST                                       6                 130                        1280
块头为130 共1280个块
在bbed中块头为131 共1280个块


使用bbed制造坏块:
BBED> set filename '/oracle/app/oradata/prod/test01.dbf';
        FILENAME        /oracle/app/oradata/prod/test01.dbf
        
BBED> set block 150
        BLOCK#          150
        
 BBED> dump /v offset 0 count 32
 File: /oracle/app/oradata/prod/test01.dbf (0)
 Block: 150     Offsets:    0 to   31  Dba:0x00000000
-------------------------------------------------------
 06a20000 96008001 e20c1100 00000204 l .¢......â.......
 6f8f0000 01000000 415a0100 d80c1100 l o.......AZ..Ø...
 
 
BBED> set mode edit;
        MODE            Edit

BBED> modify /x 12345678 offset 0
 File: /oracle/app/oradata/prod/test01.dbf (0)
 Block: 150              Offsets:    0 to   31           Dba:0x00000000
------------------------------------------------------------------------
 12345678 96008001 e20c1100 00000204 6f8f0000 01000000 415a0100 d80c1100      
BBED> sum apply;
Check value for File 0, Block 150:
current = 0x612d, required = 0x612d

SQL> alter system flush buffer_cache;
System altered.

再开一个会话

SQL> select count(*) from test;
select count(*) from test
                     *
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 6, block # 150)
ORA-01110: data file 6: '/oracle/app/oradata/prod/test01.dbf'

Oracle BBED工具介绍与安装

二:校验坏块几种方式:

1.使用dbv工具校验坏块:

[oracle@server1 ~]$ dbv userid=system/oracle file=/oracle/app/oradata/prod/test01.dbf blocksize=8192
DBVERIFY: Release 11.2.0.4.0 - Production on Sat Oct 10 22:06:59 2020
Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.
DBVERIFY - Verification starting : FILE = /oracle/app/oradata/prod/test01.dbf
Page 150 is marked corrupt
Corrupt block relative dba: 0x01800096 (file 6, block 150)
Bad header found during dbv: 
Data in bad block:
 type: 18 format: 4 rdba: 0x01800096
 last change scn: 0x0000.00110ce2 seq: 0x2 flg: 0x04
 spare1: 0x56 spare2: 0x78 spare3: 0x0
 consistency value in tail: 0x0ce20602
 check value in block header: 0x612d
 computed block checksum: 0x0
DBVERIFY - Verification complete
Total Pages Examined         : 6400
Total Pages Processed (Data) : 1241
Total Pages Failing   (Data) : 0
Total Pages Processed (Index): 0
Total Pages Failing   (Index): 0
Total Pages Processed (Other): 154
Total Pages Processed (Seg)  : 1
Total Pages Failing   (Seg)  : 0
Total Pages Empty            : 5003
Total Pages Marked Corrupt   : 1
Total Pages Influx           : 0
Total Pages Encrypted        : 0
Highest block SCN            : 1124771 (0.1124771)

2.RMAN工具校验:

RMAN> backup validate datafile 6
RMAN就像真正备份时一样读取整个要备份的文件,但RMAN实际上并不产生任何备份集或镜像副本。
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
6    FAILED 0              5003         6400            1124771   
  File Name: /oracle/app/oradata/prod/test01.dbf
  Block Type Blocks Failing Blocks Processed
  ---------- -------------- ----------------
  Data       0              1241            
  Index      0              0               
  Other      1              156             
validate found one or more corrupt blocks
See trace file /oracle/app/diag/rdbms/prod/prod/trace/prod_ora_4542.trc for details
  
或者
RMAN> validate datafile 6;
RMAN> validate datafile 6 block 150;
使用validate命令可以手动检查数据库文件中物理损坏或逻辑损坏和数据文件丢失,或者确定备份集是否可以用于还原。

校验出来的坏块会记录在v$database_block_corruption视图中
SQL> select * from v$database_block_corruption;
     FILE#     BLOCK#     BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
         6        150          1                  0 CORRUPT

三:坏块处理方式:
1.首先确定坏块对象是表还是索引

根据报错提示的文件号块号确定坏块对象:
SQL>select tablespace_name,segment_type,owner,segment_name from dba_extents where file_id=6 and 150 between block_id AND block_id + blocks - 1;

2.如果是索引对象损坏可以进行重建

alter index indexname rebuild 

3.如果是表对象损坏,分为以下几种情况

情况1:
如果存在RMAN备份,那么可以使用RMAN恢复
RMAN>blockrecover datafile 6 block 150;
或者使用
RMAN> recover corruption list;

情况2:
如果数据文件不存在RMAN备份,但是存在数据文件冷备份,那么也可以使用BBED COPY命令恢复,存在风险
可以参考:
https://blog.csdn.net/baoyuhang0/article/details/108980548

情况3:
如果不存在备份,那么坏块部分的数据肯定要丢失了.
首先需要进行跳过坏块扫描(两种方式):
方式一:
SQL> exec dbms_repair.skip_corrupt_blocks('SYS','TEST');

SQL> select skip_corrupt from user_tables where table_name='TEST';
SKIP_COR
--------
ENABLED //跳过坏块扫描已开启

方式二:
设置10231 内部事件,设置在全表扫描时跳过损坏的数据块
alter system set events '10231 trace name context forever,level 10'

再次查询已经无坏块报错,但是数据丢失一部分
SQL> select count(*) from TEST;    
  COUNT(*)
----------
     86879
     
86957->86879 对比丢失部分数据


后续可以使用expdp/impdp将数据导出再导入(如果不跳过坏块扫描则expdp会失败)
或者CTS创建新表再重命名:

例如设置10231事件:
alter session SET EVENTS '10231 trace name context forever,level 10';
create table tab_new as select * from tab;
rename tab to tab_bak;
rename tab_new to new;
alter index indexname rebuild;
alter session SET EVENTS '10231 trace name context off';

四:BBED修复坏块

待补充

本文地址:https://blog.csdn.net/baoyuhang0/article/details/108998977