oracle三种类型坏块的处理思路总结(没有物理备份)

坏块的发生,很罕见,但生产系统偶尔还是会出现。如果有物理备份,处理起来相对简单,直接进行块级recover即可,但如果只有逻辑备份呢?处理起来要分四种情况,在此总结一下:


一、datafile的数据块坏了,在sql执行扫描到这个块的时候会报ORA-01578:

ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 21, block # 12)
ORA-01110: data file 21: '/u01/app/oracle/oradata/RWDB_production/T6.DBF'


但是,这种坏块不会影响数据库重启,只是在重启到open阶段的时候会报:

Thu Nov 20 10:39:00 CST 2014
Corrupt Block Found
         TSN = 26, TSNAME = CORRUPT
         RFN = 21, BLK = 12, RDBA = 88080396
         OBJN = 591083, OBJD = 591083, OBJECT = USER_TAB, SUBOBJECT =
         SEGMENT OWNER = RWUSER, SEGMENT TYPE = Table Segment


db在open的时候会扫描数据文件的状态,这里可以清楚地看到是什么类型的段、什么用户、什么对象出现了坏块。还可以用dbv工具进一步check:

[oracle@BJ-TEST]/u01/app/oracle/admin/RWDB>dbv file=/u01/app/oracle/oradata/RWDB_production/T6.DBF


DBVERIFY - Verification complete

Total Pages Examined         : 25
Total Pages Processed (Data) : 0
Total Pages Failing   (Data) : 0
Total Pages Processed (Index): 0
Total Pages Failing   (Index): 0
Total Pages Processed (Other): 11
Total Pages Processed (Seg)  : 0
Total Pages Failing   (Seg)  : 0
Total Pages Empty            : 13
Total Pages Marked Corrupt   : 1
Total Pages Influx           : 0
Highest block SCN            : 1132783081 (0.1132783081)

这里也可以看到Total Pages Marked Corrupt为1,即有1个坏块。


处理:

这种类型的坏块,处理办法有很多,support上的建议办法如下:

1、用DBMS_REPAIR.SKIP_CORRUPT_BLOCKS处理,即跳过坏块。

2、用CTAS建一个临时表,上面坏了的表为user_tab,可建一个临时表user_tab_tmp

3、将user_tab表重命名:alter table user_tab rename to user_tab_corrupt

4、将user_tab_tmp改为生产系统正式表:alter table user_tab_tmp rename to user_tab

5、重建user_tab表的索引

这种恢复办法,那个坏块里面的数据会丢掉。如果是每天都进行逻辑备份,还可以将现在的user_tab与昨天逻辑备份里面的user_tab进行比对,以最大限度恢复数据。


二、datafile的head块坏了(1号块)

一个8k block大小的数据文件,我们用ultraedit打开,以16进制方式显示,其中00000000~00001ff0是0号块,后面开始是1号块,即这个数据文件的head块。这个块坏了就相当危险,数据库重启会直接报错:

SQL> conn /as sysdba;
Connected to an idle instance.
SQL> startup;
ORACLE instance started.

Total System Global Area  935329792 bytes
Fixed Size                  2100680 bytes
Variable Size             385876536 bytes
Database Buffers          541065216 bytes
Redo Buffers                6287360 bytes
Database mounted.
ORA-01122: database file 24 failed verification check
ORA-01110: data file 24: '/u01/app/oracle/oradata/RWDB_production/T9.DBF'
ORA-01210: data file header is media corrupt


可以看到,数据库打不开了。

alert报下面的东西:
Thu Nov 20 15:11:10 CST 2014
ALTER DATABASE OPEN
Read of rdba: 0x06000001 (file 24, block 1) failed with ORA-01210.
Hex dump of (file 24, block 1) in trace file /u01/app/oracle/admin/RWDB/udump/rwdb_ora_5850.trc
Corrupt block relative dba: 0x06000001 (file 24, block 1)
Bad header found during datafile header read
Data in bad block:
 type: 49 format: 1 rdba: 0x31000031
 last change scn: 0x0000.00000000 seq: 0x31 flg: 0x31
 spare1: 0x0 spare2: 0x0 spare3: 0x0
 consistency value in tail: 0x00000b01
 check value in block header: 0x3131
 block checksum disabled
Trying reread from disk.
Reread of rdba: 0x06000001 (file 24, block 1) failed with ORA-01210
ORA-1122 signalled during: ALTER DATABASE OPEN...


dbv也可以检测到:

[oracle@BJ-TEST]/u01/app/oracle/admin/RWDB/bdump>dbv file=/u01/app/oracle/oradata/RWDB_production/T9.DBF

DBVERIFY - Verification complete

Total Pages Examined         : 25
Total Pages Processed (Data) : 1
Total Pages Failing   (Data) : 0
Total Pages Processed (Index): 0
Total Pages Failing   (Index): 0
Total Pages Processed (Other): 10
Total Pages Processed (Seg)  : 0
Total Pages Failing   (Seg)  : 0
Total Pages Empty            : 13
Total Pages Marked Corrupt   : 1
Total Pages Influx           : 0
Highest block SCN            : 1132794574 (0.1132794574)


如果半夜干升级割接(要重启服务器),遇到这种问题,身边又没有DBA,还是很棘手的,业务直接就会中断,如果是HA的系统,坏的datafile又刚好在磁阵上,那么通过切换也无法解决这个问题,因为oracle资源组就起不来。对于非归档模式的数据库,解决方法如下:

SQL> ALTER DATABASE DATAFILE '/u01/app/oracle/oradata/RWDB_production/T9.DBF' OFFLINE DROP;

Database altered.

SQL> alter database open;

Database altered.


这里,先不管数据丢失与否,先启动了数据库再说,免得故障闹大!:)


三、datafile的os head块坏了(0号块)

什么是datafile的0号块?官方称之为操作系统的头块,里面的东西不是oracle写的,是操作系统记录的文件大小等文件系统相关的信息。0号块坏了,可以正常重启数据库,没问题。但是,如果哪一天遇到紧急问题需要重建控制文件,将会面临报错:

ORA-27047: unable to read the header block of file


对于0号块的检测,用前面的dbv根本检测不出来(dbv命令貌似不检测0号块),需要用dbfsize来检测:

[oracle@BJ-TEST]/u02/backup>dbfsize /u01/app/oracle/oradata/RWDB_production/T8.DBF
/u01/app/oracle/oradata/RWDB_production/T8.DBF: Header block magic number is bad


这里会提示一个什么magic号坏了。

解决方法:

resize一下有问题的数据文件大小,os block head就会被重写,问题可以解决。

alter database datafile '/u01/app/oracle/oradata/RWDB_production/T8.DBF' resize <new size>


四、整个datafile都坏了(各种坏块的综合体)

笔者曾遇到过一次,整个文件都坏了,这种问题,可看做是以上坏块情况的集体爆发。

如:

dbvfile=/data1/app/oracle/oradata/RWDB/IRDBRoamerTS_01.dbf

Total Pages Examined         : 1926

Total Pages Processed (Data) : 0

Total Pages Failing   (Data) : 0

Total Pages Processed (Index): 0

Total Pages Failing   (Index): 0

Total Pages Processed (Other): 0

Total Pages Processed (Seg)  : 0

Total Pages Failing   (Seg) : 0

Total Pages Empty            : 0

Total Pages Marked Corrupt  : 1926

Total Pages Influx           : 0

Highest block SCN            : 0 (0.0)


这里可以看到,总共检测了1926个块,全坏了。如果遇到数据库重启,就无法open成功。

如果有RMAN备份,这种情况就很简单,直接restore、recover坏的数据文件就行。如果没有物理备份,就要先用上面第二种情况的解决办法先把数据库打开,然后再恢复数据。恢复数据的方法,与第二种里面又有所不同,既然这个文件里的块都坏了,再skip哪个块就没意义了。恢复数据的步骤如下:

1、看看这个dbf里面有哪些对象

2、用最新的逻辑备份将上面的对象impdp进新的表空间(如果IRDBRoamerTS_01不是表空间下的唯一文件,也可以不用建新的表空间)

你可能感兴趣的:(oracle,坏块)