0、说明
前段时间刚好遇到生产环境中数据文件出现坏块,当时将文件中数据捞出来后然后暂时将文件进行offline。
如果你也遇到过类似的情况,出于各种原因不得不将文件offline,由于该数据文件被offline后SCN便不再变化,而其它的数据文件的文件头的scn和控制文件中的scn还再进行同步。当我们再次想要online该数据文件时,必然会需要先将该文件进行recover,但当你执行recover的时候,发现redo log已经被覆盖了,相关的归档日志也已经被删除了那么该怎么办呢?
这种情况下我们便可以使用bbed将该文件头的scn改成和其他数据文件的scn一致。
下面通过例子演示下:
1、环境准备
创建测试表空间和测试表:
SQL> create tablespace test_tbs datafile '/u01/app/oracle/oradata/ndwmesp1/datafile/test_tbs01.dbf' size 100M autoextend off;
Tablespace created.
SQL> alter user test default tablespace test_tbs;
User altered.
SQL> create table tbl as select * from dba_objects;
Table created.
为了模拟归档丢失的情况,我们在非归档模式下测试:
startup force mount;
alter database noarchivelog;
alter database open;
查看数据文件SCN:
select file#,to_char(checkpoint_change#),name,status from v$datafile;
接下来我们将刚刚创建的5号文件offline,然后再手动多切换几次日志(模拟redo被覆盖)。
alter database datafile 5 offline drop;
alter system switch logfile;
然后我们再去online该文件,会提示需要recover该文件:
由于我们关闭了归档,此时必然会提示找不到相应的归档文件:
再次查看数据文件SCN,发现现在5号数据文件的SCN小于其它数据文件,此时我们我们如果可以将该文件的SCN从23035190改成23035562即可。
2、bbed修改
这里我们为了保证数据文件的SCN不再变化,我们将数据库启动到mount状态
再次查看数据文件SCN(停库时会进行checkpoint)
set linesize 300
col NAME format a80
select file#,to_char(checkpoint_change#),name,status from v$datafile;
接下来我们使用bbed来修改5号文件的SCN
安装bbed:
–三个依赖的包及其对应的路径
$ORACLE_HOME/rdbms/lib/ssbbded.o
$ORACLE_HOME/rdbms/lib/sbbdpt.o
$ORACLE_HOME/rdbms/mesg/bbedus.msb
cd $ORACLE_HOME/rdbms/lib
–编译bbed
make -f O R A C L E H O M E / r d b m s / l i b / i n s r d b m s . m k B B E D = ORACLE_HOME/rdbms/lib/ins_rdbms.mk BBED= ORACLEHOME/rdbms/lib/insrdbms.mkBBED=ORACLE_HOME/bin/bbed
编辑bbed配置文件:
vi parfile.txt
blocksize=8192
listfile=listfile.txt
mode=edit
password=blockedit
vi listfile.txt
1 /u01/app/oracle/oradata/ndwmesp1/system01.dbf 2128609280
2 /u01/app/oracle/oradata/ndwmesp1/sysaux01.dbf 1730150400
3 /u01/app/oracle/oradata/ndwmesp1/undotbs01.dbf 351272960
4 /u01/app/oracle/oradata/ndwmesp1/users01.dbf 165150720
5 /u01/app/oracle/oradata/ndwmesp1/datafile/test_tbs01.dbf 104857600
注:listfile.txt中内容可通过下面SQL直接查出:
select file#||chr(9)||name||chr(9)||bytes from v$datafile;
进入bbed:
[oracle@cnndwpmesp3T ~]$ bbed parfile=parfile.txt
BBED: Release 2.0.0.0.0 - Limited Production on Wed Feb 17 11:19:14 2021
Copyright © 1982, 2017, Oracle and/or its affiliates. All rights reserved.
************* !!! For Oracle Internal Use only !!! ***************
BBED>
这里我们需要修改的是5号文件的scn和其它文件一致,所以我们先查看下1号文件的信息:
BBED> set file 1 block 1
FILE# 1
BLOCK# 1
BBED> map
File: /u01/app/oracle/oradata/ndwmesp1/system01.dbf (1)
Block: 1 Dba:0x00400001
Data File Header
struct kcvfh, 1248 bytes @0
ub4 tailchk @8188
我们再进一步的去查看kcvfh这个结构,使用p命令:
可以看到kcvpscn这个结构,便是存放的scn,它是基于8K的偏移量为484
dump出这个内容:
显然这里的e5825f01存放的便是1号文件的SCN,我们可以验证下:
由于linux是小字节序的,这意味着实际存的数是反过来的,那么e5825f01实际对应的便是
15f82e5,转换成10进制就是23036645,和前面查出的SCN一致!
接下来我们只需要将5号文件的SCN也修改成e5825f01即可。
修改:
BBED> modify /x e582 dba 5,1 offset 484
应用:
BBED> sum apply
Check value for File 5, Block 1:
current = 0xb147, required = 0xb147
BBED> verify
DBVERIFY - Verification starting
FILE = /u01/app/oracle/oradata/ndwmesp1/datafile/test_tbs01.dbf
BLOCK = 1
至此便已经修改完成,接下来我们便可以开库:
SQL> recover datafile 5;
Media recovery complete.
SQL> alter database datafile 5 online;
Database altered.
SQL> alter database open;
Database altered.
再次查看数据文件SCN,全部一致!