oracle 10gr2 中 clob 字段原理浅析

前段时间生产库的数据文件出了点问题,导致部分数据丢失,其中包括log segment,当时想通过常规手段将丢失的log数据清除掉,但由于文件offline了,所以没办法了。
以下是通过bbed在测试库上所作的更改,目的就是想研究下log字段原理以及非常规手段清除数据的办法,该测试仅限于测试库。
在9i/10g中连接生成bbed:
cd $ ORACLE_HOME/rdbms/lib
make -f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed
以上生成的bbed可执行文件在$ORACLE_HOME/rdbms/lib目录,可以复制到其他位置或者其他同Oracle版本的机器上运行。也可通过以下命令将bbed生成到$ORACLE_HOME/bin目录
make -f ins_rdbms.mk BBED=$ORACLE_HOME/bin/bbed $ORACLE_HOME/bin/bbed
在11g中生成bbed,需要先从10g中复制如下文件到相应目录,然后再执行上述连接命令:
$ORACLE_HOME/rdbms/lib/ssbbded.o
$ORACLE_HOME/rdbms/lib/sbbdpt.o
$ORACLE_HOME/rdbms/mesg/bbedus.msb
BBED密码为blockedit

以下是测试过程:
1、创建表空间
create tablespace ts_cui datafile '/dbdata/oradata/ora10/dbsm/ts_cui_01.dbf' size 1m;
alter tablespace ts_cui add datafile '/dbdata/oradata/ora10/dbsm/ts_cui_02.dbf' size 1m;
2、建表
CREATE TABLE scott.CUI
   (  C1 NUMBER,
  C2 CLOB
   )
  TABLESPACE  users
 LOB (C2) STORE AS (
  TABLESPACE  TS_CUI enable STORAGE IN ROW  CHUNK 32768 PCTVERSION 10
  NOCACHE LOGGING
  STORAGE(INITIAL 163840 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)) ;

表建在users表空间上,log segment存储在ts_cui表空间上,使用系统建表是默认属性 enable storage in row

3\ 测试数据
然后随便插入一些数据:
 insert into cui(c1,c2) values(3,'2222222222222222222222');
 commit;
  INSERT INTO scott.cui VALUES (6,LPAD ('X',97584,'X'));
   INSERT INTO scott.cui VALUES (7,empty_clob());
commit;
需要ts_cui下的两个文件都要存储上数据,这样便于对比数据;

可以通过查看以下sql,来核实是否数据已经存在于2个文件中:
select bytes,file_id,block_id,relative_fno,segment_name,segment_type,tablespace_name
 from dba_extents t  where tablespace_name='TS_CUI';

---option-------------
造好测试数据之后,可以先将文件中的数据dump出来,以便对照修改之后的dump文件;
方法 :  alter system dump datafile 4 block xxxx;
具体dump哪块,下边有写
------------------------------------------------------------------------------------------------------------

4、删除文件
SQL>
SQL> alter database datafile '/dbdata/oradata/ora10/dbsm/ts_cui_02.dbf' offline drop;

Database altered.

5、查询数据,  select rownum,a.* from scott.cui a ; 会看到存在 value error的log列,如下
bb
上图中的第二列等于 5 的那列此时应该为 value error,这是我用bbed改过之后的效果,之前的图没存,先说明下;

6、此时就可以用bbed来修改数据了
[ora10@sdw0 dbsm]$ bbed parfile=bbed.par
Password:

BBED: Release 2.0.0.0.0 - Limited Production on Wed Jan 23 12:27:14 2013

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

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

BBED>

bbed.par 文件内容:
[root@sdw0 dbsm]# cat bbed.par
blocksize=32768
listfile=filelist.txt
mode=edit

filelist.txt 文件内容:
[root@sdw0 dbsm]# cat filelist.txt
4 /dbdata/oradata/ora10/dbsm/users01.dbf 98336768

说明:blocksize 建库块大小;98336768 users01.dbf 文件大小

BBED> info
 File#  Name                                                        Size(blks)
 -----  ----                                                        ----------
     4  /dbdata/oradata/ora10/dbsm/users01.dbf                            3001

BBED> help all
SET DBA [ dba | file#, block# ]
SET FILENAME 'filename'
SET FILE file#
SET BLOCK [+/-]block#
SET OFFSET [ [+/-]byte offset | symbol | *symbol ]
SET BLOCKSIZE bytes
SET LIST[FILE] 'filename'
SET WIDTH character_count
SET COUNT bytes_to_display
SET IBASE [ HEX | OCT | DEC ]
SET OBASE [ HEX | OCT | DEC ]
SET MODE  [ BROWSE | EDIT ]
SET SPOOL [ Y | N ]
SHOW [ | ALL ]
INFO
MAP[/v] [ DBA | FILENAME | FILE | BLOCK ]
DUMP[/v] [ DBA | FILENAME | FILE | BLOCK | OFFSET | COUNT ]
PRINT[/x|d|u|o|c] [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ]
EXAMINE[/Nuf] [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ]
:
N - a number which specifies a repeat count.
u - a letter which specifies a unit size:
  b - b1, ub1 (byte)
  h - b2, ub2 (half-word)
  w - b4, ub4(word)
  r - Oracle table/index row
f - a letter which specifies a display format:
  x - hexadecimal
  d - decimal
  u - unsigned decimal
  o - octal
  c - character (native)
  n - Oracle number
  t - Oracle date
  i - Oracle rowid
FIND[/x|d|u|o|c] numeric/character string [ TOP | CURR ]
COPY [ DBA | FILE | FILENAME | BLOCK ] TO [ DBA | FILE | FILENAME | BLOCK ]
MODIFY[/x|d|u|o|c] numeric/character string
      [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ]
ASSIGN[/x|d|u|o] =
: [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ]
: [ value | ]
SUM [ DBA | FILE | FILENAME | BLOCK ] [ APPLY ]
PUSH [ DBA | FILE | FILENAME | BLOCK | OFFSET ]
POP [ALL]
REVERT [ DBA | FILE | FILENAME | BLOCK ]
UNDO
HELP [ | ALL ]
VERIFY [ DBA | FILE | FILENAME | BLOCK ]
CORRUPT [ DBA | FILE | FILENAME | BLOCK ]

以上是bbed支持的所有命令,具体如何使用不再说明,可以百度;

7、找到损坏数据对应的block
 SELECT DBMS_ROWID.rowid_relative_fno(ROWID) FNO,DBMS_ROWID.rowid_block_number(ROWID) BLOCKID, DBMS_ROWID.rowid_row_number(ROWID) ROWNUMA   FROM scott.CUI;

8、通过bbed修改数据
修改之前的dump信息如下:
改之前:
tab 0, row 71, @0x16ea
tl: 47 fb: --H-FL-- lb: 0x0  cc: 2
col  0: [ 2]  c1 06
col  1: [40]
 00 54 00 01 02 0c 80 00 00 02 00 00 00 01 00 00 00 22 cb 0d 00 14 05 00 00
 00 00 00 1f 40 00 00 00 00 00 02 06 80 00 09


BBED> dump /v offset 5995 count 1
 File: /dbdata/oradata/ora10/dbsm/users01.dbf (4)
 Block: 2798    Offsets: 5995 to 5995  Dba:0x01000aee
-------------------------------------------------------
 05                                  l .

 <16 bytes per line>

BBED> modify /x 09 offset 5995
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
 File: /dbdata/oradata/ora10/dbsm/users01.dbf (4)
 Block: 2798             Offsets: 5995 to 5995           Dba:0x01000aee
------------------------------------------------------------------------
 09 

 <32 bytes per line>

BBED> dump /v offset 6001 count 2
 File: /dbdata/oradata/ora10/dbsm/users01.dbf (4)
 Block: 2798    Offsets: 6001 to 6002  Dba:0x01000aee
-------------------------------------------------------
 1f40                                l .@

 <16 bytes per line>

BBED> modify /x 0004 offset 6001
 File: /dbdata/oradata/ora10/dbsm/users01.dbf (4)
 Block: 2798             Offsets: 6001 to 6002           Dba:0x01000aee
------------------------------------------------------------------------
 0004 

 <32 bytes per line>

BBED> dump /v offset 6008 count 1
 File: /dbdata/oradata/ora10/dbsm/users01.dbf (4)
 Block: 2798    Offsets: 6008 to 6008  Dba:0x01000aee
-------------------------------------------------------
 02                                  l .

 <16 bytes per line>

BBED> modify /x 01 offset 6008
 File: /dbdata/oradata/ora10/dbsm/users01.dbf (4)
 Block: 2798             Offsets: 6008 to 6008           Dba:0x01000aee
------------------------------------------------------------------------
 01 

 <32 bytes per line>

BBED>

BBED> modify /x 004300 offset 6009 
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
 File: /dbdata/oradata/ora10/dbsm/users01.dbf (4)
 Block: 2798             Offsets: 6009 to 6012           Dba:0x01000aee
------------------------------------------------------------------------
 00430021 
BBED> modify /x 49 offset 6012 
 File: /dbdata/oradata/ora10/dbsm/users01.dbf (4)
 Block: 2798             Offsets: 6012 to 6012           Dba:0x01000aee
------------------------------------------------------------------------
 49 

 <32 bytes per line>

BBED> dump /v offset 6009 count 4
 File: /dbdata/oradata/ora10/dbsm/users01.dbf (4)
 Block: 2798    Offsets: 6009 to 6012  Dba:0x01000aee
-------------------------------------------------------
 00430049                            l .C.I

 <16 bytes per line>

BBED> sum apply
Check value for File 4, Block 2798:
current = 0x3779, required = 0x3779

BBED> exit

改后:
tab 0, row 71, @0x16ea
tl: 47 fb: --H-FL-- lb: 0x0  cc: 2
col  0: [ 2]  c1 06
col  1: [40]
 00 54 00 01 02 0c 80 00 00 02 00 00 00 01 00 00 00 22 cb 0d 00 14 09 00 00
 00 00 00 00 04 00 00 00 00 00 01 00 43 00 49

00 43 对应ascii C
00 49 对应ascii I

SQL> startup force
ORACLE instance started.

Total System Global Area 2147483648 bytes
Fixed Size                  2085360 bytes
Variable Size            1191185936 bytes
Database Buffers          922746880 bytes
Redo Buffers               31465472 bytes
Database mounted.
Database opened.
SQL>

9、重启数据库后,可以看到数据已经可以访问了,内容就是通过bbed修改的内容  CI
bb
下面说明一下修改的目的,对照以下图片:
bb

0054  lob head 的最大长度( Lob数据的结构,头部最大为84字节,最小为36字节)
0001 vsn
02 0c 80 00 flag
00 02    数据的单位长度为2个字节。
00 00 00 01 00 00 00 22 cb 0d   lob_id
00 14  body length
05 00 flags
00 00 00 00 chunk 数量,具体含义见下图
1f 40  lob length
00 00 00 00 00 02  version(01 表示数据在行内存放,02 表示数据存储在log段中)
其中 00 14 05 00 00 00 00 00 1f 40 00 00 00 00 00 02  也可以称为 inodeid
06 80 00 09  data/first chunk address/rdba(dba of lob chunks)
如果数据在行内存放,那么就是data内容,如果行外存放,取而代之的是rdba

06 80 00 09 转化为10机制: 109051913
   select dbms_utility.data_block_address_file(109051913) file#,dbms_utility.data_block_address_block(109051913) block# from dual;
1    26    9

可见这个log的数据存储在26文件block9上,如有兴趣可以dump出来,

以上是数据存储在行内和行外(很少数据量)的情况,以下是数据很多时的情况,见图示:

bb


bb


bb

bb


以上是大师internal里的图片,在此引用,不做具体说明了。






fj.pngQQ图片20130129׊¹0316.jpg

fj.pngQQ图片20130129ݪ#2446.jpg

fj.pngQQ图片20130129ݪ(2608.jpg

fj.png111.jpg

fj.png222.jpg

fj.png112.jpg

fj.png114.jpg

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

转载于:http://blog.itpub.net/10037372/viewspace-753525/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值