ORA-3233表空间相关问题处理(一)

2014-11-24 17:27:06 · 作者: · 浏览: 2

问题现象:


测试库使用如下方式创建索引:


create index IDX_ANA_OFFICE on ANA (OFFICE_CITY, OFFICE_NO)
tablespace IDX
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 128K
next 128K
minextents 1
maxextents unlimited
pctincrease 0
);


报错:ORA-01654: unable to extend index GALT.IDX_OFFICE by 128 in tablespace IDX



改为默认创建:


create index IDX_ANA_PNR_OFFICE on ANA (OFFICE_CITY, OFFICE_NO)
tablespace IDX;



查看SQL是:



storage


(


initial 64K


next 1M


minextents 1


maxextents unlimited


);



问题追查:


1、首先针对1654这个报错,MOS是这样介绍的:


Error: ORA-01654
Text: unable to extend index %s.%s by %s in tablespace %s
-------------------------------------------------------------------------------
Cause: Failed to allocate extent for index segment in tablespace.
Action: Use the ALTER TABLESPACE ADD DATAFILE statement to add one or more
files to the specified tablespace (1)、针对表空间不足的情况,建议使用DBA_FREE_SPACE视图进行查询(Note: 121259.1提供了若干脚本)。
(2)、另外,针对索引的问题,DBA_INDEXES视图则描述了下一个分区(NEXT_EXTENT)的大小,以及所有索引的百分比增长(PCT_INCREASE)。“next_extent”指的是试图分配的区大小(也就是报错中涉及的内容)。

区分配计算:next_extent = next_extent * (1 + (pct_increase/100))


在Concept中描述了为段分配区的算法


How Extents Are Allocated


MOS也提出了若干可能的解决方法:


Possible solutions:
------------------
- Manually coalesce adjacent free extents:
ALTER TABLESPACE COALESCE;
The extents must be adjacent to each other for this to work.


- Add a datafile:
ALTER TABLESPACE ADD DATAFILE ' name>' SIZE ;


- Resize the datafile:
ALTER DATABASE DATAFILE '' RESIZE ;


- Enable autoextend:
ALTER DATABASE DATAFILE '' AUTOEXTEND ON
MAXSIZE UNLIMITED;


- Defragment the Tablespace


- Lower "next_extent" and/or "pct_increase" size:
ALTER STORAGE ( next
pctincrease );
下面这句话我认为是重点:


“这个错误并未指出表空间中是否有足够的空间,仅仅说明Oracle不能找到一个足够大的连续空间用来匹配next extent。


2、另一篇文章“TROUBLESHOOTING GUIDE (TSG) - UNABLE TO CREATE / EXTEND Errors”说明了各种关于“UNABLE TO CREATE / EXTEND”的错误。

“unable to extend"的错误是指当没有足够连续的空间用来分配段的情况。


I. 提出了解决这种错误所需要的信息:


(1)、判断报错表空间中最大的连续空间是多少。


SELECT max(bytes) FROM dba_free_space WHERE tablespace_name = '';


这个SQL返回的是表空间最大允许的连续块大小。(DBA_FREE_SPACE不会返回临时表空间的信息,可以参考“DBA_FREE_SPACE Does not Show Information about Temporary Tablespaces (文档 ID 188610.1)”这篇文章会介绍如何查看临时表空间的连续块大小)。

如果在这个报错之后立即执行上述SQL,则返回的表空间中连续的最大块会小于这个对象正在试图分配的next extent的空间。



(2)、判断NEXT_EXTENT大小。


a) 对于PCT_INCREASE=0的字典管理表空间(DMT)或者使用统一UNIFORM区管理的本地管理表空间(LMT),使用如下SQL:


SELECT NEXT_EXTENT, PCT_INCREASE
FROM DBA_SEGMENTS
WHERE SEGMENT_NAME =
AND SEGMENT_TYPE =
AND OWNER =
AND TABLESPACE_NAME = ;


其中segment_type会展示在错误信息中,可能包含如下类型的segment:


CLUSTER
INDEX
INDEX PARTITION
LOB PARTITION
LOBINDEX
LOBSEGMENT
NESTED TABLE
ROLLBACK
TABLE
TABLE PARTITION
TYPE2 UNDO
TYPE2 UNDO (ORA-1651)


同样地,segment_name可以在错误信息中找到。


b) 对于使用SYSTEM|AUTOALLOCATE区管理的本地管理表空间(LMT)。


没有方法可以查询它的next extent大小。只能查询错误信息,错误信息中的块数乘以表空间的块大小,以此来判断需要创建的区大小。


c) 对于PCT_INCREASE>0的字典管理表空间(DMT)。


SELECT EXTENT_MANAGEMENT FROM DBA_TABLESPACES WHERE TABLESPACE_NAME = '';
使用如下公式计算需要分配的区大小:


extent size = next_extent * (1 + (pct_increase/100)
例如:


next_extent = 512000
pct_increase = 50


next extent size = 512000 * (1 + (50/100)) = 512000 * 1.5 = 768000


注意:


ORA-01650 Rollback Segment


pct_increase仅用于Oracle若干早期版本,后面版本中回滚段的pct_increase默认是0。


ORA-01652 Temporary Segment


临时段与表空间创建的存储默认值相同。


如果查询出现错误,则需要判断这个查询语句是否尽可能地最优以完成排序。


相关阅读



(3)、判断表空间是否包含了AUTOEXTENSIBLE,并已经达到MAXSIZ。


对于数据文件:


SELE