利用 BBED 恢复非归档模式下 OFFLINE 数据文件

今天来模拟一个非归档模式下恢复OFFLINE数据文件的场景,主要有2种情况:

一种是在线日志没有被覆盖,另一种是在线日志被覆盖。

第一种情况比较简单,数据库自身就能处理,而第二种情况稍显复杂,但也并不难,下面开始整个实验过程:

一、在线日志没有被覆盖的场景

--切换数据库到非归档模式

SQL> archive log list

Database log mode      
Archive Mode

Automatic archival      
Enabled

Archive destination       USE_DB_RECOVERY_FILE_DEST

Oldest online log sequence     6

Next log sequence to archive   8

Current log sequence       8

SQL> shutdown immediate

Database closed.

Database dismounted.

ORACLE instance shut down.

SQL> startup mount

ORACLE instance started.

Total System Global Area  285212672 bytes

Fixed Size    1218992 bytes

Variable Size  125830736 bytes

Database Buffers  155189248 bytes

Redo Buffers    2973696 bytes

Database mounted.

SQL> alter database noarchivelog;

Database altered.

SQL> archive log list

Database log mode      
No Archive Mode

Automatic archival      
Disabled

Archive destination       USE_DB_RECOVERY_FILE_DEST

Oldest online log sequence     6

Current log sequence       8

SQL>

--创建测试环境(创建表空间,创建用户,创建测试表,插入数据)

SQL> create tablespace zlm_test datafile ‘/u01/app/oracle/oradata/ora10g/zlm_test01.dbf‘ size 50M;

Tablespace created.

SQL> create user zlm1 identified by oracle;

User created.

SQL> grant connect,resource to zlm1;

Grant succeeded.

SQL> alter user zlm1 default tablespace zlm_test;

User altered.

SQL> conn zlm1/oracle

Connected.

SQL> create table offline_test(id int,name varchar2(10));

Table created.

SQL> insert into offline_test values(1,‘aaron8219‘);

1 row created.

SQL> commit;

Commit complete.

--查看数据文件检查点SCN

SQL> set line 130

SQL> col name for a45

SQL> select file#,name,status,checkpoint_change# from v$datafile order by 1;

FILE# NAME STATUS  CHECKPOINT_CHANGE#

---------- --------------------------------------------- ------- ------------------

1 /u01/app/oracle/oradata/ora10g/system01.dbfSYSTEM    551520

2 /u01/app/oracle/oradata/ora10g/undotbs01.dbf  ONLINE    551520

3 /u01/app/oracle/oradata/ora10g/sysaux01.dbfONLINE    551520

4 /u01/app/oracle/oradata/ora10g/users01.dbfONLINE    551520

5 /u01/app/oracle/oradata/ora10g/example01.dbf  ONLINE    551520

6 /u01/app/oracle/oradata/ora10g/zlm01.dbfONLINE    551520

7 /u01/app/oracle/oradata/ora10g/zlm02.dbfONLINE    551520

8 /u01/app/oracle/oradata/ora10g/zlm_test01.dbfONLINE   551753

此时8号数据文件的checkpoint SCN是551753,比其他文件都biger,或者说newer

尽管刚才插入一行数据后已经commit过了,但db buffer cache并不一定会立即刷到磁盘文件,需要手动执行检查点

SQL> alter system checkpoint;

System altered.

SQL> select file#,name,status,checkpoint_change# from v$datafile order by 1;

FILE# NAME STATUS  CHECKPOINT_CHANGE#

---------- --------------------------------------------- ------- ------------------

1 /u01/app/oracle/oradata/ora10g/system01.dbfSYSTEM    552134

2 /u01/app/oracle/oradata/ora10g/undotbs01.dbf  ONLINE    552134

3 /u01/app/oracle/oradata/ora10g/sysaux01.dbfONLINE    552134

4 /u01/app/oracle/oradata/ora10g/users01.dbfONLINE    552134

5 /u01/app/oracle/oradata/ora10g/example01.dbf  ONLINE    552134

6 /u01/app/oracle/oradata/ora10g/zlm01.dbfONLINE    552134

7 /u01/app/oracle/oradata/ora10g/zlm02.dbfONLINE    552134

8 /u01/app/oracle/oradata/ora10g/zlm_test01.dbf ONLINE   552134

--查看数据文件头的检查点SCN

SQL> select file#,name,status,checkpoint_change# from
v$datafile_header order by 1;

FILE# NAME STATUS  CHECKPOINT_CHANGE#

---------- --------------------------------------------- ------- ------------------

1 /u01/app/oracle/oradata/ora10g/system01.dbfONLINE    552134

2 /u01/app/oracle/oradata/ora10g/undotbs01.dbf  ONLINE    552134

3 /u01/app/oracle/oradata/ora10g/sysaux01.dbfONLINE    552134

4 /u01/app/oracle/oradata/ora10g/users01.dbfONLINE    552134

5 /u01/app/oracle/oradata/ora10g/example01.dbf  ONLINE    552134

6 /u01/app/oracle/oradata/ora10g/zlm01.dbfONLINE    552134

7 /u01/app/oracle/oradata/ora10g/zlm02.dbfONLINE    552134

8 /u01/app/oracle/oradata/ora10g/zlm_test01.dbf ONLINE   552134

执行了检查点以后,脏数据刷到磁盘数据文件,数据库全部数据文件的检查点SCN都会保持一致

--当前日志情况

SQL> select * from v$Log;

GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS   FIRST_CHANGE# FIRST_TIME

---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ----------

1    1      7   52428800    1 YES INACTIVE  551038 05-9? -14

2    1      8   52428800    1NO  CURRENT 
551097 05-9? -14

3    1      6   52428800    1 YES INACTIVE  550653 05-9? -14

--把8号数据文件OFFLINE

SQL> alter database datafile 8 offline;  
--只有归档模式可以用

alter database datafile 8 offline

*

ERROR at line 1:

ORA-01145: offline immediate disallowed unless media recovery enabled

SQL> alter database datafile 8 offline drop;  --非归档要用offline drop,注意,不是真正的删除物理数据文件

Database altered.

SQL> alter database datafile 8 online;   --offline drop以后,需要recover以后才能online

alter database datafile 8 online

*

ERROR at line 1:

ORA-01113: file 8 needs media recovery

ORA-01110: data file 8: ‘/u01/app/oracle/oradata/ora10g/zlm_test01.dbf‘

SQL> recover datafile 8

Media recovery complete.

SQL> alter database datafile 8 online;

Database altered.

由于此时在线日志并没有被覆盖,可以进行recover操作,然后对8号数据文件进行online

二、在线日志被覆盖的场景

--把8号数据文件重新OFFLINE

SQL> alter database datafile 8 offline drop;

Database altered.

--查看在线日志当前状态

SQL> select * from v$log;

GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS   FIRST_CHANGE# FIRST_TIME

---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ----------

1    1      7   52428800    1 YES INACTIVE  551038 05-9? -14

2    1      8   52428800    1NO  CURRENT 551097
05-9? -14

3    1      6   52428800    1 YES INACTIVE  550653 05-9? -14

--切换3次日志,把当前日志内容覆盖

SQL> alter system switch logfile;

System altered.

SQL> select * from v$log;

GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS   FIRST_CHANGE# FIRST_TIME

---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ----------

1    1      7   52428800    1 YES INACTIVE  551038 05-9? -14

2    1      8   52428800    1 NO  ACTIVE 551097
05-9? -14

3    1      9   52428800    1NO  CURRENT 
552891 05-9? -14

SQL> alter system switch logfile;

System altered.

SQL> select * from v$log;

GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS   FIRST_CHANGE# FIRST_TIME

---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ----------

1    1     10   52428800    1NO  CURRENT 
552899 05-9? -14

2    1      8   52428800    1 NO  ACTIVE 551097
05-9? -14

3    1      9   52428800    1 NO  ACTIVE  552891 05-9? -14

SQL> alter system switch logfile;

System altered.

SQL> select * from v$log;

GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS   FIRST_CHANGE# FIRST_TIME

---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ----------

1    1     10   52428800    1 NO  ACTIVE  552899 05-9? -14

2    1     11   52428800    1NO  CURRENT  552911
05-9? -14

3    1      9   52428800    1 NO  ACTIVE  552891 05-9? -14

当前日志的检查点SCN从551097变为552911,也就是说,第3次切换日志以后,current日志被覆盖了

--对8号数据文件online

SQL> alter database datafile 8 online;

alter database datafile 8 online

*

ERROR at line 1:

ORA-01113: file 8 needs media recovery

ORA-01110: data file 8: ‘/u01/app/oracle/oradata/ora10g/zlm_test01.dbf‘

可以看到,同样是需要media recovery的,从以下视图可以获得同样地结果:

SQL> select file#,online_status from v$recover_file;

FILE# ONLINE_

---------- -------

8 OFFLINE

SQL> recover datafile 8

ORA-00279: change 552554 generated at 09/05/2014 12:16:56 needed for thread 1

ORA-00289: suggestion : /u01/app/oracle/flash_recovery_area/ORA10G/archivelog/2014_09_05/o1_mf_1_8_%u_.arc

ORA-00280: change 552554 for thread 1 is in sequence #8

Specify log: {<RET>=suggested | filename | AUTO | CANCEL}

auto

ORA-00308: cannot open archived log ‘/u01/app/oracle/flash_recovery_area/ORA10G/archivelog/2014_09_05/o1_mf_1_8_%u_.arc‘

ORA-27037: unable to obtain file status

Linux Error: 2: No such file or directory

Additional information: 3

ORA-00308: cannot open archived log ‘/u01/app/oracle/flash_recovery_area/ORA10G/archivelog/2014_09_05/o1_mf_1_8_%u_.arc‘

ORA-27037: unable to obtain file status

Linux Error: 2: No such file or directory

Additional information: 3

SQL>

自动recover失败,原因是在线日志已经被覆盖了,而且目前是非归档模式,也没有可用的归档日志进行recover,

这个时候,数据库自身无法重新让该文件再online了,必须借助一个特殊工具——BBED(Block Browse Editor)

BBED是Oracle仅供内部使用的一个数据块浏览编辑工具,通过命令行方式,对数据块所在磁盘文件的十六进制物理地址进行修改,主要用来处理一些特殊恢复的场景(无备份恢复方式)。

BBED在10g数据库软件中是自带的,但是需要对其进行编译安装,需要用到3个包,分别是sbbdpt.o、ssbbded.o、bbedus.msb,其中sbbdpt.o、ssbbded.o位于?/rdbms/lib下,而bbedus.msb位于?/rdbms/mesg下。据说由于在DBLINK场景中使用BBED修改数据块的SCN,会引起SCN
headroom,因此在11g中,默认没有放入这几个文件(Oracle也许并不愿意让客户使用BBED ),因此如果11g中要使用BBED,需要去10g数据库中手工拷贝这3个文件到相应位置,然后再编译安装,要注意的是,BBED的32bit和64bit文件不能互用。似乎只能用于Unix/Linux系统中。

--检查BBED所需的3个文件sbbdpt.o、ssbbded.o、bbedus.msb是否存在

SQL> !

[[email protected] ~]$ cd $ORACLE_HOME/rdbms/lib

[[email protected] lib]$ ll

...

-rwxr-xr-x 1 oracle oinstall    3043 Jun 28  2005 sbbdpt.o

-rwxr-xr-x 1 oracle oinstall    2721 Jun 28  2005 ssbbded.o

...

[[email protected] lib]$ cd $ORACLE_HOME/rdbms/mesg/

[[email protected] mesg]$ ll

-rwxr-xr-x 1 oracle oinstall    8704 Jun 28  2005 bbedus.msb

...

--编译安装BBED

[[email protected] mesg]$ make -f $ORACLE_HOME/rdbms/lib/ins_rdbms.mk BBED=$ORACLE_HOME/bin/bbed $ORACLE_HOME/bin/bbed

Linking BBED utility (bbed)

rm -f /u01/app/oracle/product/10.2.0/db_1/bin/bbed

gcc -o /u01/app/oracle/product/10.2.0/db_1/bin/bbed -L/u01/app/oracle/product/10.2.0/db_1/rdbms/lib/ -L/u01/app/oracle/product/10.2.0/db_1/lib/ -L/u01/app/oracle/product/10.2.0/db_1/lib/stubs/ -L/usr/lib -lirc  /u01/app/oracle/product/10.2.0/db_1/lib/s0main.o
/u01/app/oracle/product/10.2.0/db_1/rdbms/lib/ssbbded.o /u01/app/oracle/product/10.2.0/db_1/rdbms/lib/sbbdpt.o `cat /u01/app/oracle/product/10.2.0/db_1/lib/ldflags`    -lnsslb10 -lncrypt10 -lnsgr10 -lnzjs10 -ln10 -lnnz10 -lnl10 /u01/app/oracle/product/10.2.0/db_1/rdbms/lib/defopt.o
-ldbtools10 -lclntsh  `cat /u01/app/oracle/product/10.2.0/db_1/lib/ldflags`    -lnsslb10 -lncrypt10 -lnsgr10 -lnzjs10 -ln10 -lnnz10 -lnl10 -lnro10 `cat /u01/app/oracle/product/10.2.0/db_1/lib/ldflags`    -lnsslb10 -lncrypt10 -lnsgr10 -lnzjs10 -ln10 -lnnz10
-lnl10 -lclient10 -lnnetd10  -lvsn10 -lcommon10 -lgeneric10 -lmm -lsnls10 -lnls10  -lcore10 -lsnls10 -lnls10 -lcore10 -lsnls10 -lnls10 -lxml10 -lcore10 -lunls10 -lsnls10 -lnls10 -lcore10 -lnls10 `cat /u01/app/oracle/product/10.2.0/db_1/lib/ldflags`    -lnsslb10
-lncrypt10 -lnsgr10 -lnzjs10 -ln10 -lnnz10 -lnl10 -lnro10 `cat /u01/app/oracle/product/10.2.0/db_1/lib/ldflags`    -lnsslb10 -lncrypt10 -lnsgr10 -lnzjs10 -ln10 -lnnz10 -lnl10 -lclient10 -lnnetd10  -lvsn10 -lcommon10 -lgeneric10   -lsnls10 -lnls10  -lcore10
-lsnls10 -lnls10 -lcore10 -lsnls10 -lnls10 -lxml10 -lcore10 -lunls10 -lsnls10 -lnls10 -lcore10 -lnls10 -lclient10 -lnnetd10  -lvsn10 -lcommon10 -lgeneric10 -lsnls10 -lnls10  -lcore10 -lsnls10 -lnls10 -lcore10 -lsnls10 -lnls10 -lxml10 -lcore10 -lunls10 -lsnls10
-lnls10 -lcore10 -lnls10   `cat /u01/app/oracle/product/10.2.0/db_1/lib/sysliblist` -Wl,-rpath,/u01/app/oracle/product/10.2.0/db_1/lib -lm    `cat /u01/app/oracle/product/10.2.0/db_1/lib/sysliblist` -ldl -lm   -L/u01/app/oracle/product/10.2.0/db_1/lib

--首先用下面的SQL语句获得数据文件列表

SQL> select file#||‘ ‘||name||‘ ‘||bytes from v$datafile ;

FILE#||‘‘||NAME||‘‘||BYTES

--------------------------------------------------------------------------------

1 /u01/app/oracle/oradata/ora10g/system01.dbf 524288000

2 /u01/app/oracle/oradata/ora10g/undotbs01.dbf 31457280

3 /u01/app/oracle/oradata/ora10g/sysaux01.dbf 251658240

4 /u01/app/oracle/oradata/ora10g/users01.dbf 104857600

5 /u01/app/oracle/oradata/ora10g/example01.dbf 104857600

6 /u01/app/oracle/oradata/ora10g/zlm01.dbf 104857600

7 /u01/app/oracle/oradata/ora10g/zlm02.dbf 104857600

8 /u01/app/oracle/oradata/ora10g/zlm_test01.dbf 52428800

--创建LISTFILE

SQL> !

[[email protected] ~]$ touch bbedlistfile.log  
--扩展名任意,能被parfile识别到就可以

[[email protected] ~]$ cat >> bbedlistfile.log << EOF

> 1 /u01/app/oracle/oradata/ora10g/system01.dbf 524288000

> 2 /u01/app/oracle/oradata/ora10g/undotbs01.dbf 31457280

> 3 /u01/app/oracle/oradata/ora10g/sysaux01.dbf 251658240

> 4 /u01/app/oracle/oradata/ora10g/users01.dbf 104857600

> 5 /u01/app/oracle/oradata/ora10g/example01.dbf 104857600

> 6 /u01/app/oracle/oradata/ora10g/zlm01.dbf 104857600

> 7 /u01/app/oracle/oradata/ora10g/zlm02.dbf 104857600

> 8 /u01/app/oracle/oradata/ora10g/zlm_test01.dbf 52428800

> EOF

--创建PARFILE

[[email protected] ~]$ touch parfile.bbd   --注意扩展名为bbd,否则识别不了

[[email protected] ~]$ cat >> parfile.bbd << EOF

> blocksize=8192

> listfile=bbedlistfile.log

> mode=edit

> EOF

--查看装载到BBED中的文件信息

BBED> info

File#  Name                                                        Size(blks)

-----  ----                                                        ----------

1  /u01/app/oracle/oradata/ora10g/system01.dbf                      64000

2  /u01/app/oracle/oradata/ora10g/undotbs01.dbf                      3840

3  /u01/app/oracle/oradata/ora10g/sysaux01.dbf                      30720

4  /u01/app/oracle/oradata/ora10g/users01.dbf                       12800

5  /u01/app/oracle/oradata/ora10g/example01.dbf                     12800

6  /u01/app/oracle/oradata/ora10g/zlm01.dbf                         12800

7  /u01/app/oracle/oradata/ora10g/zlm02.dbf                         12800

8  /u01/app/oracle/oradata/ora10g/zlm_test01.dbf                     6400

--进入BBED命令行模式(默认密码:blockedit)

[[email protected] ~]$ bbed parfile=parfile.bbd

Password:

BBED: Release 2.0.0.0.0 - Limited Production on Fri Sep 5 13:09:55 2014

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

************* !!! For Oracle Internal Use only !!! ***************

BBED>

注意:这里使用了指定了参数文件和文件列表方式登陆BBED,否则,所有参数都需要在BBED的CML界面中输入

如果数据库做过resetlogs,那么需要关注以下两项:

kcvfhrls

kcvfhrlc

由于这里并没有用resetlogs打开数据库,所以只需关注以下几项值:

kscnbas

kcvcptim

kcvfhcpc

kcvfhccc

--查看datafile 8的信息

BBED> set file 8

FILE#          8

BBED> p kcvfhckp

struct kcvfhckp, 36 bytes                   @484

struct kcvcpscn, 8 bytes                 @484

ub4 kscnbas                           @484      0x00086e6a   --数据文件头的SCN

ub2 kscnwrp                           @488      0x0000

ub4 kcvcptim                             @492      0x331c12b8

ub2 kcvcpthr                             @496      0x0001

union u, 12 bytes                        @500

struct kcvcprba, 12 bytes             @500

ub4 kcrbaseq                       @500      0x00000008   --数据文件当前写的redolog sequence

ub4 kcrbabno                       @504      0x00000ab9   --数据文件当前写的redolog block number

ub2 kcrbabof                       @508      0x0010

ub1 kcvcpetb[0]                          @512      0x02

ub1 kcvcpetb[1]                          @513      0x00

ub1 kcvcpetb[2]                          @514      0x00

ub1 kcvcpetb[3]                          @515      0x00

ub1 kcvcpetb[4]                          @516      0x00

ub1 kcvcpetb[5]                          @517      0x00

ub1 kcvcpetb[6]                          @518      0x00

ub1 kcvcpetb[7]                          @519      0x00

BBED> p kcvfhcpc

ub4 kcvfhcpc                                @140      0x00000005

BBED> p kcvfhccc

ub4 kcvfhccc                                @148      0x00000004

--和datafile 7做比较

BBED> set file 7

FILE#          7

BBED> p kcvfhckp

struct kcvfhckp, 36 bytes                   @484

struct kcvcpscn, 8 bytes                 @484

ub4 kscnbas                           @484      0x00086fcf

ub2 kscnwrp                           @488      0x0000

ub4 kcvcptim                             @492      0x331c159d

ub2 kcvcpthr                             @496      0x0001

union u, 12 bytes                        @500

struct kcvcprba, 12 bytes             @500

ub4 kcrbaseq                       @500      0x0000000b

ub4 kcrbabno                       @504      0x00000002

ub2 kcrbabof                       @508      0x0010

ub1 kcvcpetb[0]                          @512      0x02

ub1 kcvcpetb[1]                          @513      0x00

ub1 kcvcpetb[2]                          @514      0x00

ub1 kcvcpetb[3]                          @515      0x00

ub1 kcvcpetb[4]                          @516      0x00

ub1 kcvcpetb[5]                          @517      0x00

ub1 kcvcpetb[6]                          @518      0x00

ub1 kcvcpetb[7]                          @519      0x00

BBED> p kcvfhcpc

ub4 kcvfhcpc                                @140      0x0000001b

BBED> p kcvfhccc

ub4 kcvfhccc                                @148      0x0000001a

其实这里kcvfhcpc和kcvfhccc可以不必理会,要修改的就2个地方

只需要把datafile 8中offset 484和500的值改成和datafile 7一致,就ok了

--用dump命令查看datafile 7的存储值

BBED> dump /v offset 484 count 16

File: /u01/app/oracle/oradata/ora10g/zlm02.dbf (7)

Block: 1       Offsets:  484 to  499  Dba:0x01c00001

-------------------------------------------------------

cf6f0800 0000f1b7 9d151c33 01000000 l ?....穹...3....

<16 bytes per line>

注意,这里存储的格式与之前通过p kcvfhckp查看到的值是相反的

--通过以下视图可以获得endian值:

SQL> set lin 130

SQL> col platform_name for a40

SQL> select platform_id,platform_name,endian_format from v$db_transportable_platform;

PLATFORM_ID PLATFORM_NAME     ENDIAN_FORMAT

----------- ---------------------------------------- --------------

7 Microsoft Windows IA (32-bit)    Little

10 Linux IA (32-bit)    Little

5 HP Tru64 UNIX    Little

11 Linux IA (64-bit)    Little

15 HP Open VMS
    Little

8 Microsoft Windows IA (64-bit)    Little

13 Linux 64-bit for AMD    Little

12 Microsoft Windows 64-bit for AMD    Little

17 Solaris Operating System (x86)    Little

Big-Endian和Little-Endian的定义如下:

a) Little-Endian 低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。

b) Big-Endian 高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。

BBED> dump /v offset 500 count 16

File: /u01/app/oracle/oradata/ora10g/zlm02.dbf (7)

Block: 1       Offsets:  500 to  515  Dba:0x01c00001

-------------------------------------------------------

0b000000 02000000 1000e1bf 02000000 l ..........峥....

<16 bytes per line>

BBED> modify /x cf6f0800 dba 8,1 offset 484

BBED-00209: invalid number (cf6f0800)

要修改的值为8位4字节十六进制,一起写会提示非法值,可以先修改前3个字节

BBED> modify /x cf6f08 dba 8,1 offset 484

Warning: contents of previous BIFILE will be lost. Proceed? (Y/N)
y

File: /u01/app/oracle/oradata/ora10g/zlm_test01.dbf (8)

Block: 1                Offsets:  484 to  499           Dba:0x02000001

------------------------------------------------------------------------

cf6f0800 00000000 b8121c33 01000000

<32 bytes per line>

--再次验证一下

BBED> d /v dba 8,1 offset 484 count 16    --d就是dump,m就是modify,BBED的命令可以用首字母缩写

File: /u01/app/oracle/oradata/ora10g/zlm_test01.dbf (8)

Block: 1       Offsets:  484 to  499  Dba:0x02000001

-------------------------------------------------------

cf6f0800 00000000 b8121c33 01000000 l ?......?.3....

<16 bytes per line>

BBED> set file 7 block 1   --注意,这里必须再次指定一下file和block,刚才修改完以后默认file是8号

FILE#          7

BLOCK#        
1

BBED> d /v offset 500 count 16

File: /u01/app/oracle/oradata/ora10g/zlm02.dbf (7)

Block: 1       Offsets:  500 to  515  Dba:0x01c00001

-------------------------------------------------------

0b000000 02000000 1000e1bf 02000000 l ..........峥....

<16 bytes per line>

BBED> m /x 0b dba 8,1 offset 500

File: /u01/app/oracle/oradata/ora10g/zlm_test01.dbf (8)

Block: 1                Offsets:  500 to  515           Dba:0x02000001

------------------------------------------------------------------------

0b000000 b90a0000 1000bf0e 02000000

<32 bytes per line>

BBED> sum

Check value for File 8, Block 1:

current = 0xf66e, required = 0xf7c8

BBED> sum apply   -执行该命令才算是真正的修改完成

Check value for File 8, Block 1:

current = 0xf7c8, required = 0xf7c8

BBED> exit

[[email protected] ~]$ sqlplus / as sysdba

SQL*Plus: Release 10.2.0.1.0 - Production on Fri Sep 5 13:49:58 2014

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

Connected to:

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production

With the Partitioning, OLAP and Data Mining options

SQL> select file#,checkpoint_change#,last_change# from
v$datafile;

FILE# CHECKPOINT_CHANGE# LAST_CHANGE#

---------- ------------------ ------------

1       552911

2       552911

3       552911

4       552911

5       552911

6       552911

7       552911

8
      552554   552828

SQL> select file#,checkpoint_change#,resetlogs_change# from
v$datafile_header;

FILE# CHECKPOINT_CHANGE# RESETLOGS_CHANGE#

---------- ------------------ -----------------

1       552911547304

2       552911547304

3       552911547304

4       552911547304

5       552911547304

6       552911547304

7       552911547304

8
      552911547304

虽然8号数据文件的checkpoint_change#,last_change#与其他文件还是不一致的,但是它的数据文件头中的信息已经一致了,也就是我们刚才改的内容

--recover数据文件并使其online

SQL> recover datafile 8

Media recovery complete.

QL> alter database datafile 8 online;

Database altered.

--再次查看

SQL> select file#,checkpoint_change#,last_change# from v$datafile;

FILE# CHECKPOINT_CHANGE# LAST_CHANGE#

---------- ------------------ ------------

1       552911

2       552911

3       552911

4       552911

5       552911

6       552911

7       552911

8
      555977

SQL> select file#,checkpoint_change#,resetlogs_change# from v$datafile_header;

FILE# CHECKPOINT_CHANGE# RESETLOGS_CHANGE#

---------- ------------------ -----------------

1       552911  547304

2       552911  547304

3       552911  547304

4       552911  547304

5       552911  547304

6       552911  547304

7       552911  547304

8
      555977  547304

SQL> select * from zlm1.offline_test;

ID NAME

---------- ----------

1 aaron8219

此时可以看到,虽然8号数据文件的checkpoint_change#仍然是不一致的,但是已经比其他文件newer了,说明是当前更改的文件,其实之前不能直接online,就是因为8号数据文件的checkpoint_change#=552554要比其他文件的checkpoint_change#552911要older所致。online的时候,控制文件中记录的信息过旧(因为之前文件是offline的,它的checkpoint信息自那一刻开始就不会再变化),需要用recover把它推送到其他文件的checkpoint之后的值(即比它们都要biger
or newer)。经过recover以后,我们获得了8号文件新的checkpoint_change#=555977>552911,因此才能够重新将它online,即通过BBED,手工修改数据文件头中的checkpoint SCN,使其能够不依赖于online redo logfile和archive logfile,就能实现recover操作。

SQL> alter system checkpoint;

System altered.

SQL> select file#,checkpoint_change#,last_change# from v$datafile;

FILE# CHECKPOINT_CHANGE# LAST_CHANGE#

---------- ------------------ ------------

1       556048

2       556048

3       556048

4       556048

5       556048

6       556048

7       556048

8
      556048

8 rows selected.

SQL> select file#,checkpoint_change#,resetlogs_change# from v$datafile_header;

FILE# CHECKPOINT_CHANGE# RESETLOGS_CHANGE#

---------- ------------------ -----------------

1       556048  547304

2       556048  547304

3       556048  547304

4       556048  547304

5       556048  547304

6       556048  547304

7       556048  547304

8
      556048  547304

8 rows selected.

SQL>

当我们再次手工执行检查点以后,就会触发DBWR进程把DB BUFFER CACHE中的脏数据写到磁盘文件,此时8号数据文件和数据文件头中的checkpoint SCN信息,已经与其他数据文件都一致了。至此,整个恢复过程顺利结束。

总结

本例是通过Oracle BBED工具,在非归档模式下对OFFLINE数据文件进行恢复的过程。注意,由于current日志非常重要,它仅保留在内存中(SGA的db buffer cache),所以一般重要的系统,都是需要开启归档的,这样可以保证current日志被覆盖后依然可以对数据文件进行前滚(recover)。当我们既没有current日志,又没有归档日志,那就只能通过特殊手段来进行恢复了。如果OFFLINE的数据文件中有比较重要的数据内容,就能够使其重新ONLINE并取出数据了。当然,BBED还有更多比较复杂的运用,如当某个数据文件块出现损坏,又没有可以用的备份时,通过BBED,可以对数据文件块直接dump并替换内容等,这里就暂且不讨论了,大家可以自己参考手册进行研究。总得来说,BBED还是比较inernal的东东,想要掌握周全,实属不易。

时间: 2024-10-04 20:34:51

利用 BBED 恢复非归档模式下 OFFLINE 数据文件的相关文章

测试Oracle 11gr2 RAC 非归档模式下,offline drop数据文件后的数据库的停止与启动测试全过程

测试Oracle 11gr2 RAC 非归档模式下,offline drop数据文件后的数据库的停止与启动测试全过程 最近系统出现问题,由于数据库产生的日志量太大无法开启归档模式,导致offline的数据文件无法online! 数据库在启动的时候不检查offline的数据文件! 下面进行测试 数据库版本 SQL> select * from v$version; BANNER ------------------------------------------------------------

oracle非归档模式下的冷备份和恢复

查看归档的相关信息 SQL> archive log list数据库日志模式             非存档模式自动存档             禁用存档终点            USE_DB_RECOVERY_FILE_DEST最早的联机日志序列     72当前日志序列           74 备份中常用的术语解释: 冷备份(脱机备份): 数据库处于关闭状态下所做的物理拷贝.数据库处于非归档模式下只能使用这种方法备份. 数据库全备份:备份所有数据文件和控制文件,在全备份时,数据库可以处在

在非归档模式下不能更改表空间为备份模式

Oracle表空间设置为备份模式后,便可以联机对表空间下数据文件进行文件系统级别的copy备份操作,因为期间对表空间的修改都记录到数据库的重做日志文件中. 由此想到数据库如果是非归档模式,那么这个表空间备份模式的时间必须不能超过联机日志被覆盖的时间,才能保证数据的修改不会丢失. 那么Oracle对这种情况是如何择决的呢? 实验表明:Oracle是干脆不让你在非归档模式下开启表空间的备份模式. 报错如下: ORA-01123: cannot start online backup; media r

ORACLE 非归档模式下REDO日志丢失修复

第一步:全备datafile,controlfile,spfile/pfile 第二步:恢复日志.(原冷备的日志没有用,千万不要用!) SQL> select member from v$logfile;                         /ora/app/oracle/oradata/orcl/redo03.log /ora/app/oracle/oradata/orcl/redo02.log /ora/app/oracle/oradata/orcl/redo01.log SQL

在归档模式下,恢复一个被offline drop的datafile的方法

参考自: HOW TO RECOVER OFFLINE DROPPED DATAFILE IN ARCHIVELOG MODE (文档 ID 286355.1) 如下的实验基于oracle 11.2.0.4 linux x86-64bit完成 [[email protected] u02]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.4.0 Production on Sun Feb 15 20:33:17 2015 Copyright (c) 1

归档模式下恢复没有备份的数据文件

测试环境 SQL> select * from v$version; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production PL/SQL Release 11.2.0.4.0 - Production CORE    11.

oracle非归档模式与归档模式的备份

不一致性备份:因为备份操作不可能瞬时完成,而数据文件时刻都在写,SCN时刻都在变,备份完第n个数据文件时, 第n+1个数据文件的SCN有可能已经与之前的都不同了. 不一致性的备份在恢复后必须借助归档日志文件和联机重做日志,将数据库修复到一致性的状态才能打开.因此,创 建不一致性备份除了备份数据库启动时必须的数据文件和控制文件之外,还需要备份归档日志文件. 一致性备份:备份的数据文件和控制文件拥有相同的SCN,即一致性备份.只有数据库以shutdown immediate方式关闭 .并且数据库未被

在归档模式下删除非系统文件的恢复

众所周知,我们的核心生产数据库通常都是在归档模式下执行的,更不用说还配置DG环境的了.开启归档,并保证全部归档不丢失,就能保证我们对数据库所做的不论什么改动不会丢失,归档日志可谓是恢复的根本,假设丢失归档,那么即使RMAN功能再强大,也无法对丢失的数据进行恢复.所以我们通常配置的RMAN策略就是全备+归档+控制文件自己主动备份.这里的归档不是指数据库创建以来生成的归档(那量也太大了),而是当进行RMAN非一致性备份时新产生的那部分归档日志,用来保证数据库能够前推到一致性状态,这样才干顺利open

Oracle在归档模式下恢复

=============== 数据库的完全恢复 =============== 在归档模式下数据库完全恢复时,数据库所经过的状态如下: 1.利用备份修复(Restores)损坏或丢失的数据文件,即将备份的文件复制到数据库中原来的位置 2. 将从备份到系统崩溃这段时间所提交的数据由归档日志文件和重做日志文件中还原成数据文件所需要的数据块,这也叫前滚(Roll Forward) 3. 此时数据块中包含了所有提交的数据,也可能包含没提交的数据 4. 系统利用还原数据块回滚未提交的数据,这也叫回滚或者