ORACLE使用GV_$TEMP_SPACE_HEADER统计临时表空使用状况不许确的问题

之前写了一篇ORACLE临时表空间总结的文章, 里面介绍了几个查看临时表空间使用状况的脚本,其中一个脚本以下所示:html

 

SELECT TU.TABLESPACE_NAME                                    AS "TABLESPACE_NAME",
       TT.TOTAL - TU.USED                                    AS "FREE(G)",
       TT.TOTAL                                              AS "TOTAL(G)",
       ROUND(NVL(TU.USED, 0) / TT.TOTAL * 100, 3)            AS "USED(%)",
       ROUND(NVL(TT.TOTAL - TU.USED, 0) * 100 / TT.TOTAL, 3) AS "FREE(%)"
FROM (SELECT TABLESPACE_NAME, 
              SUM(BYTES_USED) / 1024 / 1024 / 1024 USED
       FROM GV_$TEMP_SPACE_HEADER
       GROUP BY TABLESPACE_NAME) TU ,
     (SELECT TABLESPACE_NAME,
              SUM(BYTES) / 1024 / 1024 / 1024 AS TOTAL
       FROM DBA_TEMP_FILES
       GROUP BY TABLESPACE_NAME) TT
WHERE TU.TABLESPACE_NAME = TT.TABLESPACE_NAME;

clip_image001

 

其实这个查看表空间的脚本是不许确的,有问题的(固然前面博客里面所提到的脚本到如今也没有改,之后也不打算修改了,就这样放着吧)。你能够对比下面几个脚原本看看。 sql

   

若是临时表空间是dictionary managed temporary tablespace,可使用下面SQL:app

SELECT (S.TOT_USED_BLOCKS/F.TOTAL_BLOCKS)*100 AS "PERCENT USED"
FROM
  (SELECT SUM(USED_BLOCKS) TOT_USED_BLOCKS
  FROM V$SORT_SEGMENT
  WHERE TABLESPACE_NAME='TEMPSCM2'
  ) S,
  (SELECT SUM(BLOCKS) TOTAL_BLOCKS
  FROM DBA_DATA_FILES
  WHERE TABLESPACE_NAME='TEMPSCM2'
  ) F;

 

若是临时表空间是Locally Manageed Temporary Tablespace,使用下面SQL:spa

SQL> SELECT  T.TABLESPACE_NAME,
            ( U.TOT_USED_BLOCKS / T.TOTAL_BLOCKS ) * 100 AS "PERCENT USED" 
     FROM   (SELECT TABLESPACE_NAME,
                    SUM(USED_BLOCKS) TOT_USED_BLOCKS 
             FROM   V$SORT_SEGMENT 
             WHERE  TABLESPACE_NAME = &TABLESPACE_NAME
             GROUP BY TABLESPACE_NAME) U, 
            (SELECT TABLESPACE_NAME,
                    SUM(BLOCKS) TOTAL_BLOCKS 
             FROM   DBA_TEMP_FILES 
             WHERE  TABLESPACE_NAME = &TABLESPACE_NAME
             GROUP BY TABLESPACE_NAME) T;

clip_image002

 

固然你也可使用下面SQL来查看临时表空间的使用状况, 以下所示:翻译

SELECT D.tablespace_name, 
               SPACE                                      "SUM_SPACE(M)", 
               blocks                                     "SUM_BLOCKS", 
               used_space                                 "USED_SPACE(M)", 
               Round(Nvl(used_space, 0) / SPACE * 100, 2) "USED_RATE(%)", 
               SPACE - used_space                         "FREE_SPACE(M)" 
        FROM   (SELECT tablespace_name, 
                       Round(SUM(bytes) / ( 1024 * 1024 ), 2) SPACE, 
                       SUM(blocks)                            BLOCKS 
                FROM   dba_temp_files 
                GROUP  BY tablespace_name) D, 
               (SELECT tablespace, 
                       Round(SUM(blocks * 8192) / ( 1024 * 1024 ), 2) USED_SPACE 
                FROM   v$sort_usage 
                GROUP  BY tablespace) F 
        WHERE  D.tablespace_name = F.tablespace(+)
          AND  D.tablespace_name='TEMPSCM2'

clip_image003

 

 

那么为何GV_$TEMP_SPACE_HEADER统计的数据不许确呢? 这个是由于GV_$TEMP_SPACE_HEADER取数据不许确,官方解释为: 3d

 

The views v$sort_usage or v$tempseg_usage ( and v$sort_segment) give the correct information regarding the allocation of sort segments. rest

We should always query these views to find out the actual temp usage. The view v$temp_space_header shows that these many blocks were touched in each temp file at some point when temp usage was at its highest, code

in essence, it shows the number of initialized blocks for each tempfile, not the actual allocated blocks. orm

The views v$sort_usage/v$tempseg_usage show the actual sort extents allocated for each transaction from these initialized blocks. Also, v$temp_space_header is persistent across restarts. V$sort_segment and v$sort_usage are not. htm

 

 

第二段我翻译以下:

视图v$temp_space_header显示的是每个temp文件在某一个时刻使用过的最大大小,从本质上说,它显示的是每个tempfile的初始化大小,而不是实际分配的块大小。

 

因此说从视图v$temp_space_header获取的数据其实并非实际使用的大小,它是不许确的。那么确定有人会问,脚本里面不是访问的GV_$TEMP_SPACE_HEADER视图吗? 跟这个视图v$temp_space_header有关系吗? 答案是有关系,他们的数据来源是一致的,也就是说来自相同的内部表,以下所示:

 

通常来讲,在GV$和V$以后, Oracle会创建GV_$和V_$视图, 随后为这些视图创建了公用同义词。GV_$TEMP_SPACE_HEADER是一个视图,以下所示

SQL> SELECT OWNER, OBJECT_NAME, OBJECT_TYPE FROM DBA_OBJECTS WHERE OBJECT_NAME ='GV_$TEMP_SPACE_HEADER';
 
OWNER                   OBJECT_NAME                         OBJECT_TYPE
-------------------- ------------------------------- -------------------
SYS                     GV_$TEMP_SPACE_HEADER                VIEW

 

GV_$TEMP_SPACE_HEADER视图的定义以下所示:

SELECT DBMS_METADATA.GET_DDL('VIEW', 'GV_$TEMP_SPACE_HEADER', 'SYS') FROM DUAL;
SELECT * FROM DBA_VIEWS WHERE VIEW_NAME='GV_$TEMP_SPACE_HEADER';
 
 
SELECT "INST_ID",
 "TABLESPACE_NAME",
 "FILE_ID",
 "BYTES_USED",
 "BLOCKS_USED",
 "BYTES_FREE",
 "BLOCKS_FREE",
 "RELATIVE_FNO"
ROM gv$temp_space_header

 

 

而gv$temp_space_header视图的定义以下(固然若是查询DBA_OBJECTS会发现它是一个同义词,指向GV_$TEMP_SPACE_HEADER,这个后面介绍缘由)

SQLselect view_definition from v$fixed_view_definition
  2  where view_name='GV$TEMP_SPACE_HEADER';
 
VIEW_DEFINITION
--------------------------------------------------------------------------------
select /*+ ordered use_nl(hc) */ hc.inst_id, ts.name, hc.ktfthctfno, (hc.ktfthcs
z - hc.ktfthcfree)*ts.blocksize, (hc.ktfthcsz - hc.ktfthcfree), hc.ktfthcfree*ts
.blocksize, hc.ktfthcfree, hc.ktfthcfno from ts$ ts, x$ktfthc hc where ts.conten
ts$ = 1 and ts.bitmapped <> 0 and ts.online$ = 1 and ts.ts# = hc.ktfthctsn and h
c.ktfthccval = 0
 
 
SQL> 

 

 

v$temp_space_header它也是一个视图(查询DBA_OBJECTS发现其是一个同义词,这个后面介绍),你会发现v$temp_space_header实际上是从视图GV$TEMP_SPACE_HEADER过滤数据,以下所示:

SELECT OWNER, OBJECT_NAME, OBJECT_TYPE FROM DBA_OBJECTS WHERE OBJECT_NAME =upper('v$temp_space_header');
 
 
QL> select view_definition from v$fixed_view_definition
 2   where view_name=upper('v$temp_space_header');
 
IEW_DEFINITION
-------------------------------------------------------------------------------
elect  TABLESPACE_NAME , FILE_ID , BYTES_USED , BLOCKS_USED , BYTES_FREE , BLOC
S_FREE , RELATIVE_FNO from GV$TEMP_SPACE_HEADER where inst_id = USERENV('Instan
e')

clip_image004

 

你在$ORACLE_HOME/rdbms/admin下的catspace.sql中,就会发现这样的SQL,这就解释了为何gv$temp_space_header是视图,又是同义词的缘由。

create or replace view gv_$temp_space_header as select * from gv$temp_space_header;
 
create or replace public synonym gv$temp_space_header
   for gv_$temp_space_header;
 
grant select on gv_$temp_space_header to SELECT_CATALOG_ROLE;

clip_image005

相关文章
相关标签/搜索