I
have been getting the ORA-1652 errors, and I have no more disk to allocate to
my TEMP tablespace:
Tue Dec 23 07:38:16 2008
ORA-1652: unable to extend temp segment by 128 in tablespace TEMP
Tue Dec 23 07:51:11 2008
ORA-1652: unable to extend temp segment by 128 in tablespace TEMP
Tue Dec 23 07:51:11 2008
ORA-1652: unable to extend temp segment by 128 in tablespace TEMP
I
have waited for SMON to clean out the un-used TEMP segments. How do I remove
the temp segments?
Normally,
you would just add disk to TEMP to avoid the ORA-1652 error, but you can also
wait for SMON to clean-up the TEMP segment.
1. Identify temporary datafile details :
SYS>
select file_name , TABLESPACE_NAME from DBA_TEMP_FILES;
FILE_NAME TABLESPACE_NAME
------------------------------------------------------- ------------------------------
/oracle_backup/test/TEST/temp01.dbf TEMP
2. Check if there is any
space available in temporary tablespace (segment)
SYS>SELECT A.tablespace_name tablespace,
D.mb_total,
SUM (A.used_blocks * D.block_size) / 1024 / 1024 mb_used,
D.mb_total - SUM (A.used_blocks * D.block_size) / 1024 / 1024 mb_free
FROM v$sort_segment A,
(
SELECT B.name, C.block_size, SUM
(C.bytes) / 1024 / 1024 mb_total
FROM v$tablespace B,
v$tempfile C
WHERE B.ts#= C.ts#
GROUP BY B.name, C.block_size
)
D
WHERE A.tablespace_name =
D.name
GROUP by A.tablespace_name, D.mb_total;
TABLESPACE MB_TOTAL
MB_USED MB_FREE
--------------------- ---------------- -------------- -------------
TEMP 54 42 12
(in above case out of 54 MB
only 12 MB is free)
3. Temporary
fix
a) Resize temporary file as
SQL> alter database tempfile ‘/u01/oradata/VIS11i/temp01.dbf’ RESIZE 3072M;
or
b) Add temp datafile to temporary tablespace
as
SQL> alter tablespace
temp add tempfile ‘/u01/oradata/VIS11i/temp02.dbf’
SIZE 1024M;
Root Cause Analysis
1. Identify
temp segment usages per session
Temp segment usage
per session.
SQL> SELECT S.sid || ',' || S.serial# sid_serial,
S.username, S.osuser, P.spid, S.module,
P.program,
SUM (T.blocks) * TBS.block_size / 1024 / 1024 mb_used, T.tablespace,
COUNT(*)
statements
FROM v$sort_usage T, v$session S,
dba_tablespaces TBS, v$process P
WHERE T.session_addr = S.saddr
AND S.paddr = P.addr
AND T.tablespace = TBS.tablespace_name
GROUP
BY S.sid, S.serial#, S.username, S.osuser, P.spid, S.module,
P.program,
TBS.block_size, T.tablespace
ORDER
BY mb_used;
2. Identify
temp segment usages per statement
Temp segment usage per statement
SELECT S.sid || ',' || S.serial# sid_serial, S.username, Q.hash_value, Q.sql_text,
Temp segment usage per statement
SELECT S.sid || ',' || S.serial# sid_serial, S.username, Q.hash_value, Q.sql_text,
T.blocks
* TBS.block_size / 1024 / 1024 mb_used, T.tablespace
FROM v$sort_usage T, v$session S, v$sqlarea Q,
dba_tablespaces TBS
WHERE T.session_addr = S.saddr
AND T.sqladdr = Q.address
AND T.tablespace = TBS.tablespace_name
ORDER
BY mb_used;
Depending on outcome of temp segment usage per session and per statement focus on problematic session/statement.
For Troubleshooting:
1
select
sql_id,max(TEMP_SPACE_ALLOCATED)/(1024*1024*1024) gig
from
DBA_HIST_ACTIVE_SESS_HISTORY
where
sample_time
> sysdate-2 and
TEMP_SPACE_ALLOCATED
> (4*1024*1024*1024)
group
by sql_id order by sql_id;
SQL_ID GIG
---------------------- --------------------
4q9b2jga61n6s
4.94921875
ay1rf7kr04nkd 4.96972656
b6xhw95dpzvvs
4.89355469
This
gives the sql_id and maximum allocated temp space of any queries that ran in
the past two days and exceeded 4 gigabytes of temp space.
2
Oracle
11g has a new view called DBA_TEMP_FREE_SPACE that displays information about
temporary tablespace usage.
TABLESPACE_NAME TABLESPACE_SIZE ALLOCATED_SPACE FREE_SPACE
------------------------------ -------------------------- ---------------------------- -----------------
TEMP 56623104 56623104 55574528
DBA_TEMP_FREE_SPACE
shows bytes which are free and also which are allocated but are available for
reuse
SQL> select
tablespace_name, bytes_used, bytes_free from v$temp_space_header group by
tablespace_name;
TABLESPACE_NAME BYTES_USED BYTES_FREE
------------------------------ ------------------ ------------------
TEMP 56623104 0
V$TEMP_SPACE_HEADER
shows total free bytes (allocated but available for reuse are not shown here)
3
For
Oracle 8 and above, the following query will return all users and their SIDs
which are doing a sort:
SELECT b.tablespace, b.segfile#, b.segblk#, b.blocks, a.sid, a.serial#, a.username, a.osuser, a.status
FROM v$session a,v$sort_usage b WHERE a.saddr = b.session_addr
ORDER BY b.tablespace, b.segfile#, b.segblk#,
b.blocks;
You will receive the following:
File Block
-----------------------
------ --------- ---------- ------- ---------- ------------------ ----------------- -----------
TEMP 4
22 289 15
1966 SCOTT usupport ACTIVE
4
Here
are various scripts which helps in determining who's using the TEMP tablespace.
a)
SQL>select a.inst_id,b.Total_MB, b.Total_MB - round(a.used_blocks*8/1024)
Current_Free_MB,
round(used_blocks*8/1024)
Current_Used_MB, round(max_used_blocks*8/1024)
Max_used_MB
from gv$sort_segment a, (select
round(sum(bytes)/1024/1024) Total_MB from dba_temp_files ) b;
b)
SQL> SELECT a.username, a.sid, a.serial#, a.osuser, b.tablespace, b.blocks, c.sql_text
FROM
gv$session a, gv$tempseg_usage b, gv$sqlarea c
WHERE
a.saddr = b.session_addr
AND
c.address= a.sql_address
AND
c.hash_value = a.sql_hash_value
ORDER
BY b.tablespace, b.blocks;
c)
SQL> select s.sid, s.osuser, s. process, s.sql_id, tmp.segtype, ((tmp.blocks*8)/1024)MB, tmp.tablespace
SQL> select s.sid, s.osuser, s. process, s.sql_id, tmp.segtype, ((tmp.blocks*8)/1024)MB, tmp.tablespace
from
gv$tempseg_usage tmp, gv$session s
where
tmp.session_num=s.serial# and segtype in ('HASH','SORT')
order
by blocks desc;
d)
SQL> select sql_id,sum(blocks) from gv$tempseg_usage group by sql_id order by 2 desc;
No comments:
Post a Comment