首先看temp ts,以下操作會使用temp表空間:
- build index.
- ORDER BY or GROUP BY
- DISTINCT.
- UNION & INTERSECT & MINUS
- Sort-Merge joins.
- Analyze
正常來說,在完成Select語句、create index等一些使用TEMP表空間的排序操作后,Oracle是會自動釋放掉臨時段a的。
但有些有侯我們則會遇到臨時段沒有被釋放,TEMP表空間幾乎滿的狀況,甚至是我們重啟了數據庫仍沒有解決問題
在v$sort_segment字典中,我們可能看到temp的詳細的使用情況,
SQL> desc v$sort_segment
名稱 是否為空? 類型
-------------------------------------- --------------- -------- ------------
TABLESPACE_NAME VARCHAR2(31)
SEGMENT_FILE NUMBER
SEGMENT_BLOCK NUMBER
EXTENT_SIZE NUMBER
CURRENT_USERS NUMBER
TOTAL_EXTENTS NUMBER
TOTAL_BLOCKS NUMBER
USED_EXTENTS NUMBER
USED_BLOCKS NUMBER
FREE_EXTENTS NUMBER
FREE_BLOCKS NUMBER
ADDED_EXTENTS NUMBER
EXTENT_HITS NUMBER
FREED_EXTENTS NUMBER
FREE_REQUESTS NUMBER
MAX_SIZE NUMBER
MAX_BLOCKS NUMBER
MAX_USED_SIZE NUMBER
MAX_USED_BLOCKS NUMBER
MAX_SORT_SIZE NUMBER
MAX_SORT_BLOCKS NUMBER
RELATIVE_FNO NUMBER
而v$sort_usage將會提供目前操作的會話.
SQL> desc v$sort_usage;
名稱 是否為空? 類型
----------------------------------------------------- -------- -------------
USERNAME VARCHAR2(30)
USER VARCHAR2(30)
SESSION_ADDR RAW(4)
SESSION_NUM NUMBER
SQLADDR RAW(4)
SQLHASH NUMBER
TABLESPACE VARCHAR2(31)
CONTENTS VARCHAR2(9)
SEGTYPE VARCHAR2(9)
SEGFILE# NUMBER
SEGBLK# NUMBER
EXTENTS NUMBER
BLOCKS NUMBER
SEGRFNO# NUMBER
sql>select tablespace_name,current_users,total_blocks,used_blocks,free_blocks from v$sort_segment;
TABLESPACE_NAME CURRENT_USERS TOTAL_BLOCKS USED_BLOCKS FREE_BLOCKS
------------------------------ ------------- ------------ ----------- -----------
TEMP 1 13696 13440 256
SQL> /
TABLESPACE_NAME CURRENT_USERS TOTAL_BLOCKS USED_BLOCKS FREE_BLOCKS
------------------------------ ------------- ------------ ----------- -----------
TEMP 1 13696 13696 0
SQL> select username,session_addr,sqladdr,sqlhash,tablespace from v$sort_usage;
USERNAME SESSION_ SQLADDR SQLHASH TABLESPACE
---------- -------- -------- ---------- --------------------
SYS 682102D8 66BE52D8 919180126 TEMP
更多的信息如下:
col tablespace format a20
select se.username,se.sid,se.serial#,su.extents,su.blocks*to_number(rtrim(p.value)) as Space,tablespace,segtype,sql_text from v$sort_usage su,v$parameter p,v$session se,v$sql s
where p.name='db_block_size' and su.session_addr=se.saddr and s.hash_value=su.sqlhash and s.address=su.sqladdr order by se.username,se.sid;
USERNAME SID SERIAL# EXTENTS SPACE TABLESPACE SEGTYPE
---------- ---------- ---------- ---------- ---------- -------------------- ---------
SQL_TEXT
----------------------------------------------------------------
SYS 9 5 107 112197632 TEMP SORT
select * from arbor.server_lookup where rownum<1000000 order by
bill_lname_find
一般來說,排序操作都很快,由於本例是測試,所以temp表空間已經撐爆了,結果還沒有出來,所以可以抓到相應的sql。
而這時候,在另一個會話中,我的查詢語句已經結束了,但是沒有返回任何結果!
metalink推薦下列一些方法:
--重啟實例
重啟實例重啟時,smon進程對臨時段釋放,但是對於生產庫,我們就不能用這種方法了。。。。
如果重啟后sort段沒有被釋放呢?
--修改參數(僅適用於8i及8i以下版本)
SQL>alter tablespace temp increase 1;
SQL>alter tablespace temp increase 0;
--合並碎片(僅適用於字典管理的表空間)
1、首先看誰在用臨時段
SELECT se.username,
sid,
serial#,
sql_address,
machine,
program,
tablespace,
segtype,
contents
FROM v$session se,
v$sort_usage su
WHERE se.saddr=su.session_addr;
USERNAME SID SERIAL# SQL_ADDR MACHINE PROGRAM TABLESPACE
---------- ---------- ---------- -------- -------------------- ---------------------------------------- ----------
SYS 9 3 66CDF6D0 ASPIRE\GZ-ZHAOLEHUAN sqlplus.exe TEMP
2、然后將那些會話Kill掉
Alter system kill session 'sid,serial#';
SQL> alter system kill session '9,3';
系統已更改。
3、整理下表空間
Alter tablespace TEMP coalesce
*
ERROR 位於第 1 行:
ORA-03217: 變更 TEMPORARY TABLESPACE 無效的選項
而事實上,這處方法只能針對字典管理的表空間。對於本地管理的表空間,不是需要整理的。
--診斷事件
select ts#, name from sys.ts$ ;
TS# NAME
---------- --------------------
0 SYSTEM
1 UNDOTBS1
2 TEMP
3 CWMLITE
4 DRSYS
5 EXAMPLE
6 INDX
7 ODM
8 TOOLS
9 USERS
10 XDB
11 CAT_CUST
12 CAT_CUST_IDX
13 zlh_test
14 ZLH_TEST
15 TEMP1
已選擇16行。
SQL>alter session set events 'immediate trace name DROP_SEGMENTS level 4'
說明:level=TS#+ 1
--重建temp
1.創建中轉臨時表空間
create temporary tablespace TEMP1 TEMPFILE 'E:\ORACLE\ORADATA\ORCL9\temp02.DBF' SIZE 512M REUSE AUTOEXTEND ON NEXT 1M MAXSIZE UNLIMITED;
2.改變缺省臨時表空間為剛剛創建的新臨時表空間temp1
alter database default temporary tablespace temp1;
3.刪除原來臨時表空間
drop tablespace temp including contents and datafiles;
4.重新創建臨時表空間
create temporary tablespace TEMP TEMPFILE 'E:\ORACLE\ORADATA\ORCL9\temp01.DBF' SIZE 512M REUSE AUTOEXTEND ON NEXT 1M MAXSIZE UNLIMITED;
5.重置缺省臨時表空間為新建的temp表空間
alter database default temporary tablespace temp;
6.刪除中轉用臨時表空間
drop tablespace temp1 including contents and datafiles;
7.如果有必要,那么重新指定用戶表空間為重建的臨時表空間
alter user arbor temporary tablespace temp;
當然,以上方法,是因為表空間撐爆了,我們才去采用解決辦法,但最根本的原因還是在於disk的sort過多,而disk sort過多也可能是因為
sort area的設置有問題。不過,從memory和disk的空間上來考慮,如果因為disk sort而導致temp的空間增長太快,最應該注意的是到底是什么樣的sql語句要使用這么多的temp空間?
對於sort area設置,不在本文討論的范圍,轉帖網上別人總結的如下:
http://space.itpub.net/?uid-8720638-action-viewspace-itemid-364724
原始出處已不可考。。。。。
排序區域的分配
-專用服務器分配sort area.
排序區域在PGA.
-共享服務器分配sort area.
排序區域在UGA. (UGA在shared pool中分配).
在9i以前的版本,由sort_area_size決定sort area的分配,在9i及以后的版本,
當workarea_size_policy等auto時,由pga_aggregate_target參數決定sort
area的大於,這時的sort area應該是pga總內存的5%.當workarea_size_policy
等manual時,sort area的大小還是於sort_area_size決定.
無論是那個版本,如果sort area開得過小,In-memory Sort率較低,那temp表空間
肯定會增長得很快,如果開得較高,在C/S結構中將會導致內存消耗嚴重(長連接較多).
由於smon進程每隔5分鍾都要對不再使用的sort segment進行回收,如果你不想讓
smon回收sort segment的話,可以使用以下兩個event寫入初始化參數文件,然后
重啟實例,這樣如果你的磁盤排序較多,很快就會漲暴磁盤......
event="10061 trace name context forever, level 10" //禁止加收
event="10269 trace name context forever, level 10" //禁止合並碎片
通過合理地設置pga或sort_area_size,可以消除大部分的dist sort,那其它的disk
sort該如何處理呢?從sort引起的原因來看,索引/分析/異常引起的disk sort應該是
很少的一部分,其它的應該是select中的distinct/union/group by/order by以及
merge sort join啦,那我們如何捕獲這些操作呢?
通常如何有磁盤排序的SQL,它的邏輯讀/物理讀/排序/執行時間等都是比較大的,所以我
們可以對v$sqlarea或v$sql字典進行過濾,經過長期地監控數據庫,相信可以把這些害
群之馬找出來.即然找出這些引起disk sort的SQL后怎么辦呢?當然是對SQL進行分析,
盡而優化之。
#!/bin/sh
ORACLE_SID=miat1cat;
export ORACLE_SID
sqlplus /nolog <<EOF
conn /as sysdba
col sql_text format a81
col disk_reads format 999999.99
col bgets_per format 99999999.99
col "ELAPSD_TIME(s)" format 9999.99
col "cpu_time(s)" format 9999.99
set long 99999999999
set pagesize 9999
select address,hash_value,disk_reads/executions disk_reads,elapsed_time/1000000/executions as "ELAPSD_TIME(s)",
buffer_gets/executions bgets_per,executions,first_load_time as first_time,sql_text
from v$sql
where executions > 0 and (disk_reads/executions > 500 or buffer_gets/executions > 20000) and command_type = 3
order by 3,4;
--select s.disk_reads,s.buffer_gets/s.executions bgets_per,first_load_time,st.sql_text
-- from v$sql s,v$sqltext_with_newlines st
--where s.address=st.address and s.hash_value=st.hash_value
-- and s.disk_reads > 1000 or (s.executions > 0 and s.buffer_gets/s.executions > 50000)
--order by st.piece;
exit
EOF
用以下語句查看表空間的使用情況:
也可以用如下的語句:
------查看所有表空間大小及使用情況
SELECT d.status "Status",
d.tablespace_name "Name",
d.contents "Type",
d.extent_management "Extent Management",
to_char(nvl(a.bytes / 1024 / 1024, 0), '99999999.999') "Total Size (M)",
to_char(nvl(a.bytes - nvl(f.bytes, 0), 0) / 1024 / 1024,
'99999999.999') "Used (M)",
to_char(nvl(nvl(f.bytes, 0), 0) / 1024 / 1024, '99999999.999') "Free (M)",
to_char(nvl((a.bytes - nvl(f.bytes, 0)) / a.bytes * 100, 0),
'990.00') "Used %"
FROM sys.dba_tablespaces d,
(SELECT tablespace_name, SUM(bytes) bytes
FROM dba_data_files
GROUP BY tablespace_name) a,
(SELECT tablespace_name, SUM(bytes) bytes
FROM dba_free_space
GROUP BY tablespace_name) f
WHERE d.tablespace_name = a.tablespace_name(+)
AND d.tablespace_name = f.tablespace_name(+);
Status Name Type Extent Man Total Size (M Used (M) Free (M) Used %
--------- ------------------------------ --------- ---------- ------------- ------------- ------------- -------
ONLINE BMIS_DATA PERMANENT LOCAL 2046.000 1.000 2045.000 0.05
ONLINE CPAS_DATA PERMANENT LOCAL 1023.000 227.500 795.500 22.24
ONLINE INDX PERMANENT LOCAL 255.000 .063 254.938 0.02
ONLINE MOMAX_DATA PERMANENT LOCAL 13296.000 10785.500 2510.500 81.12
ONLINE MOPORTAL_DATA PERMANENT LOCAL 2046.000 733.063 1312.938 35.83
ONLINE MPAS_DATA PERMANENT LOCAL 3069.000 105.000 2964.000 3.42
ONLINE SMAIL_DATA PERMANENT LOCAL 1023.000 7.688 1015.313 0.75
ONLINE SYSTEM PERMANENT LOCAL 1023.000 347.375 675.625 33.96
ONLINE TOOLS PERMANENT LOCAL 1271.000 123.063 1147.938 9.68
ONLINE UNDOTBS1 UNDO LOCAL 9207.000 2355.313 6851.688 25.58
ONLINE USERS PERMANENT LOCAL 255.000 15.625 239.375 6.13
ONLINE TEMP TEMPORARY LOCAL .000 .000 .000 0.00
11 rows selected.