数据文件头部位图block损坏怎么办

近期某客户的一个核心出现异常;其中某个数据文件头部位图block损坏,导致业务收到现在。那么针对这种情况,该如何处理呢?

通常的做法有如下3种:

1、使用dbms_space_admin去重建表空间的bitmap block信息;这种方案通常情况下执行都不会成功。

2、将问题文件上面的对象全部move到其他表空间种,并drop该datafile。

3、移动整个问题表空间的对象,然后drop重建整个表空间;一般来讲,如果表空间比较大,这个方案通常不可行。

因此,我们可能多数情况下都会选择第2种方案。

这里我们先来模拟一下客户环境种的实际错误情况。

1、创建测试表空间并增加数据文件

SQL> alter tablespace test add datafile '/data/app/oracle/oradata/killdb/test2.dbf' size 20m;

Tablespace altered.

SQL> create table test110 tablespace test as select * from dba_objects;

Table created.

SQL> select distinct owner,segment_name,file_id from  dba_extents where tablespace_name='TEST' order by 3;

OWNER                          SEGMENT_NAME                      FILE_ID
------------------------------ ------------------------------ ----------
ROGER                          TEST                                    5
ROGER                          TEST110                                 5
ROGER                          TEST2                                   5
ROGER                          TEST110                                 6

 

2、dump datafile bitmap信息

execute dbms_space_admin.tablespace_dump_bitmaps('TEST');
......

File Space Bitmap Block:
BitMap Control:
RelFno: 6, BeginBlock: 128, Flag: 0, First: 304, Free: 63184
FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF
FFFFFFFFFFFF0000 0000000000000000 0000000000000000 0000000000000000

从上述dump的trace种我们可以看到file 6文件头部前面的file space bitmap block信息。

3、bbed修改文件头

BBED> set file 6 block 3
        FILE#           6
        BLOCK#          3

BBED> d /v count 100
 File: /data/app/oracle/oradata/killdb/test2.dbf (6)
 Block: 3       Offsets:    0 to   99  Dba:0x01800003
-------------------------------------------------------
 1ea20000 03008001 11431200 00000104 l .........C......
 16b10000 06000000 80000000 00000000 l ................
 30010000 d0f60000 00000000 00000000 l 0...............
 00000000 00000000 ffffffff ffffffff l ................
 ffffffff ffffffff ffffffff ffffffff l ................
 ffffffff ffffffff ffffffff ffff0000 l ................
 00000000                            l ....

 <16 bytes per line>

BBED> d /v offset 32 count 8
 File: /data/app/oracle/oradata/killdb/test2.dbf (6)
 Block: 3       Offsets:   32 to   39  Dba:0x01800003
-------------------------------------------------------
 30010000 d0f60000                   l 0.......

 <16 bytes per line>

BBED>  modify /x 2f01 offset 32
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
 File: /data/app/oracle/oradata/killdb/test2.dbf (6)
 Block: 3                Offsets:   32 to   39           Dba:0x01800003
------------------------------------------------------------------------
 2f010000 d0f60000

 <32 bytes per line>

BBED> modify /x cf 0ffset 36
BBED-00400: invalid blocktype (30)


BBED> modify /x cf offset 36
 File: /data/app/oracle/oradata/killdb/test2.dbf (6)
 Block: 3                Offsets:   36 to   43           Dba:0x01800003
------------------------------------------------------------------------
 cff60000 00000000

 <32 bytes per line>

BBED> sum apply
Check value for File 6, Block 3:
current = 0xb116, required = 0xb116

这里我们修改frist和end rdba地址即可。

4、尝试通过move表然后drop 数据文件

SQL> conn roger/roger
Connected.
SQL> alter table test move tablespace users;

Table altered.

SQL> alter table test2 move tablespace users;
alter table test2 move tablespace users
            *
ERROR at line 1:
ORA-00607: Internal error occurred while making a change to a data block
ORA-00600: internal error code, arguments: [kdBlkCheckError], [6], [3],
[18018], [], [], [], [], [], [], [], []


SQL> drop table test2;

Table dropped.

SQL> alter tablespace test drop datafile '/data/app/oracle/oradata/killdb/test2.dbf';
alter tablespace test drop datafile '/data/app/oracle/oradata/killdb/test2.dbf'
*
ERROR at line 1:
ORA-00607: Internal error occurred while making a change to a data block
ORA-00600: internal error code, arguments: [kdBlkCheckError], [6], [3],
[18018], [], [], [], [], [], [], [], []

 

那么如果处理这个问题呢。首先我们确实需要讲损坏文件上面的对象都挪走或者drop掉(如果可以drop的话).

当把对象都move或者drop后;我们再进行drop datafile操作时,发现仍然会提示坏块。这种情况下,其实处理也比较简单。

既然对都不存在了,那么可以完全可以把该文件理解为一个空文件。通过在同一个表空间种增加一个空的数据文件的方式,然后copy同样的block

进行覆盖即可。

SQL> alter tablespace test add datafile '/data/app/oracle/oradata/killdb/test3.dbf' size 50m;

Tablespace altered.

SQL>  alter system flush buffer_cache;

System altered.
BBED> copy file 7 block 3 to file 6 block 3
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
 File: /data/app/oracle/oradata/killdb/test2.dbf (6)
 Block: 3                Offsets:    0 to   19           Dba:0x01800003
------------------------------------------------------------------------
 1ea20000 0300c001 09491200 00000104 48410000

 <32 bytes per line>

BBED> set file 6 block 3
        FILE#           6
        BLOCK#          3

BBED> modify /x 03008001 offset 4
 File: /data/app/oracle/oradata/killdb/test2.dbf (6)
 Block: 3                Offsets:    4 to    7           Dba:0x01800003
------------------------------------------------------------------------
 03008001

 <32 bytes per line>

BBED> sum apply
Check value for File 6, Block 3:
current = 0x4108, required = 0x4108

BBED> verify
DBVERIFY - Verification starting
FILE = /data/app/oracle/oradata/killdb/test2.dbf
BLOCK = 3


DBVERIFY - Verification complete

Total Blocks Examined         : 1
Total Blocks Processed (Data) : 0
Total Blocks Failing   (Data) : 0
Total Blocks Processed (Index): 0
Total Blocks Failing   (Index): 0
Total Blocks Empty            : 0
Total Blocks Marked Corrupt   : 0
Total Blocks Influx           : 0
Message 531 not found;  product=RDBMS; facility=BBED

接下来最后我们来试试能否drop这个不需要的文件。

SQL>  alter system flush buffer_cache;

System altered.

SQL> alter tablespace test drop datafile '/data/app/oracle/oradata/killdb/test2.dbf';

Tablespace altered.

可以看到,我们非常顺利删除了这个问题文件。

很久没写文章了;比较简单的测试;供大家参考!


评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注