顾名思义,dba_free_space指的是Oracle还有多少表空间剩余空间,其视图结构也相当简单:

SQL> desc dba_free_space

Name                                      Null?    Type

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

TABLESPACE_NAME                                    VARCHAR2(30)

FILE_ID                                            NUMBER

BLOCK_ID                                           NUMBER

BYTES                                              NUMBER

BLOCKS                                             NUMBER

RELATIVE_FNO                                       NUMBER

但是我们查询dba_free_space时,即表空间剩余空间常常是离碎的,比如

SQL> select * from dba_free_space where file_id=7;

TABLESPACE_NAME                   FILE_ID   BLOCK_ID      BYTES     BLOCKS RELATIVE_FNO

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

ZHOUL                                   7      27145     983040        120            7

ZHOUL                                   7      27905      65536          8            7

ZHOUL                                   7      28937    7274496        888            7

ZHOUL                                   7      36617     851968        104            7

ZHOUL                                   7      60129     327680         40            7

ZHOUL                                   7      63497     720896         88            7

6 rows selected.

这是为什么呢?继续查看视图dba_free_space的创建语句:

create or replace view dba_free_space

(tablespace_name, file_id, block_id, bytes, blocks, relative_fno)

as

select ts.name, fi.file#, f.block#,

       f.length * ts.blocksize, f.length, f.file#

from sys.ts$ ts, sys.fet$ f, sys.file$ fi

where ts.ts# = f.ts#

  and f.ts# = fi.ts#

  and f.file# = fi.relfile#

  and ts.bitmapped = 0

union all

select /*+ ordered use_nl(f) use_nl(fi) */

       ts.name, fi.file#, f.ktfbfebno,

       f.ktfbfeblks * ts.blocksize, f.ktfbfeblks, f.ktfbfefno

from sys.ts$ ts, sys.x$ktfbfe f, sys.file$ fi

where ts.ts# = f.ktfbfetsn

  and f.ktfbfetsn = fi.ts#

  and f.ktfbfefno = fi.relfile#

  and ts.bitmapped <> 0 and ts.online$ in (1,4) and ts.contents$ = 0

union all

select /*+ ordered use_nl(u) use_nl(fi) */

       ts.name, fi.file#, u.ktfbuebno,

       u.ktfbueblks * ts.blocksize, u.ktfbueblks, u.ktfbuefno

from sys.recyclebin$ rb, sys.ts$ ts, sys.x$ktfbue u, sys.file$ fi

where ts.ts# = rb.ts#

  and rb.ts# = fi.ts#

  and rb.file# = fi.relfile#

  and u.ktfbuesegtsn = rb.ts#

  and u.ktfbuesegfno = rb.file#

  and u.ktfbuesegbno = rb.block#

  and ts.bitmapped <> 0 and ts.online$ in (1,4) and ts.contents$ = 0

union all

select ts.name, fi.file#, u.block#,

       u.length * ts.blocksize, u.length, u.file#

from sys.ts$ ts, sys.uet$ u, sys.file$ fi, sys.recyclebin$ rb

where ts.ts# = u.ts#

  and u.ts# = fi.ts#

  and u.segfile# = fi.relfile#

  and u.ts# = rb.ts#

  and u.segfile# = rb.file#

  and u.segblock# = rb.block#

  and ts.bitmapped = 0;

可以看到dba_free_space视图有三部分组成:fet$,x$ktfbfe,x$ktfbue,recyclebin$。其中
fet$表格主要用于表空间extent管理是数据字典管理,x$ktfbue由前面的实验得知主要用于对位图块的扫描,recyclebin$主要用于
管理回收站对象。

那x$ktfbfe主要用于做什么呢?

View:   X$KTFBUE

         [k]ernel [t]ablespace [f]ile [b]itmapped

           [u]sed [e]xtents

Column          Type               Description

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

ADDR            RAW(4|8)           address of this row/entry in the array or SGA

INDX            NUMBER             index number of this row in the fixed table array

INST_ID         NUMBER             oracle instance number

KTFBUESEGTSN    NUMBER             tablespace number of segment

KTFBUESEGFNO    NUMBER             segment relative file number

KTFBUESEGBNO    NUMBER             segment block number

KTFBUEEXTNO     NUMBER             extent number

KTFBUEFNO       NUMBER             extent file number

KTFBUEBNO       NUMBER             extent block number

KTFBUEBLKS      NUMBER             extent length

打开10046事件跟踪x$ktfbfe

SQL> ALTER SESSION SET EVENTS '10046 trace name context forever, level 12';

Session altered.

SQL> select * from x$ktfbfe;

ADDR           INDX    INST_ID  KTFBFETSN  KTFBFEFNO  KTFBFEBNO KTFBFEBLKS

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

B7F57A70          0          1          0          1      69769        632

B7F57A70          1          1          1          2        233      18328

B7F57A70          2          1          2          3      36953         80

B7F57A70          3          1          2          3      37041         40

B7F57A70          4          1          2          3      37121          8

。。。

SQL> ALTER SESSION SET EVENTS '10046 trace name context off';

Session altered.

打开跟踪文件,首先Oracle对x$ktfbfe进行解析

PARSING IN CURSOR #1 len=22 dep=0 uid=0 oct=3 lid=0 tim=1273325024428885 hv=502180737 ad='2674fde8'

select * from x$ktfbfe

END OF STMT

PARSE #1:c=0,e=130,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=1273325024428880

BINDS #1:

EXEC #1:c=0,e=78,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=1273325024429032

WAIT #1: nam='SQL*Net message to client' ela= 1 driver id=1650815232 #bytes=1 p3=0 obj#=-1 tim=1273325024429077

其次Oracle进一步解析ts$表,获取满足条件的ts#和flags

PARSING IN CURSOR #2 len=100 dep=1 uid=0 oct=3 lid=0 tim=1273325024429259 hv=3768030067 ad='25b84394'

select ts#, flags from ts$ where bitmapped <> 0 and contents$ = 0   and (online$ = 1 or online$ = 4)

END OF STMT

PARSE #2:c=0,e=91,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=1273325024429255

BINDS #2:

EXEC #2:c=1000,e=50,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=1273325024429371

WAIT #2: nam='db file sequential read' ela= 39 file#=1 block#=57 blocks=1 obj#=16 tim=1273325024442859

WAIT #2: nam='db file scattered read' ela= 130 file#=1 block#=58 blocks=7 obj#=16 tim=1273325024443240

FETCH #2:c=1000,e=13908,p=8,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=1273325024443299

最后Oracle解析file$,传入绑定变量0,1,2...8

PARSING IN CURSOR #3 len=36 dep=1 uid=0 oct=3 lid=0 tim=1273325024443480 hv=1570213724 ad='27af1440'

select file# from file$ where ts#=:1

END OF STMT

PARSE #3:c=0,e=80,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=1273325024443476

BINDS #3:

kkscoacd

Bind#0

  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00

  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0

  kxsbbbfp=b7f65180  bln=22  avl=01  flg=05

  value=0

EXEC #3:c=0,e=119,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=1273325024443693

WAIT #3: nam='db file sequential read' ela= 14835 file#=1 block#=113 blocks=1 obj#=16 tim=1273325024458576

WAIT #3: nam='db file sequential read' ela= 236 file#=1 block#=114 blocks=1 obj#=16 tim=1273325024458882

FETCH #3:c=999,e=15195,p=2,cr=3,cu=0,mis=0,r=1,dep=1,og=4,tim=1273325024458914

FETCH #3:c=0,e=8,p=0,cr=1,cu=0,mis=0,r=0,dep=1,og=4,tim=1273325024458949

STAT #3 id=1 cnt=1 pid=0 pos=1 obj=17 op='TABLE ACCESS FULL FILE$ (cr=4 pr=2 pw=0 time=15194 us)'

WAIT #1: nam='db file sequential read' ela= 16 file#=1 block#=2 blocks=1 obj#=-1 tim=1273325024459119

WAIT #1: nam='db file sequential read' ela= 15 file#=1 block#=3 blocks=1 obj#=-1 tim=1273325024459190

FETCH #1:c=2999,e=30138,p=12,cr=8,cu=2,mis=0,r=1,dep=0,og=1,tim=1273325024459250

WAIT #1: nam='SQL*Net message from client' ela= 244 driver id=1650815232 #bytes=1 p3=0 obj#=-1 tim=1273325024459537

FETCH #2:c=0,e=9,p=0,cr=1,cu=0,mis=0,r=1,dep=1,og=4,tim=1273325024459584

。。。

PARSING IN CURSOR #3 len=36 dep=1 uid=0 oct=3 lid=0 tim=1273325024482416 hv=1570213724 ad='27af1440'

select file# from file$ where ts#=:1

END OF STMT

PARSE #3:c=0,e=13,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=1273325024482412

BINDS #3:

kkscoacd

Bind#0

  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00

  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0

  kxsbbbfp=b7f65134  bln=22  avl=02  flg=05

  value=7

EXEC #3:c=0,e=92,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=1273325024482587

FETCH #3:c=0,e=22,p=0,cr=3,cu=0,mis=0,r=1,dep=1,og=4,tim=1273325024482634

FETCH #3:c=0,e=5,p=0,cr=1,cu=0,mis=0,r=0,dep=1,og=4,tim=1273325024482666

STAT #3 id=1 cnt=1 pid=0 pos=1 obj=17 op='TABLE ACCESS FULL FILE$ (cr=4 pr=0 pw=0 time=19 us)'

WAIT #1: nam='db file sequential read' ela= 17 file#=6 block#=2 blocks=1 obj#=-1 tim=1273325024482802

WAIT #1: nam='db file sequential read' ela= 15 file#=6 block#=3 blocks=1 obj#=-1 tim=1273325024482875

FETCH #2:c=0,e=7,p=0,cr=1,cu=0,mis=0,r=1,dep=1,og=4,tim=1273325024482917

通过查看跟踪文件,我们可以看到Oracle对x$ktfbfe表格的查询,最终会转换成对ts$的查询,通过条件过滤定位file$,然后从文件的2号block和3号block去取得数据。

我们知道每个数据文件的2号至-8号block是关于extent map的block。

从block type为1d可以知道这个block类型为KTFB Bitmapped File Space Header

BBED> dump block 2 offset 0 count 32

File: /oradata/mcstar/zhoul01.dbf (0)

Block: 2                Offsets:    0 to   31           Dba:0x00000000

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

1da20000 0200c001 1fb3840e 000a0304 15fd0000 07000000 08000000 60f80000

<32 bytes per line>

从block type为12可以知道这个block类型为KTFB Bitmapped File Space Bitmap

BBED> dump block 3 offset 0 count 32

File: /oradata/mcstar/zhoul01.dbf (0)

Block: 3                Offsets:    0 to   31           Dba:0x00000000

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

1ea20000 0300c001 1fb3840e 000a0104 35cd0000 07000000 09000000 00000000

<32 bytes per line>

从以上分析中我们推断出,Oracle查看x$ktfbfe,其实就是对Oracle 数据文件的block 2至block 8扫描(本例block 3-8为空,则跳过不扫描)。

从dba_free_space视图创建脚本中,我们还看到了表格recyclebin$内容的选取

继续测试:

在数据库中删除一张表格RBOTEST,其数据量有52567

SQL> select count(*) from RBOTEST;

COUNT(*)

----------

     52567

SQL> drop table RBOTEST;

Table dropped.

刷内存,保证脏块刷出至数据文件

SQL>  alter system flush buffer_cache;

System altered.

在recyclebin中我们看到了删除表格

SQL> show recyclebin

ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME

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

RBOTEST          BIN$oeDriA+aATTgQBCsowQS+Q==$0 TABLE        2011-04-27:14:55:03

在基表中也存在

SQL> select OBJ#,OWNER#,ORIGINAL_NAME,FILE#,BLOCK# ,FLAGS,SPACE from recyclebin$;

OBJ#     OWNER# ORIGINAL_NAME                         FILE#     BLOCK#      FLAGS      SPACE

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

    246366         60 RBOTEST_OBJ                               7      29579         18        128

    246367         60 RBOTEST_OWNER#                            7      29707         18        112

    246365         60 RBOTEST                                   7      27147         30        768

但是在x$ktfbfe显示依然是删除前的状态

SQL> select * from x$ktfbfe

  2  where ktfbfefno=7;

ADDR           INDX    INST_ID  KTFBFETSN  KTFBFEFNO  KTFBFEBNO KTFBFEBLKS

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

B7F57A70         50          1          8          7      29817          8

B7F57A70         51          1          8          7      36617        104

B7F57A70         52          1          8          7      60129         40

B7F57A70         53          1          8          7      63497         88

通过bbed查看block状态,发现checkval值未变,这说明Oracle在Oracle 10g中drop 表格时extent map并未发生变化

BBED> dump block 2 offset 0 count 32

File: /oradata/mcstar/zhoul01.dbf (0)

Block: 2                Offsets:    0 to   31           Dba:0x00000000

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

1da20000 0200c001 1fb3840e 000a0304 15fd0000 07000000 08000000 60f80000

<32 bytes per line>

BBED> dump block 3 offset 0 count 32

File: /oradata/mcstar/zhoul01.dbf (0)

Block: 3                Offsets:    0 to   31           Dba:0x00000000

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

1ea20000 0300c001 1fb3840e 000a0104 35cd0000 07000000 09000000 00000000

<32 bytes per line>

清空回收站

SQL> purge recyclebin;

Recyclebin purged.

SQL> select OBJ#,OWNER#,ORIGINAL_NAME,FILE#,BLOCK# ,FLAGS,SPACE from recyclebin$;

no rows selected

继续查看x$ktfbfe和物理上block状态,发现未变,继续刷内存。

SQL> alter system flush buffer_cache;

System altered.

SQL> select * from x$ktfbfe

  2  where ktfbfefno=7;

ADDR           INDX    INST_ID  KTFBFETSN  KTFBFEFNO  KTFBFEBNO KTFBFEBLKS

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

B7F26A58         47          1          8          7      27145        120

B7F26A58         48          1          8          7      27905          8

B7F26A58         49          1          8          7      28937        888

B7F26A58         50          1          8          7      36617        104

B7F26A58         51          1          8          7      60129         40

B7F26A58         52          1          8          7      63497         88

6 rows selected.

BBED> dump block 2 offset 0 count 32

File: /oradata/mcstar/zhoul01.dbf (0)

Block: 2                Offsets:    0 to   31           Dba:0x00000000

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

1da20000 0200c001 5879930e 000a0104 955b0000 07000000 08000000 60f80000

<32 bytes per line>

BBED> dump block 3 offset 0 count 32

File: /oradata/mcstar/zhoul01.dbf (0)

Block: 3                Offsets:    0 to   31           Dba:0x00000000

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

1ea20000 0300c001 5879930e 000a0104 6e0e0000 07000000 09000000 00000000

<32 bytes per line>

可以看到x$ktfbfe和block均发生了变化。

通过对dba_free_space的研究我们可以得出以下结论:

1、对x$ktfbfe的扫描,其实是物理上对数据文件2-8号block的扫描

2、在Oracle 10g,在不带参数purge,drop表格时,并不会对数据文件头extent
map更新,通过这种方式减少了Oracle对extent
map争用的可能性,这也是dba_free_space视图创建脚本中需要对基表recyclebin$选择的原因之一。曾经碰到过一案例,回收站对象
太多导致执行dba_free_space时间很长。

3、在对回收站清空后,会更新数据文件头extent map,但命令purge recyclebin并不会引起对象基表的checkpoint。

谈谈Oracle dba_free_space的更多相关文章

  1. 谈谈oracle中的临时表

    --------------------创建临时表 临时保存从xml字符串解析来的数据--------------------------- 会话级别临时表SQL> create global ...

  2. 谈谈oracle里的join、left join、right join、full join-版本2

    --1.left join  左表为主表,左表返回全部数据,右表只返回与左表相匹配的数据select   t1.fpdm,t1.fphm ,t1.zjr,t1.zjsj,t1.zjjx,t1.zjje ...

  3. 谈谈oracle里的join、left join、right join

    create table l as select 'left_1' as str,'1' as v from dual union allselect 'left_2' ,'2' as v from ...

  4. 关于ORACLE通过file_id与block_id定位数据库对象遇到的问题的一点思考

    在ORACLE中,我们可以通过file_id(file#)与block_id(block#)去定位一个数据库对象(object).例如,我们在10046生成的trace文件中file#=4 block ...

  5. oracle 监听启动、停止、查看命令

    1.su oracle 然后启动监听器 1.lsnrctl start  会看到启动成功的界面; 1.lsnrctl stop  停止监听器命令. 1.lsnrctl status  查看监听器命令. ...

  6. oracle 方向及资料

    总结了一下大家的意见,也加了一些个人的看法,Oracle的学习路径,可供参考: 初级阶段: 可以从OCP教材开始,还有文档中的Administrator's Guide.Concepts.Perfor ...

  7. 说说oracle中的面向对象与面向集合

    这一篇算是对近期自己学习的一个心得总结 一.oracle的面向对象 SQL是面向集合的这个大家都知道,但是不可否认现在的oracle中有很多地方都体现着面向对象的思维.(这也算是各大语言殊途同归的一个 ...

  8. [转帖]Oracle 12cR2使用经验

    大规模升级来临,谈谈Oracle 12cR2使用经验 随着2019年2月13日,Oracle 19c (Oracle 12.2.0.3) for Exadata 版本发布,Oracle 12cR2体系 ...

  9. Oracle降低高水位先(转载)

    Oracle  降低高水位线的方法 高水位(HIGH WARTER MARK,HWM)好比水库中储水的水位,用于描述数据库中段的扩展方式.高水位对全表扫描方式有着至关重要的影响.当使用DELETE删除 ...

随机推荐

  1. 一个人ACM(我们赶上了ACM)

    时间过得真快,不经意间我已经花了两年的大学生活,现在是时候写的东西.纪念馆两年左右的时间,最近一直在玩博客.我写了一个博客.纪念我们终将逝去的青春. 就从报考说起吧.高考成绩一般,自己选择了土建类的学 ...

  2. 对java中classloader使用的一点理解(转)

    先简单介绍下java的classloader,网上资料很多,就说点关键的. Java 中的类加载器大致可以分成两类,一类是系统提供的,另外一类则是由 Java 应用开发人员编写的.系统提供的类加载器主 ...

  3. ASP.NET MVC流程解说

    开始想这个标题时,,很忧郁什么标题将得到更好的叫什么,最后确定的解释,虽然稍0基金会,但是,这个概念是非常.我想出了一个相当的价格值的. ,開始. 1.MVC的基本开发流程   2.webform和M ...

  4. Java新手如何学习Spring、Struts、Hibernate三大框架?(转)

    整理知乎大牛答案: 1.入门看文档(blog,书籍等等),深入理解配置文件的含义(Spring.Struts.Hibernate); 2.遇到问题,自己动手解决,如果解决了,为什么这样解决?(凡事总问 ...

  5. springMVC注解优化

    本文是本人在学习网络视频的过程中的一些总结. 本文是对关于一些springMVC在使用注解的优化. 使用以下的标签,会自己主动引入Annotation的配置 <mvc:annotation-dr ...

  6. Qt Quick 组件和动态创建的对象具体的解释

    在<Qt Quick 事件处理之信号与槽>一文中介绍自己定义信号时,举了一个简单的样例.定义了一个颜色选择组件,当用户在组建内点击鼠标时,该组件会发出一个携带颜色值的信号,当时我使用 Co ...

  7. printf 对齐

      printf关于对其的问题(参考有关博客加上自己的一些总结) 1.关于左对齐或右对齐问题, 默认的如果%后没有“-”是右对齐的,如果%后跟“0”,不足的个数用0来填充, 例如:printf(&qu ...

  8. C语言字符串函数大全

    C语言字符串函数大全 函数名: stpcpy 功 能: 拷贝一个字符串到另一个 用 法: char *stpcpy(char *destin, char *source); 程序例: #include ...

  9. 大数据系列修炼-Scala课程04

    Scala中继承实现:超类的构造.字段重写.方法重写 关于超类的构建:超类可以在子类没有位置的限制,可以在子类中调用父类的方法 类中字段重写:在重写字段前面加一个override就可以重新赋值 类中方 ...

  10. autorun.vbs病毒的清除办法

    症状:计算机里面出现一堆autorun为文件名称的文件,删除后出现找不到autorun.vbs的提示.我就打开当中的一个文件:Autorun.bat,内容例如以下: @echo off  //不显示系 ...