ora-01652无法通过128(在表空间temp中)




ora-01652无法通过128(在表空间temp中)

(2012-02-16 21:15:20)

url: http://blog.sina.com.cn/s/blog_6111c0620100ygpb.html

今天的一个小问题在此顺便一提,有3张表,大致上分别有960000条,960000条,560000条数据,三张表通过where条件进行关联,然后将结果insert到另外一张表中去,执行的过程中很慢,等了十几分钟没反应,好不容易有了反应却报了如下错误:


ora-01652无法通过128(在表空间temp中)_第1张图片

网络上搜索了解决方案,通常做法就是扩大表空间,于是扩了,扩到了8G,还是报错,最终,发现三张表中都没有索引,加了索引后问题很快解决。



ora-01652无法通过128(在表空间temp中)扩展temp段

 2011-03-04 15:37 柠檬绿松

url:http://www.cnblogs.com/songling/archive/2011/03/04/1970965.html

今天提交请求后,提示ORA-01652: 无法通过 128 (在表空间 TEMP 中) 扩展 temp 段。最后通过ALTER DATABASE TEMPFILE '/*/*/db/apps_st/data/tempx01.dbf' RESIZE 7168M;扩展临时表空间来解决

今天提交请求后,提示ORA-01652: 无法通过 128 (在表空间 TEMP 中) 扩展 temp 段。最后通过ALTER DATABASE TEMPFILE '/*/*/db/apps_st/data/tempx01.dbf' RESIZE 7168M;扩展临时表空间来解决。在网上找了些资料,重新学习下临时表空间的知识点,记录在此以免以后忘记。

临时表空间相关知识点总结(转载)

临时表空间的作用:

  临时表空间主要用途是在数据库进行排序运算[如创建索引、order by及group by、distinct、union/intersect/minus/、sort-merge及join、analyze命令]、管理索引[如创建索引、IMP进行数据导入]、访问视图等操作时提供临时的运算空间,当运算完成之后系统会自动清理。

  当临时表空间不足时,表现为运算速度异常的慢,并且临时表空间迅速增长到最大空间(扩展的极限),并且一般不会自动清理了。

  如果临时表空间没有设置为自动扩展,则临时表空间不够时事务执行将会报ora-01652无法扩展临时段的错误,当然解决方法也很简单:1、设置临时数据文件自动扩展,或者2、增大临时表空间。

  临时表空间的相关操作:

  查询默认临时表空间:

  SQL> select * from database_properties where property_name='DEFAULT_TEMP_TABLESPACE';

  PROPERTY_NAME

  ------------------------------

  PROPERTY_VALUE

  --------------------------------------------------------------------------------

  DESCRIPTION

  --------------------------------------------------------------------------------

  DEFAULT_TEMP_TABLESPACE

  TEMP

  Name of default temporary tablespace

  查询临时表空间状态:

  SQL> select tablespace_name,file_name,bytes/1024/1024 file_size,autoextensible from dba_temp_files;

  TABLESPACE_NAME

  ——————————

  FILE_NAME

  ——————————————————————————–

  FILE_SIZE AUT

  ———- —

  TEMP

  /u01/app/oracle/oradata/orcl/temp01.dbf

  100 YES

  扩展临时表空间:

  方法一、增大临时文件大小:

  SQL> alter database tempfile ‘/u01/app/oracle/oradata/orcl/temp01.dbf’ resize100m;

  Database altered.

  方法二、将临时数据文件设为自动扩展:

  SQL> alter database tempfile ‘/u01/app/oracle/oradata/orcl/temp01.dbf’ autoextend on next 5m maxsize unlimited;



解决ora-01652无法通过128(在temp表空间中)

(2008-12-03 13:29:01)

url: http://blog.sina.com.cn/s/blog_4d9ece9a0100caw3.html

作者:西方经济学   

解决ora-01652无法通过128(在temp表空间中)扩展temp段的过程
 
昨天开发人员跟我说,执行一个sql语句后,大约花了10分钟,好不容易有一个结果,但是报了一个ora-01652错误,查阅了oracle的错误代码说明:意思是指temp表空间无法自动扩展temp段。这种问题一般有两种原因:一是临时表空间空间太小,二是不能自动扩展。
分析过程:
    既然是temp表空间有问题,那当然就要从temp表空间说起啦。首先要说明的是temp表空间的作用,temp表空间主要是用作需要排序的操作。
    1.临时表空间是用于在进行排序操作(如大型查询,创建索引和联合查询期间存储临时数据)每个用户都有一个临时表空间。
    2.对于大型操作频繁,(大型查询,大型分类查询,大型统计分析等),应指定单独的临时表空间,以方便管理。
    3.分配用户单独临时表空间,一般是针对大型产品数据库,OLTP数据库,数据库仓库对于小型产品不需要单独制定临时表空间,使用默认临时表空间。
    正常情况下,一个sql执行之后,返回结果后系统会自动收回分配给这个用户的空间。以便可以把此部分空间再分配给其他用户。
好了,既然问题出在临时表空间,那就查看一下临时表空间信息:
    select * from dba_tablespaces;
    select * from dba_temp_files;
    select * from v$tempfile
    通过观察发现,temp表空间只有一个数据文件,大小为4G,不自动扩展。大小为4G,应该说是不能算小啦。这时想到,需要看一看执行的sql语句到底是什么样的,难道它能把这个空间用完(由于系统事务非常少,所以暂不考虑其它用户语句对temp的影响),于是就把那个语句拷贝下拉,研究一番:
SELECT a.TASKID, a.EXAMTYPECODE, a.CONTROLDEPARTMENT, a.DEFAULTRECRUITSPEC, a.ISUPCUNTRYLINE,
  a.ISUPCOLLEGELINE, a.ISMAYJOINRETRIAL, a.JOINRETRIALGIST, a.JOINRETRIALBAK, a.TEMPERSIGN,
  a.RECRUITSTUDENTTYPE, a.MATRICULATEGIST, a.ISNOTICEEXAMINEE, a.AFTERHANDLEDEP, a.TUITION,
  a.KSBH, a.BH, a.XXB, a.BMDDM, a.BMDMC,
  a.BMH, a.XM, a.XMPY, a.ZJLX, a.ZJLXMC,
  a.ZJHM, a.CSRQ, a.MZM, a.MZ, a.XBM,
  a.XB, a.HFM, a.HF, a.ZZMMM, a.ZZMM,
  a.HKSZSSM, a.HKSZSSMC, a.HKSZDXXDZ, a.CSDSSM, a.CSDSSMC,
  a.CSDXXDZ, a.XXGZDW, a.TXDZ, a.YZBM, a.LXDH,
  a.DZXX, a.BYNY, a.XLM, a.XL, a.XWM,
  a.XW, a.KSLYM, a.KSLY, a.KSFSM, a.KSFS,
  a.BKLBM, a.BKLB, a.DASZDWSSM, a.DASZDWSSMC, a.DASZDW,
  a.DASZDWDZ, a.DASZDWYZBM, a.XXGZJL, a.BYXX, a.BYXX1,
  a.BYXX2, a.BYXX3, a.BYXX4, a.JL, a.JTCY,
  a.BYDW, a.BYDWM, a.BYZYDM, a.BYZYMC, '0'||a.DWDM DWDM,
  a.DWMC, a.TJDWDM, a.TJDWMC, a.ZYDM, a.ZYMC,
  a.YXSM, a.YXSMC, a.YJFXM, a.YJFX, a.DSXM,
  a.ZZLLM, a.ZZLLMC, a.WGYM, a.WGYMC, a.YWK1M,
  a.YWK1MC, a.YWK2M, a.YWK2MC, a.YWK3M, a.YWK3MC,
  a.XYJRM, a.XYJR, a.JFBZ, a.ZXBZ, a.BMSJ,
  a.BYXXBZ, a.SFZH, a.BYND, a.KSDW, a.DWSZSSM,
  a.DWSZSSMC, a.ZZLL, a.WGY, a.YWK1, a.YWK2,
  a.YWK3, a.ZF, (NVL(a.fscj,0)) FSCJ, a.LQLBM, a.LQLB,
  a.DXWPDW, a.PG, a.PGBZ, a.BZ, a.WDDWLM,
  a.WDDWL, a.JFLY, a.LQQK, a.BLDW, a.NRXNY,
  a.LQND, a.BZ1, a.BZ2, a.KCH, a.KCDD,
  a.ZWH,a.ZPPATH, a.XH, a.BKZYM, a.BKZY,
  a.XVH,a.DY6FLAG, a.BXYWK1MC, a.BXYWK2MC, a.BXYWK3MC,
  a.QKBZ1, a.QKBZ2, a.QKBZ3, a.QKBZ4, a.QKBZ5,
  a.SSMZLQ, a.KSQK, a.JGM, a.JGS, a.JGSX,
  a.NLDM, a.NL, a.DXZYM, a.DXZY, a.HKSZDSX,
  a.DQDM, a.YDWYB, a.BRTXZ, a.GZDWZ, a.YDWLM,
  a.DWLB, a.BRYB, a.BRDH, a.JTDWM, a.GL,
  a.TSLB, a.TSLBM, a.XXFSM, a.XXFS, a.LQZYM,
  LQZY, ZPCJ, DSXHMH1, DSXHMH2, DSXHMH3,
  a.DSXHMH4, a.SZSSM, a.ZXJH, a.ZXJHBZ, a.BLZGNX,
  BLZG, BLZG1, BLZBZ, JS1MC, JS1CJ,
  a.JS2MC, a.JS2CJ, a.SSMZ, a.SSMZBZ, a.DXWPSSM,
  a.DXWPSS, a.LQXSM, a.LQXSMC, a.LQDSM, a.LQDSXM,
  a.LQYJFXM, a.LQYJFXMC, a.HANDLERESULT, a.XLZSBH, a.XWZSBH,
  a.LQYJFXID, a.XXXS,nvl2(a.reexam , ROUND(GYZF),(zf * ( 1- 0.3))) GYZF,a.GYFS, a.GYCS,
  b.reexam ,a.SPECIALITYNO,a.SPECIALITYNAME,
    (
    SELECT STUDENTTYPE FROM CODE_STUDENTTYPE
    WHERE STUDENTTYPECODE=A.recruitstudenttype ) STUDENTTYPE,
    (SELECT collegename FROM ENROL_COLLEGEINFO)  FSDWMC,
    (SELECT collegecode FROM ENROL_COLLEGEINFO) FSDWDM,
    (CASE WHEN a.handleresult='已录取' THEN '1' ELSE '0' END ) nlq,'' HKSZDM
FROM
  ( SELECT X.*, Y.SPECIALITYNO,Y.SPECIALITYNAME FROM ENROL_EXAMINEE X,    BASE_SPECIALITY Y WHERE X.DEFAULTRECRUITSPEC=Y.SPECSTANDCODE AND x.CONTROLDEPARTMENT IS NOT NULL  ) A
  ,(SELECT taskid,reexam FROM ENROL_EXAMINEE) b WHERE a.taskid=b.taskid
  ORDER BY A.KSBH ASC
  咋一看,真不赖,字段将近一百个,而且原表记录数有15000多条。所以可能真的把临时表空间吃完。于是对涉及到的基表做了一个空间占用情况统计:
SQL> set serveroutput on
SQL> exec show_space('ENROL_EXAMINEE','AUTO');
Total Blocks............................2432                                                                     
Total Bytes.............................19922944                                                             
Unused Blocks...........................0                                                                           
Unused Bytes............................0                                                                           
Last Used Ext FileId....................11                                                                         
Last Used Ext BlockId...................301576                                                                 
Last Used Block.........................128                                                                       
计算一下基表占用19922944字节,大约是19M。还不包括其它的表的字段统计。先将temp数据文件自动扩展。先不管这个sql语句是否优化,做一个执行计划和统计分析,得到如下结果:
PLAN_TABLE_OUTPUT                                                                                                                           
----------------------------------------------------------------------------------------------------                                                                       
| Id  | Operation                                        |  Name                                            | Rows  | Bytes |TempSpc| Cost  |                                                                     
|    0 | SELECT STATEMENT                          |                                                        |  9023K|  9130M|            |  3579K|                                                                     
|    1 |  SORT ORDER BY                              |                                                        |  9023K|  9130M|      19G|  3579K|
|*  2 |    HASH JOIN                                    |                                                        |  9023K|  9130M|            |    439 |                                                                     
|    3 |      TABLE ACCESS FULL                  | ENROL_EXAMINEE                          | 15146 |    310K|            |    231 |                                                                     
|*  4 |      TABLE ACCESS BY INDEX ROWID| ENROL_EXAMINEE                          |    596 |    591K|            |        2 |                                                                     
|    5 |        NESTED LOOPS                          |                                                        |  4171 |  4236K|            |    170 |                 
|    6 |          TABLE ACCESS FULL              | BASE_SPECIALITY                        |      84 |  2016 |            |        2 |             
|*  7 |          INDEX RANGE SCAN                | EXAMINEE_DEFAULTSPEC_INDEX  |    202 |            |            |        1 |                   
PLAN_TABLE_OUTPUT                                                                                                                           
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):                                                       
---------------------------------------------------                                                       
                                                                                                                                                             
    2 - access("SYS_ALIAS_1"."TASKID"="ENROL_EXAMINEE"."TASKID")                               
    4 - filter("SYS_ALIAS_1"."CONTROLDEPARTMENT" IS NOT NULL)                                     
    7 - access("SYS_ALIAS_1"."DEFAULTRECRUITSPEC"="Y"."SPECSTANDCODE")                   
PLAN_TABLE_OUTPUT                                                                                                                           
--------------------------------------------------------------------------------
            filter("SYS_ALIAS_1"."DEFAULTRECRUITSPEC" IS NOT NULL)                                   
                                                                                                                                                             
Note: cpu costing is off                                                                                   
由此可知,临时表空间扩展到19G。这当然会把临时表空间全部吃掉。这时应该从sql语句本身来找问题。
那个sql语句基表大约有15000,而且涉及将近100个字段,最后还有一个非常耗费资源的排序操作。去掉那个order by 查看记录的返回数。
发现返回的记录数为26950729。这对我们数据库的硬件配置来说是一个很大数量级的数据,而且字段有非常多,所以占用既定的temp表空间的之后还不停的扩展,如果没有设置自动扩展,必然导致无法分配temp段。所以那个问题的产生就是必然的啦。现在追究为什么基表只有15000多条,而查询结构却是26950729条,所以怀疑是sql语句中存在cartesian,于是开始从业务需求来分析这个语句, 果然是将最后一个(SELECT taskid,reexam FROM ENROL_EXAMINEE) b 中的基表应该是enrol_task而不是enrol_examinee,因为会产生两个表同个taskid来连接,而每个taskid下有很多学生,这就导致产生了一个庞大的cartesian乘积。最终导致对26950729条记录的排序而使临时表空间用尽。(此时没有自动扩展)将b结果集中ENROL_EXAMINEE用ENROL_TASK来替换,即使还有一个排序,结果也会在很短的时间内返回。
最后需要说明的是:
      1、sql语句完成之后,需要检查记录的准确性。
      2、尽量不要在视图中进行order by ,这是一个非常耗费资源的操作。
写下拉,以存警示!

你可能感兴趣的:(ora-01652无法通过128(在表空间temp中))