本想将这种情况下的恢复步骤永远藏在心中的, 因为它在实际生活中太难以恢复了. 看到有人真的遇到了这种情况, 我还是将恢复的步骤写一下吧. 先来创建一个表空间及带BLOB字段表.
SQL> CREATE TABLESPACE LOBDATA
2 DATAFILE 'C:\oracle\oradata\db10g\lobdata01.dbf' size 24m
3 extent management local uniform size 128K
4 segment space management manual;
Tablespace created.
SQL> CREATE TABLE T_LOB (COL1 NUMBER, COL2 BLOB) TABLESPACE LOBDATA;
Table created.
接下来插入几条记录, 并提交, 再进行Checkpoint和Drop表的操作. 然后我们拷出这个表空间的文件进行恢复. 先来看一下这个表空间中有什么Segment.
AUL> scan header
2008-02-21 19:39:16
RDBA=0x02000009(8/9),type=0x10,fmt=0xa2,seq=0x01,flag=0x04
seg/obj=0x00002ef0=12016
RDBA=0x02000029(8/41),type=0x10,fmt=0xa2,seq=0x01,flag=0x04
seg/obj=0x00002ef2=12018
2008-02-21 19:39:16
AUL>
在这里可以找到两个, 一个是表的, 一个是LOB索引的, 无法区分? 那就扫描一下数据好了.
AUL> scan data
2008-02-21 19:40:03
RDBA=0x0200000a(8/10),type=0x06,fmt=0xa2,seq=0x01,flag=0x06
seg/obj=0x00002ef0=12016,csc=0x0000.001b627f,itc=2,typ=1 - DATA
tab#= 0 nrow= 4 offs= 0
RDBA=0x0200002a(8/42),type=0x06,fmt=0xa2,seq=0x01,flag=0x06
seg/obj=0x00002ef2=12018,csc=0x0000.001b627b,itc=2,typ=2 - INDEX
2008-02-21 19:40:03
AUL>
可以发现, 12016是表的数据段编号, 12018则是LOB索引段编号, 其实还有一个LOB段编号12017, 只是AUL扫描时忽略了而已. 如果直接进行UNLOAD则LOB字段最多只能得到大约12个块的大小的值, 这是因为Oracle只能行内存放12个LOB CHUNK的地址, 超过12个CHUNK的, 就要用到LOB索引中的信息了, 如果LOB索引坏掉了, 那么LOB数据就无法准确恢复了.
AUL> SET LOB_STORAGE 1
Current LOB_STORAGE is : 1-FILE
AUL> UNLOAD OBJECT 12016 COLUMN NUMBER BLOB TO TEST.TXT;
2008-02-21 19:44:32
2008-02-21 19:44:32
在UNLOAD命令中无法为字段指定LOB索引的信息, 因此没有SYSTEM是不能恢复LOB数据的, 但是我们可以借SYSTEM信息, 只要将借来的信息改改就行了.
AUL> desc scott.t_lobnew
Storage(OBJ#=12026 OBJD=12026 TS=4 FILE=4 BLOCK=3915 CLUSTER=0)
No. SEQ INT Column Name Type
--- --- --- ------------- ----------------
1 1 1 COL1 NUMBER
2 2 2 COL2 BLOB (SYS_IL0000012026C00002$$)
要从AULOBJ文件中分别取得表和LOB索引的对象编号.
C:\MYDUL>grep T_LOBNEW AULOBJ.TXT
12026,30,T_LOBNEW,,2,
C:\MYDUL>grep SYS_IL0000012026C00002 AULOBJ.TXT
12028,30,SYS_IL0000012026C00002$$,,1,
再从AULTAB文件中取得表和LOB索引的存贮位置信息.
C:\MYDUL>grep 12026 AULTAB.TXT
12026,12026,4,4,3915,,
C:\MYDUL>grep 12028 AULTAB.TXT
12028,12028,4,4,3931,
要改掉第2(数据段编号),4(Segment Header File),5(Segment Header Block)三个个字段的值.
12026,12016,4,8,9,,
12028,12018,4,8,41,
接下来进行数据恢复就没有问题了, 可以恢复全部的LOB数据了.
AUL> UNLOAD TABLE SCOTT.T_LOBNEW TO TEST.TXT;
2008-02-21 19:58:58
Unload OBJD=12026 FILE=8 BLOCK=9 CLUSTER=0 ...
2008-02-21 19:58:59
可以想象, 如果表空间中的表很多, 将很难确定LOB索引段的段编号, 因此恢复难度很大. 如果还有DROP时的日志可以分析的话, 则要容易一些.
留言 (1)
现在已经可以在命令行上指定LOB索引段的地址参数了, 格式
LOB col.file.block
运行如下unload命令,也可以工作了.
UNLOAD OBJECT 12016 COLUMN NUMBER BLOB LOB 2.8.41 TO TEST.TXT;
Posted by anysql | Feb 22, 2008 10:35 AM