Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2868589
  • 博文数量: 599
  • 博客积分: 16398
  • 博客等级: 上将
  • 技术积分: 6875
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-30 12:04
个人简介

WINDOWS下的程序员出身,偶尔也写一些linux平台下小程序, 后转行数据库行业,专注于ORACLE和DB2的运维和优化。 同时也是ios移动开发者。欢迎志同道合的朋友一起研究技术。 数据库技术交流群:58308065,23618606

文章分类

全部博文(599)

文章存档

2014年(12)

2013年(56)

2012年(199)

2011年(105)

2010年(128)

2009年(99)

分类: Oracle

2012-08-17 14:35:53

今天在测试库检查数据文件大小的时候,发现FILE$记录的与数据字典视图不一致,本以为file$记录的就是文件的大小,实际却不是这样的。

点击(此处)折叠或打开

  1. SQL> select file#,blocks from v$datafile_header;

  2.      FILE# BLOCKS
  3. ---------- ----------

  4.          1 88320
  5.          2 62720
  6.          3 10880
  7.          4 640
  8.          5 12800
  9.          6 5120

  10. 6 rows selected.

  11. SQL> select file_id,blocks from dba_data_files order by 1;

  12.    FILE_ID BLOCKS
  13. ---------- ----------

  14.          1 88320
  15.          2 62720
  16.          3 10880
  17.          4 640
  18.          5 12800
  19.          6 5120

  20. 6 rows selected.

  21. SQL> select file#,blocks from file$;

  22.      FILE# BLOCKS
  23. ---------- ----------

  24.          1 64000
  25.          2 51200
  26.          3 3200
  27.          4 640
  28.          5 12800
  29.          6 1280

  30. 6 rows selected.

上面的结果显示dba_data_files与v$datafile_header一样,也与实际文件的大小一样,而file$记录的却与实际文件大小不一样。
通过创建DBA_DATA_FILES视图脚本发现这个视图来自2部分,一个是file$.spare1 is NULL的情况,一个是file$.spare1 is not NULL情况。
如下所示:

点击(此处)折叠或打开

  1. select v.name, f.file#, ts.name,
  2.        ts.blocksize * f.blocks, f.blocks,
  3.        decode(f.status$, 1, 'INVALID', 2, 'AVAILABLE', 'UNDEFINED'),
  4.        f.relfile#, decode(f.inc, 0, 'NO', 'YES'),
  5.        ts.blocksize * f.maxextend, f.maxextend, f.inc,
  6.        ts.blocksize * (f.blocks - 1), f.blocks - 1,
  7.        decode(fe.fetsn, 0, decode(bitand(fe.festa, 2), 0, 'SYSOFF', 'SYSTEM'),
  8.          decode(bitand(fe.festa, 18), 0, 'OFFLINE', 2, 'ONLINE', 'RECOVER'))
  9. from sys.file$ f, sys.ts$ ts, sys.v$dbfile v, x$kccfe fe
  10. where v.file# = f.file#
  11.   and f.spare1 is NULL
  12.   and f.ts# = ts.ts#
  13.   and fe.fenum = f.file#
  14. union all
  15. select
  16.        v.name,f.file#, ts.name,
  17.        decode(hc.ktfbhccval, 0, ts.blocksize * hc.ktfbhcsz, NULL),
  18.        decode(hc.ktfbhccval, 0, hc.ktfbhcsz, NULL),
  19.        decode(f.status$, 1, 'INVALID', 2, 'AVAILABLE', 'UNDEFINED'),
  20.        f.relfile#,
  21.        decode(hc.ktfbhccval, 0, decode(hc.ktfbhcinc, 0, 'NO', 'YES'), NULL),
  22.        decode(hc.ktfbhccval, 0, ts.blocksize * hc.ktfbhcmaxsz, NULL),
  23.        decode(hc.ktfbhccval, 0, hc.ktfbhcmaxsz, NULL),
  24.        decode(hc.ktfbhccval, 0, hc.ktfbhcinc, NULL),
  25.        decode(hc.ktfbhccval, 0, hc.ktfbhcusz * ts.blocksize, NULL),
  26.        decode(hc.ktfbhccval, 0, hc.ktfbhcusz, NULL),
  27.        decode(fe.fetsn, 0, decode(bitand(fe.festa, 2), 0, 'SYSOFF', 'SYSTEM'),
  28.          decode(bitand(fe.festa, 18), 0, 'OFFLINE', 2, 'ONLINE', 'RECOVER'))
  29. from sys.v$dbfile v, sys.file$ f, sys.x$ktfbhc hc, sys.ts$ ts, x$kccfe fe
  30. where v.file# = f.file#
  31.   and f.spare1 is NOT NULL
  32.   and v.file# = hc.ktfbhcafno
  33.   and hc.ktfbhctsn = ts.ts#
  34.   and fe.fenum = f.file#;

对于spare1 is NULL的情况,DBA_DATA_FILES显示的文件BLOCKS来自file$视图,而对于spare1 is NOT NULL的情况,
实际文件的大小来自sys.x$ktfbhc视图。
 
查询了一下这个FILE$表的创建脚本,SPARE1列的含义是tablespace-relative DBA of space file header。
 

点击(此处)折叠或打开

  1. create table file$ /* file table */
  2. ( file# number not null, /* file identifier number */
  3.   status$ number not null, /* status (see KTS.H): */
  4.                                                /* 1 = INVALID, 2 = AVAILABLE */
  5.   blocks number not null, /* size of file in blocks */
  6.                                            /* zero for bitmapped tablespaces */
  7.   ts# number, /* tablespace that owns file */
  8.   relfile# number, /* relative file number */
  9.   maxextend number, /* maximum file size */
  10.   inc number, /* increment amount */
  11.   crscnwrp number, /* creation SCN wrap */
  12.   crscnbas number, /* creation SCN base */
  13.   ownerinstance varchar("M_IDEN"), /* Owner instance name */
  14.   spare1 number, /* tablespace-relative DBA of space file header */
  15.                                    /* NULL for dictionary-mapped tablespaces */
  16.   spare2 number,
  17.   spare3 varchar2(1000),
  18.   spare4 date
  19. )
  20. /

查询表file$ 的spare1列确实都不是为NULL的,如下:
 

点击(此处)折叠或打开

  1. SQL> select file#,blocks,spare1 from file$;

  2.      FILE# BLOCKS SPARE1
  3. ---------- ---------- ----------

  4.          1 64000 4194306
  5.          2 51200 8388610
  6.          3 3200 12582914
  7.          4 640 16777218
  8.          5 12800 20971522
  9.          6 1280 25165826

  10. 6 rows selected.


DBA_DATA_FILES显示的正确结果实际来自表sys.x$ktfbhc,这个表的含义是Kernel Tablespace File Bitmap Header Control
 

点击(此处)折叠或打开

  1. SQL> select KTFBHCAFNO,KTFBHCSZ from sys.x$ktfbhc;

  2. KTFBHCAFNO KTFBHCSZ
  3. ---------- ----------

  4.          1 88320
  5.          2 62720
  6.          3 10880
  7.          4 640
  8.          5 12800
  9.          6 5120

  10. 6 rows selected.

实际视图的这2部分分别代表字典管理的表空间和本地管理的表空间。
对于本地管理的表空间,file$表记录的是文件创建时候的大小,一旦文件以后自动扩展了或者RESIZLE了,file$
表显示的文件大小必须从sys.x$ktfbhc查询了。
如下:

点击(此处)折叠或打开

  1. SQL> select 1000*8192 from dual;

  2.  1000*8192
  3. ----------

  4.    8192000

  5. SQL> create tablespace filetest datafile '/u01/app/oracle/oradata/huateng/file01.dbf' size 8192000;

  6. Tablespace created.

  7. SQL> select file#,blocks,spare1 from file$;

  8.      FILE# BLOCKS SPARE1
  9. ---------- ---------- ----------

  10.          1 64000 4194306
  11.          2 51200 8388610
  12.          3 3200 12582914
  13.          4 640 16777218
  14.          5 12800 20971522
  15.          6 1280 25165826
  16.          7 1000 29360130

  17. 7 rows selected.

  18. SQL> select KTFBHCAFNO,KTFBHCSZ from sys.x$ktfbhc;

  19. KTFBHCAFNO KTFBHCSZ
  20. ---------- ----------

  21.          1 88320
  22.          2 62720
  23.          3 10880
  24.          4 640
  25.          5 12800
  26.          6 5120
  27.          7 1000

  28. 7 rows selected.

  29. SQL> select 2000*8192 from dual;

  30.  2000*8192
  31. ----------

  32.   16384000

  33. SQL> alter database datafile 7 resize 16384000;

  34. Database altered.

  35. SQL> select file#,blocks,spare1 from file$;

  36.      FILE# BLOCKS SPARE1
  37. ---------- ---------- ----------

  38.          1 64000 4194306
  39.          2 51200 8388610
  40.          3 3200 12582914
  41.          4 640 16777218
  42.          5 12800 20971522
  43.          6 1280 25165826
  44.          7 1000 29360130

  45. 7 rows selected.

  46. SQL> select KTFBHCAFNO,KTFBHCSZ from sys.x$ktfbhc;

  47. KTFBHCAFNO KTFBHCSZ
  48. ---------- ----------

  49.          1 88320
  50.          2 62720
  51.          3 10880
  52.          4 640
  53.          5 12800
  54.          6 5120
  55.          7 2000

  56. 7 rows selected.

因此正确的查询文件的大小还是通过DBA_DATA_FILES保险,无论是本地管理的表空间还是字典管理的表空间。
file$表显示的大小对于本地管理的表空间是不正确的。
阅读(2146) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~