Oracle效能優化:收縮臨時表空間

thamsyangsw發表於2014-03-14

http://www.51testing.com/html/09/n-808809.htmlhttp://www.51testing.com/html/09/n-808809.htmlhttp://www.51testing.com/html/09/n-808809.htmlhttp://www.51testing.com/html/09/n-808809.htmlhttp://www.51testing.com/html/09/n-808809.htmlhttp://www.51testing.com/html/09/n-808809.htmlhttp://www.51testing.com/html/09/n-808809.htmlhttp://www.51testing.com/html/09/n-808809.htmlhttp://www.51testing.com/html/09/n-808809.htmlhttp://www.51testing.com/html/09/n-808809.htmlhttp://www.51testing.com/html/09/n-808809.htmlhttp://www.51testing.com/html/09/n-808809.html當排序操作、重建索引等大型操作無法在記憶體中完成時,臨時表空間將為排序提供便利。一般情況下臨時表空間為多個使用者,多個會話所共

  享。不能為會話分批空間配額。臨時表空間耗用過度且在不能自動擴充套件的情形下將收到“ORA-1652:unable to extend temp segment” 錯誤.下面

  描述了過度擴充套件後如何釋放臨時表空間。

  一、臨時表空間何時釋放

  檢索資料的會話遊標關閉時,佔用的臨時空間即被釋放

  資料庫關閉,重啟(一般情況),會話 log off

  二、釋放過大的臨時表空間


1、檢視當前臨時表空間的情況
SQL> select * from v$version where rownum<2;

BANNER
----------------------------------------------------------------
Oracle Database 10g Release 10.2.0.3.0 - 64bit Production
SQL> @temp_sort_segment

+==================================================================================+
| Segment Name            : The segment name is a concatenation of the             |
|                           SEGMENT_FILE (File number of the first extent)         |
|                           and the                                                |
|                           SEGMENT_BLOCK (Block number of the first extent)       |
| Current Users           : Number of active users of the segment                  |
| Total Temp Segment Size : Total size of the temporary segment in MB              |
| Currently Used Bytes    : Bytes allocated to active sorts                        |
| Extent Hits             : Number of times an unused extent was found in the pool |
| Max Size                : Maximum number of MB ever used                         |
| Max Used Size           : Maximum number of MB used by all sorts                 |
| Max Sort Size           : Maximum number of MB used by an individual sort        |
| Free Requests           : Number of requests to deallocate                       |
+==================================================================================+
--&gt此時臨時表空間go_temp中達到了32GB
    Tablespace  Segment Current Currently Pct.   Extent      Max Max Used Max Sort     Free
          Name     Name   Users   Used MB Used     Hits  Size MB  Size MB  Size MB Requests
-------------- -------- ------- --------- ---- -------- -------- -------- -------- --------
TEMP           SYS.0.0        4         4    2    1,864      217      217      217        0
GO_TEMP        SYS.0.0        0         0    0    1,305   32,766      367      367        0
**************          ------- ---------      -------- -------- -------- -------- --------
sum                           4         4         3,169   32,983      584      584        0

SQL> col tbsname format a15
SQL> select s.name tbsname,t.name,(t.bytes/1024/1024) mb,t.status
  2  from v$tablespace s,v$tempfile t                            
  3  where s.ts# = t.ts#;                                        

TBSNAME         NAME                                                       MB STATUS
--------------- -------------------------------------------------- ---------- -------
TEMP            /u02/database/ORADB/temp/tempORADB.dbf                  235 ONLINE
GO_TEMP         /u02/database/ORADB/temp/ORADB_tempORADB.dbf          32767 ONLINE

SQL> @temp_usage2      --&gt此時temp已使用的為4MB,而GO_TEMP未使用

TABLESPACE             MB_TOTAL    MB_USED    MB_FREE
-------------------- ---------- ---------- ----------
GO_TEMP                 32767          0      32767
TEMP                      218          4        214

2、觀察及分析臨時表空間的耗用情況
SQL> select count(*) from big_table;    --&gt開啟另一個session

  COUNT(*)
----------
   2000000

SQL> select * from big_table order by 2,3,4,5,7,8 desc;  --&gt對big_table 實施排序

SQL> alter index pk_stock_tbl_arc rebuild;      --&gt開啟另一個session重建索引

SQL> @temp_sort_segment.sql           --&gt可以看到此時temp表空間耗用達到234MB,go_temp的耗用達到375MB

    Tablespace  Segment Current Currently Pct.   Extent      Max Max Used Max Sort     Free
          Name     Name   Users   Used MB Used     Hits  Size MB  Size MB  Size MB Requests
-------------- -------- ------- --------- ---- -------- -------- -------- -------- --------
TEMP           SYS.0.0        4       234    2    2,077      234      234      230        0
GO_TEMP        SYS.0.0        1       375    1    2,055   32,766      375      375        0
**************          ------- ---------      -------- -------- -------- -------- --------
sum                           5       609         4,132   33,000      609      605        0

SQL> @temp_sort_users.sql  --&gt獲得當前排序的會話

   INST_ID SID_SERIAL Username   OSUSER          SPID         MODULE     PROGRAM       MB_USED TABLESPACE STATEMENTS
---------- ---------- ---------- --------------- ------------ ---------- ---------- ---------- ---------- ----------
         1 1064,9259  SCOTT      oracle          14456        SQL*Plus  oracle@SZD        234 TEMP                4
                                                                         B (TNS V1-
                                                                         V3)

         1 1073,5166  GO_ADMIN   oracle          2480         SQL*Plus  oracle@SZD        375 GO_TEMP           1
                                                                         B (TNS V1-
                                                                         V3)
3、使用resize,縮小臨時表空間,如不能縮小,轉到下一步
SQL> SELECT 'alter database tempfile ''' || a.name || ''' resize ' || b.siz || 'M;'  resize_command
  2  FROM v$tempfile a
  3        ,(SELECT ceil(tmsize.maxblk * bk.value / 1024 / 1024) siz
  4       FROM (SELECT nvl(MAX(segblk#), 128) maxblk
  5            FROM v$sort_usage) tmsize
  6             ,(SELECT VALUE
  7            FROM v$parameter
  8            WHERE NAME = 'db_block_size') bk) b;

RESIZE_COMMAND
----------------------------------------------------------------------------------------
alter database tempfile '/u02/database/ORADB/temp/ORADB_tempORADB.dbf' resize 106M;
alter database tempfile '/u02/database/ORADB/temp/tempORADB.dbf' resize 106M;

--&gt實際上此時佔用32GB的臨時資料檔案已經縮小
alter database tempfile '/u02/database/ORADB/temp/ORADB_tempORADB.dbf' resize 106M;

Database altered.

--&gt為便於演示,此時假定TEMP為過大的臨時表空間且不能釋放
--&gt下面調整表明已使用空間超出了分配的空間
SQL> alter database tempfile '/u02/database/ORADB/temp/tempORADB.dbf' resize 106M; 
alter database tempfile '/u02/database/ORADB/temp/tempORADB.dbf' resize 106M
*
ERROR at line 1:
ORA-03297: file contains used data beyond requested RESIZE value

SQL> select count(*) from v$sort_usage where tablespace='TEMP';   --&gt當前有未釋放的臨時段

  COUNT(*)
----------
         4
        
/**************************************************/
/* Author: Robinson Cheng                         */
/* Blog:  http://blog.csdn.net/robinson_0612     */
/* MSN:   robinson_0612@hotmail.com              */
/* QQ:     645746311                              */
/**************************************************/   
    
4、新建一箇中轉臨時表空間
SQL> create temporary tablespace temp2 tempfile '/u02/database/ORADB/temp/ORADB_temp02.dbf'
  2  size 10m autoextend on;
 
Tablespace created.

--&gt如果此時過大的臨時表空間為預設的臨時表空間,則必須將預設的臨時表空間設定為新的臨時表空間之後
SQL> select property_name,property_value from database_properties
  2  where property_name like 'DEFAULT_TEMP_TABLESPACE';

PROPERTY_NAME                  PROPERTY_VALUE
------------------------------ --------------------
DEFAULT_TEMP_TABLESPACE        TEMP
 
SQL> alter database default temporary tablespace temp2;

Database altered.

5、轉移使用者到中轉臨時表空間
--&gt過大臨時表空間上的那些使用者需要遷移到新建的臨時表空間
--&gt查詢dba_users檢視查詢哪些使用者位於過大的臨時表空間之上
--&gt並使用下面的命令將其切換到新的臨時表空間
alter user temporary tablespace temp2;

6.等到過大臨時表空間上的沒有臨時段被使用,即已經全部釋放即可刪除過大的臨時表空間

SQL> show user;    --&gt由於當前使用者為scott,所以臨時表空間未能釋放
USER is "SCOTT"

SQL> conn / as sysdba   --&gt切換到sysdba
Connected.

SQL> @temp_usage2      --&gt臨時段已經被釋放

TABLESPACE             MB_TOTAL    MB_USED    MB_FREE
-------------------- ---------- ---------- ----------
GO_TEMP                   106          0        106
TEMP                      235          0        235

--&gt如果沒有釋放在可以kill session的情況下kill session.利用前面獲得的sid,serial#來執行(前提是允許該情況發生).
alter system kill session '1064,9259'

7.刪除過大的臨時表空間

SQL> alter tablespace temp tempfile offline;   --&gt先將其離線

Tablespace altered.

SQL> drop tablespace temp including contents and datafiles;   --&gt刪除臨時表空間及相應的檔案

Tablespace dropped.

SQL> select s.name tbsname,t.name,(t.bytes/1024/1024) mb,t.status                   
  2  from v$tablespace s,v$tempfile t                                               
  3  where s.ts# = t.ts#;                                                           
                                                                                    
TBSNAME         NAME                                                       MB STATUS
--------------- -------------------------------------------------- ---------- -------
GO_TEMP       /u02/database/ORADB/temp/ORADB_tempORADB.dbf           106 ONLINE
TEMP2        /u02/database/ORADB/temp/ORADB_temp02.dbf                10 ONLINE

--&gt也可以使用下面的命令來完成僅僅刪除單個檔案
ALTER DATABASE TEMPFILE '/u02/database/ORADB/temp/tempORADB.dbf' DROP INCLUDING DATAFILES; --&gt刪除單個檔案

7、根據需求可以建立原來的臨時表空間並將切換出去使用者切換到此臨時表空間


  三、總結

  1、關注alert_.log檔案中的ORA-1652錯誤並調查什麼原因導致該錯誤。有些時候並不是由於當前的SQL 導致臨時表空間不能擴充套件,很可能由於前一個SQL耗用了99%的臨時表空間,而後一個SQL執行時即出現錯誤。對於此類情況應調查前一SQL並調整避免過多的磁碟排序。

  2、如果基於空間壓力應該關閉臨時表空間的自動擴充套件。因此為臨時表空間設定合理的大小就成了一個問題。個人的解決方案是首先檢查ORA-1652,其次是觀察業務高峰期的峰值。如前面查詢中的欄位Max Size(: Maximum number of MB ever used)的值來預估。如果大師們有更好的建議不妨拍磚。

  3、通過重啟資料庫,臨時表空間所耗用的大小有時候並不能縮小。

  4、在Oracle 11g之前一般是通過建立中轉臨時表空間來達到縮小的目的。不是很完美,因為有些時候臨時段未釋放導致不能刪除臨時表空間及資料檔案。在11g可以直接使用下面的命令來完成:

  alter tablespace temp shrink space;

  alter tablespace temp shrink tempfile '

' keep n ;

  5、系統預設的臨時表空間不能被刪除,因此如果系統預設的臨時表空間過大刪除前應該新置一個系統預設的臨時表空間。

  6、刪除過大臨時表空間前其上的使用者應該先將其設定到中轉臨時表空間,重建後再將其置回原狀態。

  7、減少磁碟排序的首要任務調整SQL,如避免笛卡爾積,為表新增合理的索引等。其次要考慮PGA的值是否設定合理。

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

相關文章