`
itspace
  • 浏览: 979058 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

谈谈Oracle dba_free_space

阅读更多

顾名思义,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。
分享到:
评论

相关推荐

    Oracle10g DBA经常使用的动态性能视图和数据字典

    - **dba_free_space**:提供了所有表空间中的自由分区信息,有助于DBA了解哪些表空间还有可用空间。 - **dba_indexs**:描述了数据库中所有索引的信息,包括索引类型、状态等。这对于优化查询性能非常重要。 - **dba...

    Oracle_DBA_数据库日常维护手册常用SQL_脚本

    FROM dba_free_space GROUP BY tablespace_name; ``` 此查询返回每个表空间中的碎片数量和最大碎片大小,帮助DBA识别哪些表空间需要进行碎片整理。一旦确定了需要整理的表空间,DBA可以使用ALTER TABLESPACE命令来...

    oracle_DBA常用命令

    SELECT tablespace_name, file_id, Block_id, bytes, blocks FROM Dba_free_space; ``` - **作用:** 查询每个表空间中的自由块信息,包括块的位置、大小等。 - **应用场景:** 用于识别表空间中的碎片化程度,并...

    ORACLE DBA常用SQL语句

    - `DBA_FREE_SPACE`和`DBA.segments`:查看表空间和段的使用情况。 - `ALTER TABLESPACE ADD DATAFILE`和`DROP DATAFILE`:添加或删除数据文件。 通过熟练掌握以上SQL语句,ORACLE DBA能够高效地管理数据库,确保...

    oracle dba常用sql

    FROM dba_free_space GROUP BY tablespace_name ) WHERE tablespace_name = fs_ts_name; ``` #### 6. 查询表空间剩余空间 - **查看表空间剩余空间**: - 下面的SQL命令可以帮助您了解每个表空间的剩余空间...

    ORACLE数据字典

    tablespaces、DBA_ts_quotas、DBA_segments、DBA_extents、DBA_part_tables、DBA_tab_partitions、DBA_ind_partitions、DBA_free_space、DBA_users、user_resource_limits、DBA_tab_privs、DBA_col_privs、DBA_sys_...

    Oracle DBA必备日常维护问题大全

    from dba_data_files a, dba_free_space b where a.file_id = b.file_id group by a.tablespace_name, a.file_id, a.bytes, a.file_name order by a.file_id; ``` - **查看特定表的空间使用情况**: - 首先...

    ORACLE DBA的工作内容范围和职责

    通过查询数据库视图,如`dba_data_files`和`dba_free_space`,可以获取表空间的使用率,预防空间耗尽的情况发生,并做出相应的扩展或清理策略。 6. **安全性与规范制定**:DBA需要制定和执行数据库安全策略,确保...

    oracle系统视图作用大全

    19. **DBA_EXTENTS/DBA_FREE_SPACE/DBA_FREE_SPACE_COALESCED**: 这些视图提供了关于数据库空间使用情况的详细信息,包括分配的区、空闲空间和合并空间的统计数据。 20. **DBA_IND_COLUMNS/DBA_IND_EXPRESSIONS/DBA...

    Oracle_系统表大全.doc

    - **`dba_free_space`**:统计各个表空间中的空闲空间。 - **示例命令**: ```sql SELECT tablespace_name, SUM(bytes), SUM(blocks) FROM dba_free_space GROUP BY tablespace_name; ``` - **`dba_data_files...

    oracle 数据库常用数据字典梳理.docx

    静态视图的示例包括 dba_data_files、dba_db_links、dba_extents、dba_free_space 等。 动态视图是指从 SGA 和控制文件中获取的信息,用于记录当前数据库的活动情况,包括当前会话、锁、事务、SQL 语句执行情况等。...

    oracle_巡查脚本

    它通过查询`dba_free_space`视图,汇总了各个表空间的自由块(free_blk)数量,以MB为单位的总自由空间(free_m),最大的连续自由空间块(big_chunk_k)以及自由空间的块数(num_chunks)。这对于监控表空间增长...

    oracle_常用系统表.docx

    10. **dba_free_space**: 提供了各表空间的空闲空间信息。 11. **dba_profiles**: 定义了用户的资源限制,如CPU使用、会话数量等。 12. **dba_sys_privs**和**dba_tab_privs**: 分别记录系统权限和对象权限的授予...

    oracle dba数据库日常维护完全手册

    select tablespace_name, count(*) chunks, max(bytes/1024/1024) max_chunk from dba_free_space group by tablespace_name; 如果表空间的碎片状况较严重,可以尝试使用以下 SQL 命令进行表空间相邻碎片的接合: ...

    Oracle DBA数据库工程师重要的技术要点

    2) used_pct from (select tablespace_name,sum(bytes) sumbytes from dba_data_files group by tablespace_name) d, (select tablespace_name,sum(bytes) sumbytes from dba_free_space group by tablespace_name) ...

    查询当前所有表空间的总大小和已使用的大小

    ##### 方法一:联合使用`dba_data_files`与`dba_free_space` 1. **查询总大小**:首先,通过`dba_data_files`视图计算每个表空间的数据文件总大小(以MB为单位)。 ```sql SELECT t.tablespace_name, SUM(t....

    Oracle_系统表大全[参照].pdf

    - `SELECT tablespace_name, SUM(bytes), SUM(blocks) FROM dba_free_space GROUP BY tablespace_name`获取每个表空间的总空间和空闲空间。 - `SELECT * FROM dba_data_files WHERE tablespace_name='RBS'`查询...

    实验2_Oracle数据库体系结构

    6. **磁盘空间分布**:使用`DBA_FREE_SPACE`和`DBA_DATA_FILES`联接查询,可以详细地查看每个表空间在每个数据文件上的使用和剩余空间。 7. **回滚段的状态**:查询`DBA_ROLLBACK_SEGS`可以检查所有回滚段的状态、...

Global site tag (gtag.js) - Google Analytics