[Oracle] 处理表空间不够用的问题

来源:互联网 发布:耿美网络剧 编辑:程序博客网 时间:2024/04/30 08:24

问题1: 在Java 中遇到ORA-01691: unable to extend lob segment 问题。

原因:表空间不够用了------扩充啊。

解决方法:

1 查看linux 系统是否用足够的硬盘空间:

      命令1: du -sm /xxx/xxx       查看/xxx/xxx 路径的磁盘空间   单位为:M 兆

      命令2:df -h      查看系统的磁盘使用情况。


2 扩充oracle 的表空间

1)查看所有表空间使用情况

select b.file_id 文件ID号,b.tablespace_name 表空间名,b.bytes/1024/1024||'M'字节数,(b.bytes-sum(nvl(a.bytes,0)))/1024/1024||'M' 已使用,sum(nvl(a.bytes,0))/1024/1024||'M' 剩余空间,100 - sum(nvl(a.bytes,0))/(b.bytes)*100 占用百分比from dba_free_space a,dba_data_files bwhere a.file_id=b.file_idgroup by b.tablespace_name,b.file_id,b.bytesorder by b.file_id;

2)查看用户默认的表空间.

select username,default_tablespace from dba_users;

3.查看要扩展的表空间使用的数据文件路径与名字

select * from dba_data_files where tablespace_name like 'yourTableSpaceName%';

4)扩展表空间,表空间扩展有两种方法:增加数据文件;调整当前数据文件的大小或扩展的大小。

(1)增加数据文件

ALTER TABLESPACE TESTTBSADD DATAFILE 'D:/ora/datafile/users.ora' SIZE 500MAUTOEXTEND ONNEXT 50MMAXSIZE 2000M;
增加了一个500M的数据文件,并且可以自动扩展到2G,每次扩展50M。


(2)增加当前数据文件的大小

ALTER DATABASEDATAFILE 'D:/ora/datafile/users.ora'RESIZE 50000M;--或者使用file_idALTER DATABASEDATAFILE 10RESIZE 50000M;

(3)在使用过程中,如果想改变某个数据文件的最大大小,可以

ALTER DATABASEDATAFILE 'D:/ora/datafile/users.ora'AUTOEXTEND ONMAXSIZE 10240M;


本文参考整理自:http://blog.163.com/duanpeng3@126/blog/static/885437352011101792722813/


问题2:数据库表空间满。


1  查看表,索引占用数据库大小情况

select segment_name, sum(bytes)/1024/1024 Mbytese
from user_segments group by segment_name order by Mbytese desc

结果:SYS_LOB0000203753C00006$$  段 占用大。

2  查看SYS_LOB0000203753C00006$$  是那张表的

select db.TABLE_NAME,db.INDEX_NAME, db.column_name
from dba_lobs db
where SEGMENT_NAME='SYS_LOB0000203753C00006$$' ;

结果:EC_PAGE 表

结论:truncate EC_PAGE 表


本文参考整理自:http://www.itpub.net/thread-941913-2-1.html

                                http://soft.zdnet.com.cn/software_zone/2011/0406/2028299.shtml


问题3:临时表空间扩展

oracle 临时表空间的增删改查

1、查看临时表空间 (dba_temp_files视图)(v_$tempfile视图)
select tablespace_name,file_name,bytes/1024/1024 file_size,autoextensible from dba_temp_files;
select status,enabled, name, bytes/1024/1024 file_size from v_$tempfile;--sys用户查看

2、缩小临时表空间大小
alter database tempfile 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\TELEMT\TEMP01.DBF' resize 100M;

3、扩展临时表空间:
方法一、增大临时文件大小:
SQL> alter database tempfile ‘/u01/app/oracle/oradata/orcl/temp01.dbf’ resize 100m;
方法二、将临时数据文件设为自动扩展:
SQL> alter database tempfile ‘/u01/app/oracle/oradata/orcl/temp01.dbf’ autoextend on next 5m maxsize unlimited;
方法三、向临时表空间中添加数据文件:
SQL> alter tablespace temp add tempfile ‘/u01/app/oracle/oradata/orcl/temp02.dbf’ size 100m;

4、创建临时表空间
SQL> create temporary tablespace temp1 tempfile ‘/u01/app/oracle/oradata/orcl/temp11.dbf’ size 10M;

5、更改系统的默认临时表空间:
--查询默认临时表空间
select * from database_properties where property_name='DEFAULT_TEMP_TABLESPACE';
--修改默认临时表空间
alter database default temporary tablespace temp1;
所有用户的默认临时表空间都将切换为新的临时表空间:
select username,temporary_tablespace,default_ from dba_users;
--更改某一用户的临时表空间:
alter user scott temporary tablespace temp;

6、删除临时表空间
删除临时表空间的一个数据文件:
SQL> alter database tempfile ‘/u01/app/oracle/oradata/orcl/temp02.dbf’ drop;
删除临时表空间(彻底删除):
SQL> drop tablespace temp1 including contents and datafiles cascade constraints;

7、查看临时表空间的使用情况(GV_$TEMP_SPACE_HEADER视图必须在sys用户下才能查询)
GV_$TEMP_SPACE_HEADER视图记录了临时表空间的使用大小与未使用的大小
dba_temp_files视图的bytes字段记录的是临时表空间的总大小
SELECT temp_used.tablespace_name,
       total - used as "Free",
       total as "Total",
       round(nvl(total - used, 0) * 100 / total, 3) "Free percent"
  FROM (SELECT tablespace_name, SUM(bytes_used) / 1024 / 1024 used
          FROM GV_$TEMP_SPACE_HEADER
         GROUP BY tablespace_name) temp_used,
       (SELECT tablespace_name, SUM(bytes) / 1024 / 1024 total
          FROM dba_temp_files
         GROUP BY tablespace_name) temp_total
 WHERE temp_used.tablespace_name = temp_total.tablespace_name

8、查找消耗资源比较的sql语句
Select se.username,
       se.sid,
       su.extents,
       su.blocks * to_number(rtrim(p.value)) as Space,
       tablespace,
       segtype,
       sql_text
  from v$sort_usage su, v$parameter p, v$session se, v$sql s
 where p.name = 'db_block_size'
   and su.session_addr = se.saddr
   and s.hash_value = su.sqlhash
   and s.address = su.sqladdr
 order by se.username, se.sid
 
9、查看当前临时表空间使用大小与正在占用临时表空间的sql语句
select sess.SID, segtype, blocks * 8 / 1000 "MB", sql_text
  from v$sort_usage sort, v$session sess, v$sql sql
 where sort.SESSION_ADDR = sess.SADDR
   and sql.ADDRESS = sess.SQL_ADDRESS
 order by blocks desc;

10、临时表空间组介绍
  1)创建临时表空间组:
create temporary tablespace tempts1 tempfile '/home/oracle/temp1_02.dbf' size 2M tablespace group group1;
create temporary tablespace tempts2 tempfile '/home/oracle/temp2_02.dbf' size 2M tablespace group group2;
 
 2)查询临时表空间组:dba_tablespace_groups视图
select * from dba_tablespace_groups;
GROUP_NAME                     TABLESPACE_NAME
------------------------------ ------------------------------
GROUP1                         TEMPTS1
GROUP2                         TEMPTS2

 3)将表空间从一个临时表空间组移动到另外一个临时表空间组:
alter tablespace tempts1 tablespace group GROUP2 ;
select * from dba_tablespace_groups;

GROUP_NAME                     TABLESPACE_NAME
------------------------------ ------------------------------
GROUP2                         TEMPTS1
GROUP2                         TEMPTS2

 4)把临时表空间组指定给用户
alter user scott temporary tablespace GROUP2;

 5)在数据库级设置临时表空间
alter database <db_name> default temporary tablespace GROUP2;

 6)删除临时表空间组 (删除组成临时表空间组的所有临时表空间)
drop tablespace tempts1 including contents and datafiles;
select * from dba_tablespace_groups;
GROUP_NAME                     TABLESPACE_NAME
------------------------------ ------------------------------
GROUP2                         TEMPTS2

drop tablespace tempts2 including contents and datafiles;
select * from dba_tablespace_groups;
GROUP_NAME                     TABLESPACE_NAME

11、对临时表空间进行shrink(11g新增的功能)
--将temp表空间收缩为20M
alter tablespace temp shrink space keep 20M;
--自动将表空间的临时文件缩小到最小可能的大小
ALTER TABLESPACE temp SHRINK TEMPFILE ’/u02/oracle/data/lmtemp02.dbf’;

临时表空间作用
Oracle临时表空间主要用来做查询和存放一些缓冲区数据。临时表空间消耗的主要原因是需要对查询的中间结果进行排序。
重启数据库可以释放临时表空间,如果不能重启实例,而一直保持问题sql语句的执行,temp表空间会一直增长。直到耗尽硬盘空间。
网上有人猜测在磁盘空间的分配上,oracle使用的是贪心算法,如果上次磁盘空间消耗达到1GB,那么临时表空间就是1GB。
也就是说当前临时表空间文件的大小是历史上使用临时表空间最大的大小。

临时表空间的主要作用:
  索引create或rebuild;
  Order by 或 group by;
  Distinct 操作;
  Union 或 intersect 或 minus;
  Sort-merge joins;
  analyze.

转载自:http://www.blogjava.net/japper/archive/2012/06/28/381721.html


问题4:undo表空间

Oracle 的Undo有两种方式: 一是使用undo 表空间,二是使用回滚段. 

 

  我们通过 undo_management 参数来控制使用哪种方式,如果设为auto,就使用UNDO 表空间,这时必须要指定一个UNDO 表空间。 如果设为manual,系统启动后使用rollback segment方式存储undo信息。如果系统没有指定undo_management,那么系统默认以manual方式启动,即使设置了auto方式的参数,这些参数将被忽略。

当实例启动的时候,系统自动选择第一个有效的undo表空间或者是rollback segment,如果没有有效的可用的undo表空间或者是回滚段,系统使用system rollback segment这种情况是不被推荐的,当系统运行在没有undo的情况下,系统会在alert.log中记录一条警告信息。

SQL> show parameter undo

NAME                   TYPE        VALUE

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

undo_management          string      AUTO

undo_retention             integer     900

undo_tablespace            string      UNDOTBS1

参考:Oracle undo 管理

http://blog.csdn.net/tianlesoftware/archive/2009/11/30/4901666.aspx

 

一. UNDO 表空间

下面来看一下undo 的表空间管理。先来查看一下表空间的使用情况:

/* Formatted on 2010/6/23 9:46:58 (QP5 v5.115.810.9015) */

SELECT   a.tablespace_name,

         ROUND (a.total_size) "total_size(MB)",

         ROUND (a.total_size) - ROUND (b.free_size, 3) "used_size(MB)",

         ROUND (b.free_size, 3) "free_size(MB)",

         ROUND (b.free_size / total_size * 100, 2) || '%' free_rate

  FROM   (  SELECT   tablespace_name, SUM (bytes) / 1024 / 1024 total_size

              FROM   dba_data_files

          GROUP BY   tablespace_name) a,

         (  SELECT   tablespace_name, SUM (bytes) / 1024 / 1024 free_size

              FROM   dba_free_space

          GROUP BY   tablespace_name) b

 WHERE   a.tablespace_name = b.tablespace_name(+);

TABLESPACE_NAME      total_size(MB) used_size(MB) free_size(MB) FREE_RATE

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

SYSAUX                   580       545.187        34.813  6%

UNDOTBS1                 90        23.875        66.125 73.47%

DAVE                      20          6.25         13.75  68.75%

USERS                     10         8.375         1.625  16.25%

SYSTEM                   960       951.062         8.938  93%

从结果我们看到UNDO 表空间已经用了23.875M。 我们看一下这使用的23M空间里空闲和非空闲比例:

/* Formatted on 2010/6/23 9:49:53 (QP5 v5.115.810.9015) */

  SELECT   tablespace_name, status, SUM (bytes) / 1024 / 1024 "Bytes(M)"

    FROM   dba_undo_extents

GROUP BY   tablespace_name, status;

TABLESPACE_NAME      STATUS      Bytes(M)

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

UNDOTBS1             UNEXPIRED     9.1875

UNDOTBS1             EXPIRED      13.6875

我们看一下查询的结果,UNEXPIRED EXPIRED 是已使用的undo 表空间,其中expired 说明是已经过期的数据,也就是15分钟(默认情况)以外的数据,以被覆盖,可以认为是空闲的。

在此补充一点知识:

采用UNDO 表空间时,会有一个参数UNDO_RETENTION该参数用来指定undo 记录保存的最长时间,以秒为单位,是个动态参数,完全可以在实例运行时随时修改,通常默认是900 秒,也就是15 分钟。

undo_retention 只是指定undo 数据的过期时间,并不是说,undo 中的数据一定会在undo表空间中保存15 分钟,比如说刚一个新事务开始的时候,如果undo 表空间已经被写满,则新事务的数据会自动覆盖已提交事务的数据,而不管这些数据是否已过期,因此呢,这就又关联回了第一点,当你创建一个自动管理的undo 表空间时,还要注意其空间大小,要尽可能保证undo 表空间有足够的存储空间。

undo_retention 中指定的时间一过,已经提交事务中的数据就立刻无法访问,它只是失效,只要不被别的事务覆盖,它会仍然存在,并可随时被flashback 特性引用。如果你的undo表空间足够大,而数据库又不是那么繁忙,那么其实undo_retention 参数的值并不会影响到你,哪怕你设置成1,只要没有事务去覆盖undo 数据,它就会持续有效。因此呢,这里还是那句话,要注意undo 表空间的大小,保证其有足够的存储空间。

只有在一种情况下,undo 表空间能够确保undo 中的数据在undo_retention 指定时间过期前一定有效,就是为undo 表空间指定Retention Guarantee,指定之后,oracle 对于undo 表空间中未过期的undo 数据不会覆盖,例如:

SQL> Alter tablespace undotbs1 retention guarantee;

 

禁止undo 表空间retention guarantee,例如:

SQL> Alter tablespace undotbs1 retention noguarantee;

总结一下:

UNDO 表空间是会被重用的,只有当事务没结束,或开了retention guarantee,或在undo_retention时间内不能被重用。

在undo_retention规定的时间内,数据都是有效的,过期后都会设为无效,状态被改为Expired,这些回滚段将会被看作Free Space。但是只要数据没有被覆盖就可以使用。如果空间已满,新事务的数据会自动覆盖掉已经提交的事务数据,即使在undo_retention的时间内。除非指定Retention Guarantee模式,才能保证在undo_retention内不被覆盖。

二. UNDO 表空间满了的处理方法

2.1 先模拟UNDO 表空间满的情况


SQL>  alter system set undo_retention=10800; -- 3个小时
系统已更改。
SQL> create undo tablespace undo datafile 'F:/backup/undo.dbf' size 1m ;
表空间已创建。
SQL> alter tablespace undo retention guarantee;
表空间已更改。
SQL> alter system set undo_tablespace=undo;
系统已更改。

SQL> create table DBA(id number);

表已创建。
SQL> begin

  2  for i in 1 .. 100000 loop

  3  insert into dba values(i);

  4  commit;

  5  end loop;

  6  end;

  7  /

begin

*

第 1 行出现错误:

ORA-30036: 无法按 8 扩展段 (在还原表空间 'UNDO' 中)

ORA-06512: 在 line 3

2.2 处理方法

处理方法有两种,一是添加undo 表空间的数据文件,二是切换UNDO tablespace. 这种情况下多用在undo 表空间已经非常大的情况。 

2.2.1 增加数据文件

SQL> ALTER TABLESPACE undo ADD DATAFILE 'F:/backup/undo02.dbf' size 100M reuse;

表空间已更改。

SQL> begin

  2  for i in 1..100000 loop

  3  insert into dba values(1);

  4  commit;

  5  end loop;

  6  end;

  7  /

PL/SQL 过程已成功完成。

2.2.2 切换UNDO 表空间

1、建立新的表空间UNDOTBS2

SQL> CREATE UNDO TABLESPACE UNDOTBS2 DATAFILE 'F:/backup/undo03.dbf' size 100M reuse;

表空间已创建。

2、切换到新建的UNOD表空间上来,操作如下
SQL> alter system set undo_tablespace=UNDOTBS2 scope=both;

系统已更改。

3、将原来的UNDO表空间,置为脱机:
SQL> alter tablespace UNDO offline;

表空间已更改。

4、删除原来的UNDO表空间:
SQL> drop tablespace UNDO including contents AND DATAFILES CASCADE CONSTRAINTS ;

表空间已删除。

如果只是drop tablespace UNDO ,则只会在删除控制文件里的记录,并不会物理删除文件。 

Drop undo表空间的时候必须是在未使用的情况下才能进行。如果undo表空间正在使用(例如事务失败,但是还没有恢复成功),那么drop表空间命令将失败。在drop表空间的时候可以使用including contents。

 

三. UNDO 表空间损坏的恢复方法

一般Undo 表空间损坏的情况下,数据库都已不能正常打开了。启动时都会报类似如下的错误:

ORA-01157: cannot identify/lock data file 12 - see DBWR trace file
ORA-01110: data file 12: '/d01/oramtest/proddata/undo01.dbf'

 要想解决问题,必须重建UNDO 表空间,但是如果不open, 就不能重建创建undo 表空间。 所以可以先用系统默认的undo 表空间:system rollback segment 来启动数据库,再创建UNDO 表空间。

3.1 创建pfile 文件

SQL> create pfile='F:/initorcl.ora' from spfile;

文件已创建。
3.2 修改pfile文件
#*.undo_tablespace='UNDOTBS1'

#*.undo_management='AUTO'

undo_management='MANUAL'

rollback_segments='SYSTEM'

3.3 启动数据库至Mount 状态

SQL> STARTUP MOUNT pfile='F:/initorcl.ora' ;

3.4 offline drop undo 表空间

 SQL> ALTER DATABASE DATAFILE 'D:/app/Administrator/oradata/orcl/UNDOTBS01.DBF' OFFLINE DROP; 

3.5 open 数据库

SQL> ALTER DATABASE OPEN;

3.6 删除旧的undo 表空间

SQL> DROP TABLESPACE UNDOTBS1 INCLUDING CONTENTS;   

注:该命令不会删除物理文件。 要想一起删除物理文件需要 AND DATAFILES CASCADE CONSTRAINTS ;

如:  drop tablespace UNDOTBS1 including contents AND DATAFILES CASCADE CONSTRAINTS ;

3.7 创建新的UNDO 表空间

SQL> create undo tablespace undotbs1 datafile 'D:/app/Administrator/oradata/orcl/UNDOTBS01.DBF' size 100M ;

create undo tablespace undotbs1 datafile 'D:/app/Administrator/oradata/orcl/UNDOTBS01.DBF' size 100M

*

第 1 行出现错误:

ORA-01119: 创建数据库文件 'D:/app/Administrator/oradata/orcl/UNDOTBS01.DBF'时出错

ORA-27038: 所创建的文件已存在

OSD-04010: 指定了 <create> 选项, 但文件已经存在

因为我们之前删除时并没有删除物理文件,所以在建同名文件时就会报错。 我们可以加上REUSE 参数。 只要文件不在使用,就可以重写已经存在的文件。 

SQL> create undo tablespace undotbs1 datafile 'D:/app/Administrator/oradata/orcl/UNDOTBS01.DBF' size 100M reuse;

表空间已创建。

3.8  shutdown 数据库 并将pfile 改回

SQL> select name,issys_modifiable from v$parameter where name='undo_management' or name='rollback_segments';

NAME             ISSYS_MOD

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

rollback_segments    FALSE

undo_management    FALSE

从上面查询的结果,可以知道修改这2个参数必须重启数据,所以还是shutdown 吧。 

SQL> shutdown immediate

3.9 修改pfile 参数

*.undo_tablespace='UNDOTBS1'

*.undo_management='AUTO'

#undo_management='MANUAL'

#rollback_segments='SYSTEM'

3.10 用刚才修改的pfile 启动数据库,并创建spfile

SQL> startup pfile='F:/initorcl.ora' ;

SQL> create spfile from pfile='F:/initorcl.ora';

3.10 再次shutdown,用spfile 启动. 

SQL> shutdown immediate

SQL> startup

一般数据文件损坏的情况也可以采用类似的方法, 先启动到mount, 在将损坏的数据文件offline drop。 在open 数据库,drop 掉损坏的数据文件。 当然这种做法有数据丢失。 能恢复的话,尽量恢复。

转载自:http://blog.csdn.net/tianlesoftware/article/details/5689558

原创粉丝点击