您的位置:首页 > 数据库 > Oracle

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

2016-08-22 22:24 330 查看
以前写了一篇ORACLE临时表空间总结的文章,里面介绍了几个查看临时表空间使用情况的脚本,其中一个脚本如下所示:

SELECTTU.TABLESPACE_NAMEAS"TABLESPACE_NAME",
TT.TOTAL-TU.USEDAS"FREE(G)",
TT.TOTALAS"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(SELECTTABLESPACE_NAME,
SUM(BYTES_USED)/1024/1024/1024USED
FROMGV_$TEMP_SPACE_HEADER
GROUPBYTABLESPACE_NAME)TU,
(SELECTTABLESPACE_NAME,
SUM(BYTES)/1024/1024/1024ASTOTAL
FROMDBA_TEMP_FILES
GROUPBYTABLESPACE_NAME)TT
WHERETU.TABLESPACE_NAME=TT.TABLESPACE_NAME;




其实这个查看表空间的脚本是不准确的,有问题的(当然前面博客里面所提到的脚本到现在也没有改,以后也不打算修改了,就这样放着吧)。你可以对比下面几个脚本来看看。
如果临时表空间是dictionarymanagedtemporarytablespace,可以使用下面SQL:

SELECT(S.TOT_USED_BLOCKS/F.TOTAL_BLOCKS)*100AS"PERCENTUSED"
FROM
(SELECTSUM(USED_BLOCKS)TOT_USED_BLOCKS
FROMV$SORT_SEGMENT
WHERETABLESPACE_NAME='TEMPSCM2'
)S,
(SELECTSUM(BLOCKS)TOTAL_BLOCKS
FROMDBA_DATA_FILES
WHERETABLESPACE_NAME='TEMPSCM2'
)F;

如果临时表空间是LocallyManageedTemporaryTablespace,使用下面SQL:

SQL>SELECTT.TABLESPACE_NAME,
(U.TOT_USED_BLOCKS/T.TOTAL_BLOCKS)*100AS"PERCENTUSED"
FROM(SELECTTABLESPACE_NAME,
SUM(USED_BLOCKS)TOT_USED_BLOCKS
FROMV$SORT_SEGMENT
WHERETABLESPACE_NAME=&TABLESPACE_NAME
GROUPBYTABLESPACE_NAME)U,
(SELECTTABLESPACE_NAME,
SUM(BLOCKS)TOTAL_BLOCKS
FROMDBA_TEMP_FILES
WHERETABLESPACE_NAME=&TABLESPACE_NAME
GROUPBYTABLESPACE_NAME)T;




当然你也可以使用下面SQL来查看临时表空间的使用情况,如下所示:

SELECTD.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(SELECTtablespace_name,
Round(SUM(bytes)/(1024*1024),2)SPACE,
SUM(blocks)BLOCKS
FROMdba_temp_files
GROUPBYtablespace_name)D,
(SELECTtablespace,
Round(SUM(blocks*8192)/(1024*1024),2)USED_SPACE
FROMv$sort_usage
GROUPBYtablespace)F
WHERED.tablespace_name=F.tablespace(+)
ANDD.tablespace_name='TEMPSCM2'




那么为什么GV_$TEMP_SPACE_HEADER统计的数据不准确呢?这个是因为GV_$TEMP_SPACE_HEADER取数据不准确,官方解释为:
Theviewsv$sort_usageorv$tempseg_usage(andv$sort_segment)givethecorrectinformationregardingtheallocationofsortsegments.
Weshouldalwaysquerytheseviewstofindouttheactualtempusage.Theviewv$temp_space_headershowsthatthesemanyblocksweretouchedineachtempfileatsomepointwhentempusagewasatitshighest,
inessence,itshowsthenumberofinitializedblocksforeachtempfile,nottheactualallocatedblocks.
Theviewsv$sort_usage/v$tempseg_usageshowtheactualsortextentsallocatedforeachtransactionfromtheseinitializedblocks.Also,v$temp_space_headerispersistentacrossrestarts.V$sort_segmentandv$sort_usagearenot.
第二段我翻译如下:
视图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>SELECTOWNER,OBJECT_NAME,OBJECT_TYPEFROMDBA_OBJECTSWHEREOBJECT_NAME='GV_$TEMP_SPACE_HEADER';
OWNEROBJECT_NAMEOBJECT_TYPE
----------------------------------------------------------------------
SYSGV_$TEMP_SPACE_HEADERVIEW


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

SELECTDBMS_METADATA.GET_DDL('VIEW','GV_$TEMP_SPACE_HEADER','SYS')FROMDUAL;
SELECT*FROMDBA_VIEWSWHEREVIEW_NAME='GV_$TEMP_SPACE_HEADER';
SELECT"INST_ID",
"TABLESPACE_NAME",
"FILE_ID",
"BYTES_USED",
"BLOCKS_USED",
"BYTES_FREE",
"BLOCKS_FREE",
"RELATIVE_FNO"
ROMgv$temp_space_header


而gv$temp_space_header视图的定义如下(当然如果查询DBA_OBJECTS会发现它是一个同义词,指向GV_$TEMP_SPACE_HEADER,这个后面介绍原因)

SQL>selectview_definitionfromv$fixed_view_definition
2whereview_name='GV$TEMP_SPACE_HEADER';
VIEW_DEFINITION
--------------------------------------------------------------------------------
select/*+ordereduse_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.ktfthcfnofromts$ts,x$ktfthchcwherets.conten
ts$=1andts.bitmapped<>0andts.online$=1andts.ts#=hc.ktfthctsnandh
c.ktfthccval=0
SQL>


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

SELECTOWNER,OBJECT_NAME,OBJECT_TYPEFROMDBA_OBJECTSWHEREOBJECT_NAME=upper('v$temp_space_header');
QL>selectview_definitionfromv$fixed_view_definition
2whereview_name=upper('v$temp_space_header');
IEW_DEFINITION
-------------------------------------------------------------------------------
electTABLESPACE_NAME,FILE_ID,BYTES_USED,BLOCKS_USED,BYTES_FREE,BLOC
S_FREE,RELATIVE_FNOfromGV$TEMP_SPACE_HEADERwhereinst_id=USERENV('Instan
e')




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

createorreplaceviewgv_$temp_space_headerasselect*fromgv$temp_space_header;
createorreplacepublicsynonymgv$temp_space_header
forgv_$temp_space_header;
grantselectongv_$temp_space_headertoSELECT_CATALOG_ROLE;



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: