临时表空间重建

本文记录了Oracle数据库中临时表空间无法扩展的问题排查过程,包括错误信息解析、状态检查及最终通过重建临时表空间解决问题的方法。

 OS: suse10
 DBMS:oracle11.1.0.7
 
 查询一个表报temp 表空间相关错误,日志报tempfile 不能扩展

  Current log# 2 seq# 644 mem# 0: /oradata/test02/test02/redo02.log
Tue May 14 14:29:41 2013
ORA-1652: unable to extend temp segment by 128 in tablespace                 TEMP
ORA-1652: unable to extend temp segment by 128 in tablespace                 TEMP
ORA-1652: unable to extend temp segment by 128 in tablespace                 TEMP
Tue May 14 14:29:52 2013
ORA-1652: unable to extend temp segment by 128 in tablespace                 TEMP


oracle@rac1:/opt/oracle/db/diag/rdbms/test02/test02/trace> export ORACLE_SID=test02
oracle@rac1:/opt/oracle/db/diag/rdbms/test02/test02/trace> sqlplus / as sysdba

SQL*Plus: Release 11.1.0.7.0 - Production on Tue May 14 14:31:18 2013

Copyright (c) 1982, 2008, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
With the Partitioning, Real Application Clusters, OLAP, Data Mining
and Real Application Testing options

扩展临时表空间失败

SQL> alter database tempfile 1 autoextend on ;
alter database tempfile 1 autoextend on
*
ERROR at line 1:
ORA-00376: file 201 cannot be read at this time
ORA-01110: data file 201: '/oradata/test02/test02/temp01.dbf'


SQL> host
从错误日志上可能数据文件offline 引起的 
oracle@rac1:/opt/oracle/db/diag/rdbms/test02/test02/trace> oerr ora 376
00376, 00000, "file %s cannot be read at this time"
// *Cause:  attempting to read from a file that is not readable. Most likely
//          the file is offline.
// *Action: Check the state of the file. Bring it online
oracle@rac1:/opt/oracle/db/diag/rdbms/test02/test02/trace> oerr ora 1110
01110, 00000, "data file %s: '%s'"
// *Cause:  Reporting file name for details of another error
// *Action: See associated error message
oracle@rac1:/opt/oracle/db/diag/rdbms/test02/test02/trace> exit
exit

SQL> select file#,status from v$datafile;

     FILE# STATUS
---------- -------
         1 SYSTEM
         2 ONLINE
         3 ONLINE
         4 ONLINE
         5 ONLINE
         6 ONLINE
         7 ONLINE
         8 ONLINE
         9 ONLINE
        10 ONLINE
        11 ONLINE

     FILE# STATUS
---------- -------
        12 ONLINE
        13 ONLINE
        14 ONLINE
        15 ONLINE
        16 ONLINE
        17 ONLINE
        18 ONLINE
        19 ONLINE
        20 ONLINE
        21 ONLINE
        22 ONLINE

     FILE# STATUS
---------- -------
        23 ONLINE
        24 ONLINE
        25 ONLINE
        26 ONLINE
        27 ONLINE
        28 ONLINE
        29 ONLINE
        30 ONLINE
        31 ONLINE
        32 ONLINE
        33 ONLINE

     FILE# STATUS
---------- -------
        34 ONLINE
        35 ONLINE
        36 ONLINE
        37 ONLINE
        38 ONLINE
        39 ONLINE
        40 ONLINE
        41 ONLINE

41 rows selected.

SQL> desc dba_data_files;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 FILE_NAME                                          VARCHAR2(513)
 FILE_ID                                            NUMBER
 TABLESPACE_NAME                                    VARCHAR2(30)
 BYTES                                              NUMBER
 BLOCKS                                             NUMBER
 STATUS                                             VARCHAR2(9)
 RELATIVE_FNO                                       NUMBER
 AUTOEXTENSIBLE                                     VARCHAR2(3)
 MAXBYTES                                           NUMBER
 MAXBLOCKS                                          NUMBER
 INCREMENT_BY                                       NUMBER
 USER_BYTES                                         NUMBER
 USER_BLOCKS                                        NUMBER
 ONLINE_STATUS                                      VARCHAR2(7)

 

SQL> select file_id,status from dba_data_files;

   FILE_ID STATUS
---------- ---------
         4 AVAILABLE
         3 AVAILABLE
         2 AVAILABLE
         1 AVAILABLE
         5 AVAILABLE
         6 AVAILABLE
         7 AVAILABLE
         8 AVAILABLE
         9 AVAILABLE
        10 AVAILABLE
        11 AVAILABLE

   FILE_ID STATUS
---------- ---------
        12 AVAILABLE
        13 AVAILABLE
        14 AVAILABLE
        15 AVAILABLE
        16 AVAILABLE
        17 AVAILABLE
        18 AVAILABLE
        19 AVAILABLE
        20 AVAILABLE
        21 AVAILABLE
        22 AVAILABLE

   FILE_ID STATUS
---------- ---------
        23 AVAILABLE
        24 AVAILABLE
        25 AVAILABLE
        26 AVAILABLE
        27 AVAILABLE
        28 AVAILABLE
        29 AVAILABLE
        30 AVAILABLE
        31 AVAILABLE
        32 AVAILABLE
        33 AVAILABLE

   FILE_ID STATUS
---------- ---------
        34 AVAILABLE
        35 AVAILABLE
        36 AVAILABLE
        37 AVAILABLE
        38 AVAILABLE
        39 AVAILABLE
        40 AVAILABLE
        41 AVAILABLE

41 rows selected.

SQL>
SQL> select * from dba_temp_files;

FILE_NAME
--------------------------------------------------------------------------------
   FILE_ID TABLESPACE_NAME                     BYTES     BLOCKS STATUS
---------- ------------------------------ ---------- ---------- ---------
RELATIVE_FNO AUT   MAXBYTES  MAXBLOCKS INCREMENT_BY USER_BYTES USER_BLOCKS
------------ --- ---------- ---------- ------------ ---------- -----------
/oradata/test02/test02/temp01.dbf
         1 TEMP                                                 AVAILABLE

 

SQL> select status from dba_temp_files;

STATUS
---------
AVAILABLE

SQL> desc  V$DATAFILE;                 
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 FILE#                                              NUMBER
 CREATION_CHANGE#                                   NUMBER
 CREATION_TIME                                      DATE
 TS#                                                NUMBER
 RFILE#                                             NUMBER
 STATUS                                             VARCHAR2(7)
 ENABLED                                            VARCHAR2(10)
 CHECKPOINT_CHANGE#                                 NUMBER
 CHECKPOINT_TIME                                    DATE
 UNRECOVERABLE_CHANGE#                              NUMBER
 UNRECOVERABLE_TIME                                 DATE
 LAST_CHANGE#                                       NUMBER
 LAST_TIME                                          DATE
 OFFLINE_CHANGE#                                    NUMBER
 ONLINE_CHANGE#                                     NUMBER
 ONLINE_TIME                                        DATE
 BYTES                                              NUMBER
 BLOCKS                                             NUMBER
 CREATE_BYTES                                       NUMBER
 BLOCK_SIZE                                         NUMBER
 NAME                                               VARCHAR2(513)
 PLUGGED_IN                                         NUMBER
 BLOCK1_OFFSET                                      NUMBER
 AUX_NAME                                           VARCHAR2(513)
 FIRST_NONLOGGED_SCN                                NUMBER
 FIRST_NONLOGGED_TIME                               DATE
 FOREIGN_DBID                                       NUMBER
 FOREIGN_CREATION_CHANGE#                           NUMBER
 FOREIGN_CREATION_TIME                              DATE
 PLUGGED_READONLY                                   VARCHAR2(3)
 PLUGIN_CHANGE#                                     NUMBER
 PLUGIN_RESETLOGS_CHANGE#                           NUMBER
 PLUGIN_RESETLOGS_TIME                              DATE

SQL> select file#,status from V$DATAFILE;

     FILE# STATUS
---------- -------
         1 SYSTEM
         2 ONLINE
         3 ONLINE
         4 ONLINE
         5 ONLINE
         6 ONLINE
         7 ONLINE
         8 ONLINE
         9 ONLINE
        10 ONLINE
        11 ONLINE

     FILE# STATUS
---------- -------
        12 ONLINE
        13 ONLINE
        14 ONLINE
        15 ONLINE
        16 ONLINE
        17 ONLINE
        18 ONLINE
        19 ONLINE
        20 ONLINE
        21 ONLINE
        22 ONLINE

     FILE# STATUS
---------- -------
        23 ONLINE
        24 ONLINE
        25 ONLINE
        26 ONLINE
        27 ONLINE
        28 ONLINE
        29 ONLINE
        30 ONLINE
        31 ONLINE
        32 ONLINE
        33 ONLINE

     FILE# STATUS
---------- -------
        34 ONLINE
        35 ONLINE
        36 ONLINE
        37 ONLINE
        38 ONLINE
        39 ONLINE
        40 ONLINE
        41 ONLINE

41 rows selected.


没有发现offline 的文件,果断重建临时表空间.业务需要,时间比较紧


SQL> create temporary tablespace temp2 TEMPFILE '/oradata/test02/test02/temp02.dbf'
  2  SIZE 512M REUSE AUTOEXTEND ON NEXT 1M MAXSIZE UNLIMITED;

Tablespace created.

改defualt temp tablespace

SQL> alter database default temporary tablespace temp2;

Database altered.

删除老的temp 表空间
SQL> drop tablespace temp including contents and datafiles;

Tablespace dropped.

增加temp 表空间

alter tablespace temp add tempfile '/oradata/mos5200/temp03.dbf '  size 32000M

 


正常


----The end ------

<think>我们正在解决用户的问题:删除临时表空间时遇到ORA-00959错误(表空间不存在)。根据引用内容,我们得知可能有多种原因,包括表空间确实不存在、名称不匹配(大小写或隐藏字符)、或者存储未挂载等。此外,用户特别提到是临时表空间,所以我们需要考虑临时表空间的特殊性。 解决方案步骤: 1. 确认表空间是否存在:由于是临时表空间,我们需要查询`dba_tablespaces`,同时注意临时表空间在视图中的`CONTENTS`为'TEMPORARY'。 2. 检查是否有隐藏字符:使用转义符或正则表达式检查。 3. 处理依赖关系:临时表空间可能被用户作为默认临时表空间,需要先切换。 4. 安全删除:使用动态SQL避免错误,并清理残留。 注意:在删除临时表空间前,必须确保没有用户将其作为默认临时表空间。如果有,需要先修改用户的默认临时表空间。 步骤详细说明: 步骤1:确认临时表空间是否存在 我们可以通过以下查询来检查: ```sql SELECT tablespace_name FROM dba_tablespaces WHERE UPPER(tablespace_name) = 'JJJGG15' AND contents = 'TEMPORARY'; ``` 如果查询无结果,则说明表空间不存在(可能是已经删除或名称错误)。如果有结果,注意实际名称(大小写敏感)。 步骤2:检查是否有隐藏字符(如空格等) 如果用户输入的表空间名称可能有隐藏字符,可以使用以下查询: ```sql SELECT tablespace_name FROM dba_tablespaces WHERE REGEXP_REPLACE(tablespace_name, '[[:space:]]') = 'JJJGG15' AND contents = 'TEMPORARY'; ``` 步骤3:处理依赖关系 如果表空间存在,我们需要先检查是否有用户使用该临时表空间作为默认临时表空间: ```sql SELECT username FROM dba_users WHERE temporary_tablespace = '实际的表空间名(注意大小写)'; ``` 如果有,需要将这些用户的默认临时表空间切换到其他临时表空间(如TEMP): ```sql ALTER USER <用户名> TEMPORARY TABLESPACE TEMP; ``` 步骤4:删除临时表空间 如果确认表空间存在且没有用户依赖,可以尝试删除。但为了避免错误,我们可以使用动态SQL并捕获异常(ORA-00959): ```sql BEGIN EXECUTE IMMEDIATE 'DROP TABLESPACE JJJGG15 INCLUDING CONTENTS AND DATAFILES CASCADE CONSTRAINTS'; EXCEPTION WHEN OTHERS THEN IF SQLCODE = -959 THEN DBMS_OUTPUT.PUT_LINE('表空间不存在,无需删除'); ELSE RAISE; END IF; END; / ``` 步骤5:清理残留(如果必要) 如果删除后仍有残留文件,可以手动删除操作系统上的数据文件(在确认无其他用途后)。 注意:临时表空间的数据文件通常不会被立即删除,除非使用了`INCLUDING CONTENTS AND DATAFILES`。但有时可能因为权限或文件被占用而残留,需要手动处理。 另外,引用[1]中提到存储未挂载可能导致表空间文件不可用,从而在启动时出现错误。但这里我们删除表空间时,如果数据文件所在的存储未挂载,删除操作可能会失败(报其他错误)。因此,确保存储已挂载。 引用[2]中提到了临时表空间的迁移,其中使用了`ALTER TABLESPACE ... ADD TEMPFILE`,这提醒我们在删除临时表空间前,确保有替代的临时表空间供用户使用。 因此,我们总结如下: 完整解决方案: 1. 确认临时表空间是否存在(注意大小写和隐藏字符): ```sql -- 查询所有临时表空间,看是否有匹配的(忽略大小写) SELECT tablespace_name FROM dba_tablespaces WHERE UPPER(tablespace_name) = UPPER('JJJGG15') AND contents = 'TEMPORARY'; ``` 2. 如果存在,先解除依赖(修改用户的默认临时表空间): ```sql -- 查询依赖的用户 SELECT username FROM dba_users WHERE temporary_tablespace = '查询到的实际表空间名(注意大小写)'; -- 逐个修改用户 ALTER USER <用户名> TEMPORARY TABLESPACE <新的临时表空间>; ``` 3. 删除临时表空间: ```sql -- 使用动态SQL删除,避免报错 BEGIN EXECUTE IMMEDIATE 'DROP TABLESPACE ' || '实际的表空间名(注意用双引号括住如果大小写敏感)' || ' INCLUDING CONTENTS AND DATAFILES'; EXCEPTION WHEN OTHERS THEN IF SQLCODE = -959 THEN DBMS_OUTPUT.PUT_LINE('表空间不存在,无需删除'); ELSE RAISE; END IF; END; / ``` 4. 如果存储未挂载导致无法访问数据文件,需要先挂载存储,然后再执行删除。 注意:如果表空间名称是大小写敏感的,在创建时使用了双引号,那么在删除时也需要使用双引号,例如: ```sql DROP TABLESPACE "JjJgG15" ...; ``` 因此,在动态SQL中,如果查询到的表空间名是小写或混合大小写,我们需要用双引号括起来。 示例:假设实际表空间名为'JjJgG15' ```sql EXECUTE IMMEDIATE 'DROP TABLESPACE "' || 'JjJgG15' || '" INCLUDING CONTENTS AND DATAFILES'; ``` 但是,如果表空间名在数据字典中是大写的,则不需要双引号。 通常,如果没有使用双引号创建,那么表空间名在数据字典中都是大写的。因此,我们一般使用大写名称即可。 最后,生成相关问题: §§相关问题§§ 1. 如何修改Oracle用户的默认临时表空间? 2. 临时表空间的数据文件无法删除怎么办? 3. 如何重建Oracle的临时表空间?</think>### 解决 Oracle 删除临时表空间提示 ORA-00959 错误 #### 🔍 问题分析 删除临时表空间时遇到 ORA-00959 错误,通常由以下原因导致: 1. **临时表空间已被删除**(物理或逻辑删除但残留元数据) 2. **名称大小写不匹配**(Oracle 默认大写存储对象名) 3. **存在隐藏字符**(如空格、不可见字符) 4. **存储未挂载**(引用[1]场景,表空间文件不可访问) 5. **临时表空间组依赖**(临时表空间可能属于组) #### ✅ 完整解决步骤 ##### 1. 验证临时表空间存在性 ```sql -- 精确匹配(注意大写) SELECT tablespace_name, status, contents FROM dba_tablespaces WHERE tablespace_name = 'JJJGG15' AND contents = 'TEMPORARY'; -- 确保是临时表空间 -- 模糊匹配(解决隐藏字符) SELECT tablespace_name FROM dba_tablespaces WHERE REGEXP_LIKE(tablespace_name, 'JJJGG15[[:space:]]*') AND contents = 'TEMPORARY'; ``` > 📌 若无结果,说明表空间**不存在**;若存在注意**实际大小写** ##### 2. 检查存储挂载状态(引用[1]场景) ```sql -- 检查数据文件状态 SELECT file_name, status FROM dba_temp_files WHERE tablespace_name = 'JJJGG15'; ``` > ⚠️ 若返回 `MISSING` 状态,需挂载存储设备后再操作 ##### 3. 处理依赖关系 ```sql -- 检查依赖用户 SELECT username FROM dba_users WHERE temporary_tablespace = 'JJJGG15'; -- 修改用户默认临时表空间 ALTER USER <用户名> TEMPORARY TABLESPACE TEMP; ``` ##### 4. 安全删除临时表空间 ```sql -- 使用动态SQL避免错误 BEGIN EXECUTE IMMEDIATE 'DROP TABLESPACE JJJGG15 INCLUDING CONTENTS AND DATAFILES'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -959 THEN -- 非ORA-00959错误抛出 RAISE; END IF; DBMS_OUTPUT.PUT_LINE('表空间不存在,无需删除'); END; / ``` ##### 5. 清理残留元数据(可选) ```sql -- 强制清理数据字典 EXEC DBMS_SPACE_ADMIN.TABLESPACE_REMOVE('JJJGG15'); -- 清理回收站 PURGE TABLESPACE JJJGG15; ``` #### 💡 关键注意事项 1. **名称规范** Oracle 默认以**大写存储对象名**,删除时需保持一致: ```sql DROP TABLESPACE "JJJGG15"; -- 创建时用引号需保留 ``` 2. **临时文件处理** 临时表空间使用 `TEMPFILE` 而非 `DATAFILE`: ```sql SELECT file_name FROM dba_temp_files; ``` 3. **表空间组检查** 若属于表空间组需先解除: ```sql ALTER TABLESPACE GROUP <组名> DROP TABLESPACE JJJGG15; ``` 4. **操作系统验证** 手动检查临时文件路径: ```bash # Linux示例 ls -l $ORACLE_BASE/oradata/*/*temp*.dbf ``` #### 🌟 最佳实践 ```sql -- 安全删除临时表空间过程 DECLARE v_tablespace VARCHAR2(30) := 'JJJGG15'; v_exists NUMBER; BEGIN -- 检查存在性 SELECT COUNT(*) INTO v_exists FROM dba_tablespaces WHERE tablespace_name = v_tablespace AND contents = 'TEMPORARY'; IF v_exists > 0 THEN -- 解除用户依赖 FOR user_rec IN ( SELECT username FROM dba_users WHERE temporary_tablespace = v_tablespace ) LOOP EXECUTE IMMEDIATE 'ALTER USER ' || user_rec.username || ' TEMPORARY TABLESPACE TEMP'; END LOOP; -- 执行删除 EXECUTE IMMEDIATE 'DROP TABLESPACE ' || v_tablespace || ' INCLUDING CONTENTS AND DATAFILES'; END IF; END; / ``` > 通过以上步骤可彻底解决临时表空间的 ORA-00959 错误,确保操作安全可靠[^1][^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值