是用bbed工具模拟对块的破坏,并使用rman bock recover进行块恢复

第一部分 .       概述

一、        实验环境

运行环境:

[root@localhost ~]# lsb_release -a

LSB Version:    :core-3.1-ia32:core-3.1-noarch:graphics-3.1-ia32:graphics-3.1-noarch

Distributor ID: RedHatEnterpriseServer

Description:    Red Hat Enterprise Linux Server release 5.4 (Tikanga)

Release:        5.4

Codename:       Tikanga

数据库版本:

SQL> select * from v$version;

 

BANNER

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

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod

PL/SQL Release 10.2.0.1.0 - Production

CORE    10.2.0.1.0      Production

TNS for Linux: Version 10.2.0.1.0 - Production

NLSRTL Version 10.2.0.1.0 - Production

 

二、        实验目标

使用bbed工具对hr用户下的departments表所在的一个块进行破坏,然后使用RMAN block recover进行块恢复。

第二部分 .       技术概述

一、        实验步骤

1.       Linking bbed

在使用bbed工具前必须先linkbbed的代码会和oracle的数据库一起装载在unix或者linux上,但是并没有被linked

a)        编译bbed

[oracle@lzc lib]$ make -f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed

Linking BBED utility (bbed)

rm -f /u01/app/oracle/product/10.2.0.1/db_1/rdbms/lib/bbed

gcc -o /u01/app/oracle/product/10.2.0.1/db_1/rdbms/lib/bbed -L/u01/app/oracle/product/10.2.0.1/db_1/rdbms/lib/ -L/u01/app/oracle/product/10.2.0.1/db_1/lib/ -L/u01/app/oracle/product/10.2.0.1/db_1/lib/stubs/ -L/usr/lib -lirc  /u01/app/oracle/product/10.2.0.1/db_1/lib/s0main.o /u01/app/oracle/product/10.2.0.1/db_1/rdbms/lib/ssbbded.o /u01/app/oracle/product/10.2.0.1/db_1/rdbms/lib/sbbdpt.o `cat /u-ldl

。。。(省略部分)

 -lm   -L/u01/app/oracle/product/10.2.0.1/db_1/lib

查看一下是否成功编译

[oracle@lzc lib]$ ll bbed

-rwxr-xr-x 1 oracle oinstall 536161 Aug 31 09:50 bbed

可以看到成功编译!

b)        设置环境变量

为了使用方便,在任何目录下都能够随意调用bbed的命令,我们可以把bbed所在的目录/u01/app/oracle/product/10.2.0.1/db_1/rdbms/lib添加到path环境变量下,或者做一个软连接。

这里我选择第一种。

至于如何添加修改PATH环境变量,就不用多说了。在/home/oracle目录下修改.bash_profile文件即可。

2.       Starting bbed

a)        创建listfile文件filelinux.log

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

FILE#||''||NAME||''||BYTES

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

1 /u01/app/oracle/oradata/dblzc/system01.dbf 513802240

2 /u01/app/oracle/oradata/dblzc/undotbs01.dbf 83886080

3 /u01/app/oracle/oradata/dblzc/sysaux01.dbf 293601280

4 /u01/app/oracle/oradata/dblzc/users01.dbf 15728640

5 /u01/app/oracle/oradata/dblzc/soe.dbf 3436183552

b)        创建parfile文件bbed.par

blocksize=8192           //该参数为数据库的default block size

listfile=/home/oracle/bbed_test/filelinux.log  //上面创建的listfile文件

mode=edit    //进入bbed的模式,有browseedit两个参数。在browse模式下只能浏览,不能进行修改。

c)         查看要修改的数据库块的信息

  1* select file_id,owner,segment_name,block_id from dba_extents where segment_name='DEPARTMENTS' and WNER='HR'

   FILE_ID OWNER SEGMENT_NAME           BLOCK_ID

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

         4 HR    DEPARTMENTS                 121

这里的的block_id指的是这个块所在区的第一个块的block_id

d)        查看表中记录的信息

SQL> select * from departments;

DEPARTMENT_ID DEPARTMENT_NAME                MANAGER_ID LOCATION_ID

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

           10 Administration                        200        1700

           20 Marketing                             201        1800

           50 Shipping                              124        1500

           60 IT                                    103        1400

           80 Sales                                 149        2500

           90 Executive                             100        1700

          110 Accounting                            205        1700

          190  contracting                                     1700

8 rows selected.

e)        查看每行记录对应存储的块号

SQL> select dbms_rowid.rowid_block_number(rowid) from departments;

DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)

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

                                 127

                                 127

                                 127

                                 127

                                 127

                                 127

                                 127

                                 127

8 rows selected.

这里可以看到表中每行数据所在的block_id。由于测试数据比较少,所以departments这个表中的所有数据都在127这个数据块中。

从以上的查询我们可以获得我们所要操作的块的相关信息。假设我们现在修改department表所在的块的信息。File_id=4 block_id=127

3.       进入bbed

[oracle@lzc bbed_test]$ bbed parfile=bbed.par

Password:

BBED: Release 2.0.0.0.0 - Limited Production on Fri Aug 31 11:42:16 2012

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

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

BBED>

BBED的密码是blockedit,这个密码在任何客户端上都是一样的。如果你对这个工具的oracle内部安全代码足够了解,也可以使用standard reverse-engineering技术进行修改。

可以通过下面两个命令来查看,刚在在参数文件中设置的参数

BBED> show

        FILE#           4

        BLOCK#          127

        OFFSET          7554

        DBA             0x0100007f (16777343 4,127)

        FILENAME        /u01/app/oracle/oradata/dblzc/users01.dbf

        BIFILE          bifile.bbd

        LISTFILE        /home/oracle/bbed_test/filelinux.log

        BLOCKSIZE       8192

        MODE            Edit

        EDIT            Unrecoverable

        IBASE           Dec

        OBASE           Dec

        WIDTH           80

        COUNT           512

        LOGFILE         log.bbd

        SPOOL           No

 

BBED> info

 File#  Name                                                        Size(blks)

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

     1  /u01/app/oracle/oradata/dblzc/system01.dbf                       62720

     2  /u01/app/oracle/oradata/dblzc/undotbs01.dbf                      10240

     3  /u01/app/oracle/oradata/dblzc/sysaux01.dbf                       35840

     4  /u01/app/oracle/oradata/dblzc/users01.dbf                         1920

     5  /u01/app/oracle/oradata/dblzc/soe.dbf                           419456

4.       修改块中的数据

a)        设置当前数据块

BBED> set dba 4,127

        DBA             0x0100007f (16777343 4,127)

参数dba为数据块的地址data block address

假设现在我要修改departments表中包含’Sale’字符的那一行

BBED> find /c Sale

 File: /u01/app/oracle/oradata/dblzc/users01.dbf (4)

 Block: 127              Offsets: 7554 to 8065           Dba:0x0100007f

<32 bytes per line>

通过find命令我们可以找到改行在127块中的offsets

b)        查看块中的内容

然后我们可以通过改行所在的offset查看对应存储在块中的数据

BBED> dump /v dba 4,127 offset 7554 count 5

File: /u01/app/oracle/oradata/dblzc/users01.dbf (4)

 Block: 127     Offsets: 7554 to 8065  Dba:0x0100007f

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

 53616c65 7303c202 3202c21a 2c020402 l Sales..2..,...

 Dump命令使用来显示指定的块的内容,通过offset可以更进一步查看到每一行中的内容。

通过count参数控制向屏幕输出的字节数。要根据你所要查找的字符的长度来设置。

c)         修改块中的内容

BBED> modify /c lanzaichen dba 4,127 offset 7554

 File: /u01/app/oracle/oradata/dblzc/users01.dbf (4)

 Block: 127              Offsets: 7554 to 8065           Dba:0x0100007f

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

 6c616e7a 61696368 656ec21a 2c020402 c13d0249 5403c202 0402c20f 2c020402

 c1330853 68697070 696e6703 c2021902 c2102c02 0402c115 094d6172 6b657469

 6e6703c2 030202c2 132c0204 02c10b0e 41646d69 6e697374 72617469 6f6e02c2

 0302c212 3c020403 c2025b0c 20636f6e 74726163 74696e67 ff02c212 3c020403

 c2020b0a 4163636f 756e7469 6e6703c2 030602c2 123c0204 02c15b09 45786563

部分省略。。。

再次重新查看一下块中的内容

BBED> dump /v dba 4,127 offset 7554 count 10 File: /u01/app/oracle/oradata/dblzc/users01.dbf (4)

 Block: 127     Offsets: 7554 to 8065  Dba:0x0100007f

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

 6c616e7a 61696368 656ec21a 2c020402 l lanzaichen

可以看到第一行中的数据已经被修改掉,如果此时我们不对刚才的操作执行sum命令apply修改的话。由于校验值发生了变化,在数据库中这个数据块就会报错。

然后回到数据库中重新查看表中的数据,看是否能够正常检索。

5.       诊断坏块

前面我们已经成功的修改了departments表所在的块的内容,由于没有使用sum命令apply设置。所以,被修改的块不能被正常检索。那我们如何找到这个坏块呢?

a)        通过检索数据

在检索数据时会对数据所在的数据文件进行扫描(被检索的数据不在内存中),可以检测到数据文件中的坏块。

SQL> conn / as sysdba

Connected.

SQL> alter system flush buffer_cache;

System altered.

从表中检索内容之前要先把数据库高速缓冲区(data buffer cache)中的数据清除。

SQL> conn hr/oracle

Connected.

SQL> select * from departments;

select * from departments

             *

ERROR at line 1:

ORA-01578: ORACLE data block corrupted (file # 4, block # 127)

ORA-01110: data file 4: '/u01/app/oracle/oradata/dblzc/users01.dbf'

可以看到,我们刚才修改的数据被报错。

b)        Dbverify工具

SQL> select block_size  from v$datafile where file#=4;

BLOCK_SIZE

----------

      8192

SQL> host

 [oracle@lzc ~]$ dbv file=/u01/app/oracle/oradata/dblzc/users01.dbf blocksize=8192

DBVERIFY: Release 10.2.0.1.0 - Production on Fri Aug 31 15:29:13 2012

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

DBVERIFY - Verification starting : FILE = /u01/app/oracle/oradata/dblzc/users01.dbf

Page 121 is marked corrupt

Corrupt block relative dba: 0x01000079 (file 4, block 121)

Bad header found during dbv:

Data in bad block:

 type: 67 format: 7 rdba: 0x0a545055

 last change scn: 0x0000.00149f2b seq: 0x2 flg: 0x04

 spare1: 0x52 spare2: 0x52 spare3: 0x0

 consistency value in tail: 0x9f2b2002

 check value in block header: 0xd12

 computed block checksum: 0xe449

Page 122 is marked corrupt

Corrupt block relative dba: 0x0100007a (file 4, block 122)

Bad header found during dbv:

Data in bad block:

 type: 67 format: 7 rdba: 0x0a545055

 last change scn: 0x0000.00149e97 seq: 0x2 flg: 0x04

 spare1: 0x52 spare2: 0x52 spare3: 0x0

 consistency value in tail: 0x9e972102

 check value in block header: 0x4dd4

 computed block checksum: 0xe44b

Page 127 is marked corrupt

Corrupt block relative dba: 0x0100007f (file 4, block 127)

Bad check value found during dbv:

Data in bad block:

 type: 6 format: 2 rdba: 0x0100007f

 last change scn: 0x0000.00149fa2 seq: 0x1 flg: 0x06

 spare1: 0x0 spare2: 0x0 spare3: 0x0

 consistency value in tail: 0x9fa20601

 check value in block header: 0xae4a

 computed block checksum: 0x73d9

DBVERIFY - Verification complete

Total Pages Examined         : 1920

Total Pages Processed (Data) : 347

Total Pages Failing   (Data) : 0

Total Pages Processed (Index): 134

Total Pages Failing   (Index): 0

Total Pages Processed (Other): 1130

Total Pages Processed (Seg)  : 0

Total Pages Failing   (Seg)  : 0

Total Pages Empty            : 306

Total Pages Marked Corrupt   : 3

Total Pages Influx           : 0

Highest block SCN            : 1559918 (0.1559918)

可以看到有两个坏块被检测数122127。不过121122可能是实验前就存在的坏块。详细信息看后面的实验分析,会有具体介绍。

c)         使用analyze命令

SQL> analyze table departments validate structure cascade;

analyze table departments validate structure cascade

*

ERROR at line 1:

ORA-01578: ORACLE data block corrupted (file # 4, block # 121)

ORA-01110: data file 4: '/u01/app/oracle/oradata/dblzc/users01.dbf'

更多的检查工具就不一一介绍了。下面使用rman blockrecover命令进行恢复。

6.       执行恢复

执行恢复命令

RMAN> blockrecover datafile 4 block 121;

RMAN> blockrecover datafile 4 block 122;

RMAN> blockrecover datafile 4 block 127;

再次查看一下departments表看看数据是否成功恢复

SQL> select * from departments;

 

DEPARTMENT_ID DEPARTMENT_NAME                MANAGER_ID LOCATION_ID

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

           10 Administration                        200        1700

           20 Marketing                             201        1800

           50 Shipping                              124        1500

           60 IT                                    103        1400

           80 Sales                                 149        2500

           90 Executive                             100        1700

          110 Accounting                            205        1700

          190  contracting                                     1700

 

8 rows selected.

可以看到数据被成功恢复!

二、        实验分析

1.       问题一如何判断坏块的位置

在文档中诊断坏块部分我们说道,我破坏了一个快127,在检索的时候遇到了122,和121

这两个坏块。现在我们来看看这两个坏块分别位于哪个表所在的段中

SQL> select owner,block_id,segment_name from dba_extents where tablespace_name='USERS' AND block_id=121;

OWNER   BLOCK_ID SEGMENT_NAME

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

HR           121 DEPARTMENTS

SQL> select owner,block_id,segment_name from dba_extents where tablespace_name='USERS' AND block_id=122;

no rows selected

可看到121这个坏块也属于departments这个段中。至于122为啥没找到这个,我分析了一下结果是。。。。。。嘿嘿,不知道。

你可能会问我,为什么刚才在使用select * from departments; 命令时就看到一个坏块呢,这是因为departments这个表当前的数据只占用了127 一个块,在检索数据时也就只检索了这一个块。所以没有报错。

2.       问题二在bbed工具中使用find查找命令时找不到目标字符串

   a)可能是因为数据在修改提交后的数据被保存在数据库高速缓存中没有写入数据文件

这时候可以执行一次检查点事件

Alter system checkpoint;

这种情况就不演示了

b)        offset的值低于当前current offset的值。

这种情况在这里给大家模拟一下

1)        scott用户下新建一个test测试表

SQL> desc test;

 Name                                      Null?    Type

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

 TSCN                                               CHAR(10)

 

SQL> show user;

USER is "SCOTT"

2)        向其中插入两条数据

SQL> insert into test values('&var');

Enter value for var: ab

old   1: insert into test values('&var')

new   1: insert into test values('ab')

1 row created.

 

SQL> r

  1* insert into test values('&var')

Enter value for var: cd

old   1: insert into test values('&var')

new   1: insert into test values('cd')

1 row created.

查看插入的数据

SQL> select * from test;

TSCN

----------

ab

cd

3)        查看创建的测试表的file_id,以及block_id

SQL> select file_id,block_id,bytes from dba_extents where segment_name='TEST' AND wner='HR';

 

   FILE_ID   BLOCK_ID      BYTES

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

         4         65      65536

SQL> select dbms_rowid.rowid_block_number(rowid) from test;

 

DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)

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

                                  68

                                  68

4)        使用bbed工具查看块信息

在获得我们想要的信息之后现在我们可以进入bbed查看对应块中的数据了

BBED> set dba 4,68

        DBA             0x01000044 (16777284 4,68)

设置当前操作块为68,使show命令看一下当前的参数设置是否正确

BBED> show all

        FILE#           4

        BLOCK#          68

        OFFSET          0

        DBA             0x01000044 (16777284 4,68)

        FILENAME        /u01/app/oracle/oradata/dblzc/users01.dbf

        BIFILE          bifile.bbd

        LISTFILE        /home/oracle/bbed_test/filelinux.log

        BLOCKSIZE       8192

        MODE            Edit

        EDIT            Unrecoverable

        IBASE           Dec

        OBASE           Dec

        WIDTH           80

        COUNT           512

        LOGFILE         log.bbd

        SPOOL           No

5)        查找一行数据的offset

BBED> find /c ab

 File: /u01/app/oracle/oradata/dblzc/users01.dbf (4)

 Block: 68               Offsets: 8178 to 8191           Dba:0x01000044

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

 61622020 20202020 20200406 a91b

 

 <32 bytes per line>

 

BBED> dump /v offset 8178

 File: /u01/app/oracle/oradata/dblzc/users01.dbf (4)

 Block: 68      Offsets: 8178 to 8191  Dba:0x01000044

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

 61622020 20202020 20200406 a91b     l ab        ...

 

 <16 bytes per line>

可以看到test表中第一行的值正常显示。

6)        查找第二行记录的offset

现在,我们查看第二行记录的值。

BBED> find /c cd

BBED-00212: search string not found

没有找到,怎么会没有找到呢?难道是dba地址设错了?现在我们show 命令看一下详细信息

BBED> show all

        FILE#           4

        BLOCK#          68

        OFFSET          8178

        DBA             0x01000044 (16777284 4,68)

        FILENAME        /u01/app/oracle/oradata/dblzc/users01.dbf

        BIFILE          bifile.bbd

        LISTFILE        /home/oracle/bbed_test/filelinux.log

        BLOCKSIZE       8192

        MODE            Edit

        EDIT            Unrecoverable

        IBASE           Dec

        OBASE           Dec

        WIDTH           80

        COUNT           512

        LOGFILE         log.bbd

        SPOOL           No

从上面我们可以看到dba的设置没有错误啊,再细看,看到没用红色标出的部分。没错,offsets的值发生了变化,第一次我们show 命令的时候是0而我们第二次show的时候是8178

你或许会问,既然都是在一个块上,find的查找和offset查找又有什么关系呢?

这就要关联到block的结构了。向块中存储数据时,是从下往上写入,先写入的数据在下面,后写入的值在上面。而且后写入的数据也就是在上面的数据的offset值要小于先写入的。

find命令查找数据的方式是从current offset开始向下查找。由于在我find一条记录是offset的值已经变为8178,大于第二条记录的offset。所以当我查找第二条记录时find会从offset=8178 开始先下搜索。这样自然就无法找到后加入的记录的值了。

既然了解了,就不用我多说了,只需要把offset的值设为0,就不怕找不到了。

7)        重设offset的值

BBED> set offset 0

        OFFSET          0

 

BBED> find /c cd

 File: /u01/app/oracle/oradata/dblzc/users01.dbf (4)

 Block: 68               Offsets: 8164 to 8191           Dba:0x01000044

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

 63642020 20202020 20202c01 010a6162 20202020 20202020 0406a91b

 

 <32 bytes per line>

可以看到第二条记录的offset值小于第一条记录。

再看一下从 offset81648191之间的数据

BBED> dump/v offset 8164 count 27

 File: /u01/app/oracle/oradata/dblzc/users01.dbf (4)

 Block: 68      Offsets: 8164 to 8190  Dba:0x01000044

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

 63642020 20202020 20202c01 010a6162 l cd        ,...ab

 20202020 20202020 0406a9            l         ..

 

 <16 bytes per line>

可以看到第一天插入的记录的值位于第二条插入记录的值得后面。

最终成功找到了数据!

三、        实验小结

总结一点,使用rman blockrecover 恢复块是一定要有备份的,要有归档日志。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26723566/viewspace-742657/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/26723566/viewspace-742657/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值