在以下操作时会占用大量的临时表空间:
1、用户执行imp/exp 导入导出操作时,会使用大量的temporary段
2、用户在rebuild index时
3、执行create table ...... as 语句时
4、移动用户下的数据到别的表空间时
5、大量的排序操作
在10g时,如果临时表空间很大时,想要回收临时表空间的方法是:使用较小的文件创建新的临时表空间,并将这个新的表空间设置为用户的默认临时表空间,然后删除旧的表空间。但是,这有一个缺点,即过程要求删除旧的临时表空间时不能存在活动的排序操作。虽然不是什么大问题,因为等待一段时间后旧的临时表空间总会被活动事务释放,不过这个过程还是比较麻烦。
从Oracle Database11g 版本1 开始,可使用ALTER TABLESPACE SHRINK SPACE 命令收缩临时表空间,也可以使用ALTER TABLESPACE SHRINK TEMPFILE 命令收缩临时文件。对于这两个命令,可以指定可选的KEEP 子句,该子句定义了表空间/临时文件可收缩到的下限。
在Oracle 11g 以前,Temp 表空间使用以后,虽然可以释放,但是表空间的使用量显示还是100%,可以使用如下脚本查看临时表空间每个数据文件实际使用量:
SQL> set pagesize 50
SQL> col tablespace_name for a20
SQL> col "Tempfile name" for a42
SQL> set linesize 300
SQL> Select f.tablespace_name,
2 d.file_name "Tempfile name",
3 round((f.bytes_free + f.bytes_used) / 1024 /1024, 2) "total MB",
4 round(((f.bytes_free + f.bytes_used) -nvl(p.bytes_used, 0)) / 1024 / 1024, 2) "Free MB" ,
5 round(nvl(p.bytes_used, 0)/ 1024 / 1024, 2)"Used MB",
6 round((round(nvl(p.bytes_used, 0)/ 1024 /1024, 2)/round((f.bytes_free + f.bytes_used) / 1024 / 1024, 2))*100,2) as"Used_Rate(%)"
7 from SYS.V_$TEMP_SPACE_HEADER f,DBA_TEMP_FILES d, SYS.V_$TEMP_EXTENT_POOL p
8 where f.tablespace_name(+) = d.tablespace_name
9 and f.file_id(+) = d.file_id
10 and p.file_id(+) =d.file_id;
TABLESPACE_NAME Tempfile name total MB Free MB Used MB Used_Rate(%)
-------------------- ------------------------------------------ ---------- ---------- ---------- ------------
TEMP /u01/oradata/orcl/temp01.dbf 32 31 1 3.13
DBA_TEMP_FREE_SPACE字典视图是在Oracle 11g新增加的视图,用来查看表空间级别的临时空间使用率信息。此信息是从各种现有视图中导出的。
SQL> select tablespace_name,tablespace_size/1024/1024 tablespace_size,
2 allocated_space/1024/1024 allocated_space,
3 free_space/1024/1024 free_space
4 from DBA_TEMP_FREE_SPACE;
TABLESPACE_NAME TABLESPACE_SIZE ALLOCATED_SPACE FREE_SPACE
-------------------- --------------- --------------- ----------
TEMP 32 32 30
为了测试ALTER TABLESPACE SHRINK SPACE以及ALTER TABLESPACE SHRINK TEMPFILE两个命令,现在将些TEMP表空间新增一个datafile,然后将其表空间变大一些。
SQL> ALTER DATABASE TEMPFILE '/u01/oradata/orcl/temp01.dbf' RESIZE 100M;
Database altered.
SQL> ALTER DATABASE TEMPFILE '/u01/oradata/orcl/temp01.dbf' AUTOEXTEND ON NEXT 10M MAXSIZE 500M;
Database altered.
SQL> ALTER TABLESPACE TEMP ADD TEMPFILE '/u01/oradata/orcl/temp02.dbf' SIZE 100M AUTOEXTEND ON NEXT 10M MAXSIZE 500M;
Tablespace altered.
SQL> Select f.tablespace_name,
2 d.file_name "Tempfile name",
3 round((f.bytes_free + f.bytes_used) / 1024 /1024, 2) "total MB",
4 round(((f.bytes_free + f.bytes_used) -nvl(p.bytes_used, 0)) / 1024 / 1024, 2) "Free MB" ,
5 round(nvl(p.bytes_used, 0)/ 1024 / 1024, 2)"Used MB",
6 round((round(nvl(p.bytes_used, 0)/ 1024 /1024, 2)/round((f.bytes_free + f.bytes_used) / 1024 / 1024, 2))*100,2) as"Used_Rate(%)"
7 from SYS.V_$TEMP_SPACE_HEADER f,DBA_TEMP_FILES d, SYS.V_$TEMP_EXTENT_POOL p
8 where f.tablespace_name(+) = d.tablespace_name
9 and f.file_id(+) = d.file_id
10 and p.file_id(+) =d.file_id;
TABLESPACE_NAME Tempfile name total MB Free MB Used MB Used_Rate(%)
-------------------- ------------------------------------------ ---------- ---------- ---------- ------------
TEMP /u01/oradata/orcl/temp01.dbf 100 99 1 1
TEMP /u01/oradata/orcl/temp02.dbf 100 100 0 0
现在TEMP临时表空间下有2个datafile,都是100M。
现在做一些比较大的事务,以使用一些临时表空间。
SQL> create table l5m.test1
2 as select * from dba_objects;
Table created.
SQL> insert into l5m.test1 select * from l5m.test1;
75405 rows created.
SQL> /
150810 rows created.
SQL> /
301620 rows created.
SQL> create index l5m.i_test1 on l5m.test1(owner,object_name,object_id);
Index created.
建立索引会使用大量的临时表空间,现在来看一下临时表空间的使用情况:
SQL> select tablespace_name,tablespace_size/1024/1024 tablespace_size,
2 allocated_space/1024/1024 allocated_space,
3 free_space/1024/1024 free_space
4 from DBA_TEMP_FREE_SPACE;
TABLE TABLESPACE_SIZE ALLOCATED_SPACE FREE_SPACE
----- --------------- --------------- ----------
TEMP 200 36 197
这时如果需要缩小表空间的大小,用alter database tempfile '/u01/oradata/orcl/temp01.dbf' resize 5m,有可能会报ORA-03297的错误,因为临时文件包含的已用数据超过了所需的RESIZE 值。
下面试一下用alter tablespace xxx shrink tempfile和alter tablespace xxx shrink space来收缩表空间,keep选项用来指定压缩时表空间或者数据文件shrink的最小值,如果没有执行该命令,那么表空间或数据文件将被压缩到最小值。
SQL> alter tablespace temp shrink tempfile '/u01/oradata/orcl/temp01.dbf' keep 5m;
Tablespace altered.
SQL> alter tablespace temp shrink tempfile '/u01/oradata/orcl/temp02.dbf' keep 5m;
Tablespace altered.
SQL> alter tablespace temp shrink space;
Tablespace altered.
SQL> select tablespace_name,tablespace_size/1024/1024 tablespace_size,
2 allocated_space/1024/1024 allocated_space,
3 free_space/1024/1024 free_space
4 from DBA_TEMP_FREE_SPACE;
TABLE TABLESPACE_SIZE ALLOCATED_SPACE FREE_SPACE
----- --------------- --------------- ----------
TEMP 3.984375 2.984375 1
通过shrink space,临时表空间现在只有不到4M大小了。Temp 表空间过小对性能是有影响的,所以在shrink时,还是建议使用keep 指定最小值。
另外,在oracle10g时,建立全局临时表只能建立在用户默认的临时表空间下,11g则可以建立在指定的表空间。
下面建立一个temp2临时表空间,在建立全局临时表的时候可以指定tablespace选项。如果不指定tablespace选项,则这个临时表在建立这个用户默认的临时表空间上面。
SQL> CREATE TEMPORARY TABLESPACE temp2 TEMPFILE
2 '/u01/oradata/orcl/temp2_01.dbf' SIZE 10M AUTOEXTEND ON NEXT 10M MAXSIZE 500M
3 EXTENT MANAGEMENT LOCAL UNIFORM SIZE 1M;
CREATE TEMPORARY TABLESPACE temp2 TEMPFILE
Tablespace created.
SQL> select * from database_properties where property_name='DEFAULT_TEMP_TABLESPACE';
PROPERTY_NAME PROPERTY_V DESCRIPTION
------------------------------ ---------- --------------------------------------------------
DEFAULT_TEMP_TABLESPACE TEMP Name of default temporary tablespace
SQL> create global temporary table l5m.gl_temp_table(cname varchar2(10)) on commit delete rows tablespace temp2;
Table created.
SQL> col owner format a5
SQL> col object_name format a15
SQL> col object_type format a10
SQL> col temporary format a3
SQL> col tablespace_name format a5
SQL> select a.owner,a.object_name,a.object_type,a.temporary,b.tablespace_name
2 from dba_objects a,dba_tables b
3 where a.owner=b.owner and a.object_name=b.table_name
4 and a.owner='L5M' and a.object_name='GL_TEMP_TABLE'
5 /
OWNER OBJECT_NAME OBJECT_TYP TEM TABLE
----- --------------- ---------- --- -----
L5M GL_TEMP_TABLE TABLE Y TEMP2