收缩临时表空间

        当排序操作、重建索引等大型操作无法在内存中完成时,临时表空间将为排序提供便利。一般情况下临时表空间为多个用户,多个会话所共 享。不能为会话分批空间配额。临时表空间耗用过度且在不能自动扩展的情形下将收到“ORA-1652:unable to extend temp segment” 错误.下面 描述了过度扩展后如何释放临时表空间。 与之相关的内容参考:

  • Oracle 表空间与数据文件
  • 临时表空间的管理与受损恢复
  • Oracle 彻底 kill session 一、临时表空间何时释放         检索数据的会话游标关闭时,占用的临时空间即被释放         数据库关闭,重启(一般情况),会话 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                       |
+==================================================================================+
-->此时临时表空间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      -->此时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;    -->开启另一个session

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

SQL> select * from big_table order by 2,3,4,5,7,8 desc;  -->对big_table 实施排序

SQL> alter index pk_stock_tbl_arc rebuild;      -->开启另一个session重建索引

SQL> @temp_sort_segment.sql           -->可以看到此时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  -->获得当前排序的会话

   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;

-->实际上此时占用32GB的临时数据文件已经缩小
alter database tempfile '/u02/database/ORADB/temp/ORADB_tempORADB.dbf' resize 106M;

Database altered.

-->为便于演示,此时假定TEMP为过大的临时表空间且不能释放
-->下面调整表明已使用空间超出了分配的空间
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';   -->当前有未释放的临时段

  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.

-->如果此时过大的临时表空间为缺省的临时表空间,则必须将缺省的临时表空间设置为新的临时表空间之后
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、转移用户到中转临时表空间
-->过大临时表空间上的那些用户需要迁移到新建的临时表空间
-->查询dba_users视图查询哪些用户位于过大的临时表空间之上
-->并使用下面的命令将其切换到新的临时表空间
alter user <username> temporary tablespace temp2; 

6.等到过大临时表空间上的没有临时段被使用,即已经全部释放即可删除过大的临时表空间

SQL> show user;    -->由于当前用户为scott,所以临时表空间未能释放
USER is "SCOTT"

SQL> conn / as sysdba   -->切换到sysdba
Connected.

SQL> @temp_usage2      -->临时段已经被释放

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

-->如果没有释放在可以kill session的情况下kill session.利用前面获得的sid,serial#来执行(前提是允许该情况发生).
alter system kill session '1064,9259'

7.删除过大的临时表空间

SQL> alter tablespace temp tempfile offline;   -->先将其脱机

Tablespace altered.

SQL> drop tablespace temp including contents and datafiles;   -->删除临时表空间及相应的文件

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 

-->也可以使用下面的命令来完成仅仅删除单个文件
ALTER DATABASE TEMPFILE '/u02/database/ORADB/temp/tempORADB.dbf' DROP INCLUDING DATAFILES; -->删除单个文件

7、根据需求可以创建原来的临时表空间并将切换出去用户切换到此临时表空间

三、总结 1、关注alert_<sid>.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 '<dir>' keep n <mb/kb>; 5、系统缺省的临时表空间不能被删除,因此如果系统缺省的临时表空间过大删除前应该新置一个系统缺省的临时表空间。 6、删除过大临时表空间前其上的用户应该先将其设定到中转临时表空间,重建后再将其置回原状态。 7、减少磁盘排序的首要任务调整SQL,如避免笛卡尔积,为表添加合理的索引等。其次要考虑PGA的值是否设定合理。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据和云

案发现场:被注入的软件及 ORA-600 16703 灾难的恢复

最近帮助一个客户恢复数据库,遇到了如下这个问题。让我们再一次惊醒于数据安全,如果不做好防范,问题总是会来得猝不及防。

2124
来自专栏乐沙弥的世界

Oracle 12c手工建库(非CDB及CDB创建)

对于Oracle数据库的创建,Oracle除了支持dbca(GUI界面),同时也支持手工方式创建数据库,即使用CREATE DATABASE语句创建数据库。使用...

1301
来自专栏乐沙弥的世界

使用pt-table-checksum校验MySQL主从复制

pt-table-checksum是一个基于MySQL数据库主从架构在线数据一致性校验工具。其工作原理在主库上运行, 通过对同步的表在主从段执行checksum...

1782
来自专栏Java学习123

powerdesigner 15 如何导出sql schema

3177
来自专栏沃趣科技

复制状态与变量记录表 | performance_schema全方位介绍

不知不觉中,performance_schema系列快要接近尾声了,今天将带领大家一起踏上系列第六篇的征程(全系共7个篇章),在这一期里,我们将为大家全面讲解p...

1673
来自专栏杨建荣的学习笔记

关于查看dba_data_files的一个小问题(r7笔记第72天)

今天帮一个朋友看一个pl/sql的问题,他已经钻到一个死胡同里列,可能明眼人一看就知道哪里有问题,但是当局者迷,所以我抽空看了一下这个pl/sql块。 pl/s...

3775
来自专栏「3306 Pai」社区

浅析ProxySQL用户管理

对于读写分离特别重要,保证了同一个事务中所有的语句都会路由到同一组示例,防止出现同一个事务中,上下文数据不一致的情况。例如,在不开启这个属性的情况下:

2621
来自专栏乐沙弥的世界

Oracle 基于用户管理恢复的处理

Oracle支持多种方式来管理数据文件的备份与恢复来保证数据库的可靠与完整。除了使用RMAN工具以及第三方备份与恢复工具之外,基于

532
来自专栏蓝天

MySQL数据导入导出方法与工具mysqlimport

mysqlimport位于mysql/bin目录中,是mysql的一个载入(或者说导入)数据的一个非常有效的工具。这是一个命令行工具。有两个参数以及大量的选项可...

1473
来自专栏乐沙弥的世界

启用用户进程跟踪

仅仅需要标识该会话并为该会话启用跟踪(专用模式为一对一模式,即一个用户进程对应一个服务器进程)

862

扫码关注云+社区