聊聊dba_temp_free_space的allocated_space和free_space

咕嚕咕嚕先生發表於2018-06-09

 

每一個Oracle版本,都會有很多新特性和技術推出。這些技術特性,在很大程度上都能改進Oracle執行效率和應用效果,或者提高我們日常工作能力。

Temp表空間是Oracle表空間體系中一種很特殊的表空間物件。臨時表空間主要用於支援臨時表空間使用、排序分組動作空間溢位暫存等作用。我們對Temp的使用,大都是侷限在空間分配和大小設定上。在11g有,有一系列針對Temp表空間的新特性,可以很大程度上幫助我們工作。

檢視dba_temp_free_space11g引入的一個新檢視,用於描述臨時表空間使用情況。

 

SQL> select * from dba_temp_free_space;

 

TABLESPACE_NAME TABLESPACE_SIZE ALLOCATED_SPACE FREE_SPACE

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

TEMP                  481296384       481296384  479199232

 

最近和一個朋友聊起其中allocated_spacefree_space的含義,覺得很有意思。筆者決定透過一些實驗來證明結論。

 

1、環境準備

 

筆者使用Oracle11gR2環境進行測試。

 

SQL> select * from v$version;

 

BANNER

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

Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production

PL/SQL Release 11.2.0.3.0 - Production

CORE 11.2.0.3.0 Production

TNS for Linux: Version 11.2.0.3.0 - Production

NLSRTL Version 11.2.0.3.0 - Production

 

當前僅包括預設的Temp臨時表空間。

 

SQL> select file_name, file_id, tablespace_name from dba_temp_files;

 

FILE_NAME                         FILE_ID TABLESPACE_NAME

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

/u01/app/oradata/ORA11G/datafi          1 TEMP

le/o1_mf_temp_92t73qm8_.tmp              

 

說明:為減少系統對實驗結果影響,筆者建立全新的臨時表空間,透過一系列的典型操作來,監控欄位變化形態來證明實驗結論。

 

2、表空間建立過程

 

首先我們建立臨時表空間temptest。之前,我們檢查磁碟空間空閒情況:

 

[oracle@SimpleLinux ~]$ df -h

Filesystem            Size  Used Avail Use% Mounted on

/dev/sda1              48G   24G   22G  52% /

tmpfs                 6.0G  256M  5.8G   5% /dev/shm

/dev/mapper/VolGrp01-lv1

                      194M  5.6M  179M   4% /voltest01

 

當前/目錄對應大小48G,使用24G,有22G可用空間。下面建立表空間:

 

SQL> create temporary tablespace temptest tempfile size 5G

  2  extent management local uniform size 1m;

 

Tablespace created

 

和建立同樣大小資料表空間相比起來,執行建立臨時表空間語句速度很快。之後檢視磁碟空間情況。

 

[oracle@SimpleLinux ~]$ df -h

Filesystem            Size  Used Avail Use% Mounted on

/dev/sda1              48G   24G   22G  52% /

tmpfs                 6.0G  256M  5.8G   5% /dev/shm

/dev/mapper/VolGrp01-lv1

                      194M  5.6M  179M   4% /voltest01

 

容量上沒有任何變化,如果Oracle建立了5G空間,至少會顯示在磁碟大小上。但是,從Oracle內部註冊體系和檔案系統中,我們都是可以看到臨時檔案的生成。

 

SQL> select file_name, file_id, tablespace_name from dba_temp_files;

 

FILE_NAME                         FILE_ID TABLESPACE_NAME

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

/u01/app/oradata/ORA11G/datafi          1 TEMP

le/o1_mf_temp_92t73qm8_.tmp              

 

/u01/app/oradata/ORA11G/datafi          2 TEMPTEST

le/o1_mf_temptest_9j80859z_.tm           

p                                        

 

[oracle@SimpleLinux datafile]$ ls -l | grep temptest

-rw-r----- 1 oracle oinstall 5368717312 Feb 19 08:55 o1_mf_temptest_9j80859z_.tmp

 

這個是Oracle臨時資料檔案的特性,Oracle臨時檔案和資料檔案不同,建立之後是不直接佔滿空間的。我們都有這樣的經歷,建立一個很大的資料表空間,create/add過程依據不同的系統IO情況,是很消耗時間的。但是臨時檔案不是,一個上十幾G的臨時檔案可以在很快的建立成功。

但是,這個過程其實是“障眼法”。Oracle雖然建立了臨時檔案,檔案系統中也分配顯示大小檔案,但是空間卻沒有真正的分配。這在一些文獻中稱為“稀疏檔案”,檔案架構範圍都在,但是沒有實際寫入過程。TempFile中的allocated,也就與稀疏檔案有關。

注意:這就告訴我們系統部署人員,要注意臨時檔案的這個特性,不要以為磁碟上有很多的空間。

此時,我們觀察檢視dba_temp_free_space,結果如下:

 

SQL> select * from dba_temp_free_space;

 

TABLESPACE_NAME TABLESPACE_SIZE ALLOCATED_SPACE FREE_SPACE

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

TEMP                  481296384       481296384  480247808

TEMPTEST             5368709120         1048576  5367660544

 

Tablespace_size5368709120bytes大小,摺合5G。這就是我們對臨時表空間Temptest定義值

Allocated_space1048576bytes,摺合1M。我們建立了臨時檔案,即使是稀疏結構,在檔案系統上也會有一些後設資料資訊佔據空間。此時的allocated_space=1M也是合理的。

Free_Space5367660544bytes,摺合5119M。如果加入1Mallocated_size),就是5120M,摺合5G,與Tablespace_size對應。

目前資料庫沒有使用temptest進行操作,所以對新的臨時檔案而言,我們可以得到如下結論:

 

ü  新建立的資料檔案是以“稀疏檔案”的方式,雖然建立成功,但是在檔案系統中不是寫入完全,空間佔據是沒有分配的狀態;

ü  新建立檔案情況下:Allocated_space最開始表示後設資料資訊;

ü  新建立檔案情況下:Free_Space表示沒有分配的空間;

 

下面我們使用臨時表進行空間使用。

 

3、臨時表使用情況下實驗

 

臨時表常見的場景是臨時資料表。Oracle臨時表的資料都是儲存在臨時表空間裡面,當向資料表中insert插入資料之後,就會伴隨Temp臨時段的分配。

首先建立出臨時表:

 

 

SQL> create global temporary table t_temp tablespace temptest as select * from t where 1=0;

Table created

 

SQL> select count(*) from t_temp;

  COUNT(*)

----------

         0

 

建立之後,檢視dba_temp_free_space檢視變化。

 

SQL> select * from dba_temp_free_space;

 

TABLESPACE_NAME TABLESPACE_SIZE ALLOCATED_SPACE FREE_SPACE

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

TEMP                  481296384       481296384  480247808

TEMPTEST             5368709120         1048576  5367660544

 

空臨時表資料段,沒有引起臨時表空間分配動作。插入資料,筆者過去準備過一個約2G資料表,插入到臨時表中。

 

SQL> insert into t_temp select * from t;

19360512 rows inserted

 

插入動作比較慢,之後檢查作業系統層面分配情況。

 

[oracle@SimpleLinux datafile]$ df -h

Filesystem            Size  Used Avail Use% Mounted on

/dev/sda1              48G   26G   20G  57% /

tmpfs                 6.0G  256M  5.8G   5% /dev/shm

/dev/mapper/VolGrp01-lv1

                      194M  5.6M  179M   4% /voltest01

 

[oracle@SimpleLinux datafile]$ ls -l | grep temptest

-rw-r----- 1 oracle oinstall 5368717312 Feb 19 09:10 o1_mf_temptest_9j80859z_.tmp

 

注意:檔案系統層面發生了變化,剛建立5G檔案的時候,是沒有額外的變化的。插入2G資料之後,儲存層面發生變化。Used欄位從24G上升到26G這說明:插入過程才進行檔案層面的分配,分配約2G空間給稀疏檔案。

檢視情況如下:

 

SQL> select * from dba_temp_free_space;

 

TABLESPACE_NAME TABLESPACE_SIZE ALLOCATED_SPACE FREE_SPACE

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

TEMP                  481296384       481296384  480247808

TEMPTEST             5368709120      2248146944 3120562176

 

Allocated_space2248146944bytes,合計2144M,進而2.09G空間。Free_Space3120562176bytes,合計2976M,進而2.90625G。兩者合計依然能夠保持5G

Allocated_Space此時顯然包括正在使用臨時表所在空間大小,也就是本次進行檔案擴充的情況。Free_Space是沒有在檔案系統中分配的大小。

 

SQL> select sql_id, tablespace, contents, segtype, extents, blocks from v$tempseg_usage;

 

SQL_ID        TABLESPACE                      CONTENTS  SEGTYPE      EXTENTS     BLOCKS

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

9m7787camwh4m TEMPTEST                        TEMPORARY DATA            2143     274304

 

此時,我們得到結論:當使用Temp空間的時候,需要從檔案系統中請求空間使用。Allocated_space表示正在使用的空間物件,而Free_Space表示沒有分配給稀疏檔案的空間。

下面,我們釋放這部分臨時段物件。

 

4Commit後的資料情況

 

我們將資料commit之後,資料表t_temp臨時段就會自動釋放。後臺程式smon就會回收空間。

 

SQL> commit;

Commit complete

 

SQL> select count(*) from t_temp where rownum<10;

  COUNT(*)

----------

         0

 

SQL> select sql_id, tablespace, contents, segtype, extents, blocks from v$tempseg_usage;

 

SQL_ID        TABLESPACE                      CONTENTS  SEGTYPE      EXTENTS     BLOCKS

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

 

此時,dba_temp_free_space的結果如下:

 

 

SQL> select * from dba_temp_free_space;

 

TABLESPACE_NAME TABLESPACE_SIZE ALLOCATED_SPACE FREE_SPACE

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

TEMP                  481296384       481296384  480247808

TEMPTEST             5368709120      2248146944  5367660544

 

Tablespace_size大小依然為5GAllocated_Space2248146944,合計2144M,約為2.09G注意:這個大小和剛剛我們使用臨時表時候是一樣的!也就是等於在稀疏檔案中分配的大小。

Free_space5367660544,合計5119M。和沒有使用Temptest前是相同的(5G-1M)。表示當前可以使用的臨時空間。

臨時段釋放之後,檔案系統中是不會將分配的空間進行回收的。

 

[oracle@SimpleLinux datafile]$ df -h

Filesystem            Size  Used Avail Use% Mounted on

/dev/sda1              48G   26G   20G  57% /

tmpfs                 6.0G  256M  5.8G   5% /dev/shm

/dev/mapper/VolGrp01-lv1

                      194M  5.6M  179M   4% /voltest01

 

5、結論

 

經過上面的分析,我們可以清晰地看到dba_free_temp_space的欄位含義和Temp情況。

Allocated Space表示檔案系統中給臨時表空間稀疏檔案真實分配的大小,也就是某個時候系統使用這個臨時表空間最大的位置(類似於HWM)。從組成上,這個大小三部分組成:後設資料資訊(1M)、正在使用的臨時段空間、當前沒有使用但是曾經使用過的臨時段空間。

Free_space表示的維度是從實用角度入手,表示當前表空間有多大空間可以使用。包括:當前沒有使用但是曾經使用過的臨時段空間、稀疏檔案中未分配部分。

兩個欄位體積中有一部分屬於共享,是當前沒有使用但是曾經使用過的臨時段空間部分。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31480736/viewspace-2155874/,如需轉載,請註明出處,否則將追究法律責任。

相關文章