【转自www.dbafan.com】消失的segment

本文转自:http://www.dbafan.com/blog/?p=379

消失的segment

这是在一次恢复演习中偶然发现的一个有趣的问题。

当LMT表空间中文件被offline后,如果该文件中包含有segment header,那么从dba_extents中不能看到该segment。

来看一个测试:

SQL> select file_id from dba_data_files where tablespace_name=’TEST';

   FILE_ID
———-
10
        11

SQL> create table eagle_fan(x int) tablespace test;

Table created.

SQL> select  header_file from dba_segments where segment_name=’EAGLE_FAN’ and owner=’SYS';

HEADER_FILE
———–
10

SQL> select extent_id ,file_id from dba_extents where segment_name=’EAGLE_FAN’ and owner=’SYS';

EXTENT_ID    FILE_ID
———- ———-
0         10

SQL> select distinct segment_name from dba_extents where file_id=10;

SEGMENT_NAME
——————————————————————————–
TEST
EAGLE_FAN

SQL> alter database datafile 10 offline ;   

Database altered.

SQL> select extent_id ,file_id from dba_extents where segment_name=’EAGLE_FAN’ and owner=’SYS';

SQL> select distinct segment_name from dba_extents where file_id=10;

SEGMENT_NAME
——————————————————————————–
TEST

no rows selected

可以看到datafile 10被offline后,从dba_extents已经看不到该segment。推想而知,对于LMT tablespace,dba_extents会读取文件头信息。
那么也就是说,如果有文件被offline后,我们无法单从dba_extents中知道该文件中包含有哪些segment。

那么我们应该再从dba_segments中得到segment header在该文件中的segment:

SQL> select distinct segment_name from dba_extents where file_id=10
  2  union
  3  select distinct segment_name from dba_segments where header_file=10;

SEGMENT_NAME
——————————————————————————–
EAGLE_FAN
TEST

而DMT tablespace不存在这个问题,我们来看一看dba_extents的视图定义就很清楚了:

select ds.owner, ds.segment_name, ds.partition_name, ds.segment_type,
       ds.tablespace_name,
       e.ext#, f.file#, e.block#, e.length * ds.blocksize, e.length, e.file#
from sys.uet$ e, sys.sys_dba_segs ds, sys.file$ f
where e.segfile# = ds.relative_fno
  and e.segblock# = ds.header_block
  and e.ts# = ds.tablespace_id
  and e.ts# = f.ts#
  and e.file# = f.relfile#
  and bitand(NVL(ds.segment_flags,0), 1) = 0
  and bitand(NVL(ds.segment_flags,0), 65536) = 0
union all
select
       ds.owner, ds.segment_name, ds.partition_name, ds.segment_type,
       ds.tablespace_name,
       e.ktfbueextno, f.file#, e.ktfbuebno,
       e.ktfbueblks * ds.blocksize, e.ktfbueblks, e.ktfbuefno
from sys.sys_dba_segs ds, sys.x$ktfbue e, sys.file$ f
where e.ktfbuesegfno = ds.relative_fno
  and e.ktfbuesegbno = ds.header_block
  and e.ktfbuesegtsn = ds.tablespace_id
  and ds.tablespace_id = f.ts#
  and e.ktfbuefno = f.relfile#
  and bitand(NVL(ds.segment_flags, 0), 1) = 1
  and bitand(NVL(ds.segment_flags,0), 65536) = 0

union all以上的部分对应于DMT tablespace,下面的部分对应于LMT tablespace。

DMT tablespace从uet$中读取extent信息,所以不受offline datafile的影响。

LMT tablespace从x$ktfbue中读取extent信息,对于x$ktfbue,描述为”Used extent bitmap in file header for LMT (equivalent to uet$ in DMT)”

我们来看看datafile offline前后,该表有什么变化:

— online datafile 10,多分配几个extent给表eagle_fan,并记录下一些信息

SQL> recover datafile 10
Media recovery complete.
SQL> alter database datafile 10 online;

Database altered.

SQL> alter table eagle_fan allocate extent;

Table altered.

SQL> /

Table altered.

SQL> /

Table altered.

SQL> /

Table altered.

SQL> select extent_id,file_id,block_id from dba_extents where segment_name=’EAGLE_FAN’ order by extent_id;

EXTENT_ID    FILE_ID   BLOCK_ID
———- ———- ———-
0         10       7049
         1         11       7177
         2         10       7177
         3         11       7305
         4         10       7305

SQL> select ktfbuefno file_id,count(*) from sys.x$ktfbue where ktfbuefno in (10,11) group by ktfbuefno;

   FILE_ID   COUNT(*)
———- ———-
10         58
        11         58

SQL> create table t as select * from sys.x$ktfbue where ktfbuefno in (10,11);

Table created.

— offline后再来比较,可以发现关于Eagle_Fan表的信息丢失

SQL> alter database datafile 10 offline;

Database altered.

SQL> select ktfbuefno file_id,count(*) from sys.x$ktfbue where ktfbuefno in (10,11) group by ktfbuefno;

   FILE_ID   COUNT(*)
———- ———-
11         56
        10         55

SQL> select e.ktfbuefno,e.ktfbuesegfno,e.ktfbuesegbno,e.ktfbuesegtsn from t e where ktfbuefno in (10,11) and
  2  (ktfbuefno,ktfbuesegfno,ktfbuesegbno,ktfbuesegtsn)
  3  not in (select ktfbuefno,ktfbuesegfno,ktfbuesegbno,ktfbuesegtsn from sys.x$ktfbue where ktfbuefno in (10,11))
  4  ;

KTFBUEFNO KTFBUESEGFNO KTFBUESEGBNO KTFBUESEGTSN
———- ———— ———— ————
10           10         7052            9
        11           10         7052            9
        10           10         7052            9
        11           10         7052            9
        10           10         7052            9

  1* select header_file,header_block,segment_name from dba_segments where header_file=10 and header_block=7052
SQL> /

HEADER_FILE HEADER_BLOCK SEGMENT_NAME
———– ———— ——————————
10         7052 EAGLE_FAN

SQL> select * from dba_extents where segment_name=’EAGLE_FAN';

no rows selected

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值