ORA-03297错误解决一例(table)

有个表空间中的占用空间较多,但实际数据并不多.使用ALTER TABLE table SHRINK SPACE CASCAD后大部分数据文件可以调整,当试图调整其中一个数据文件尺寸的时候报
ORA-03297: file contains used data beyond requested RESIZE value
说明这个文件不能通过降低hwm来释放空间了。

数据库版本:oracle 9.2.0.1
--找到数据文件对应的文件号
SQL>select file#,name from v$datafile where name like '%BASEINFO.dbf';
5 /data/eucpdb/eucpdb/BASEINFO.dbf

找到文件中最大的块号
SQL>select max(block_id) from dba_extents where file_id=5 ;
1213833

--查看数据库块大小
SQL>show parameter db_block_size
db_block_size integer 8192

计算一下文件中最大使用块占用的位置
SQL>select 1213833*8/1024 from dual;
9483.0703125 M

----根据文件号和块ID找出数据库对象
SQL> col segment_name format a30
SQL> SET LIN 200
SQL> select segment_name,segment_type,tablespace_name,extent_id,bytes,blocks from dba_extents where file_id=5 and block_id='1213833';

SEGMENT_NAME SEGMENT_TYPE TABLESPACE_NAME EXTENT_ID BYTES BLOCKS
------------------------------ ------------------ ------------------------------ ---------- ---------- ----------
REGISTRYINFO TABLE BASEINFO 25 524288 64

SQL>
SQL> ALTER TABLE eucpmanager.REGISTRYINFO SHRINK SPACE CASCADE;  (不确定9i里能用)
表已更改。

--创建一个新的表空间,把block_id比较高的几个表移出表空间

SQL> CREATE SMALLFILE TABLESPACE "BASEINFO_BAK" DATAFILE '/data/eucpdb/eucpdb/baseinfo_bak.dbf' SIZE 100M NOLOGGING EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO;
表空间已创建。

SQL> alter user eucpmanager quota unlimited on BASEINFO_BAK;
用户已更改。

--把block_id比较高的几个表移动到新的表空间

SELECT DISTINCT SEGMENT_NAME FROM DBA_EXTENTS WHERE TABLESPACE_NAME='BASEINFO' AND FILE_ID=5 and block_id>1159985 and segment_type='TABLE' ;

SQL> SELECT distinct 'alter table '|| SEGMENT_NAME||' move tablespace baseinfo_bak; ' FROM DBA_EXTENTS WHERE TABLESPACE_NAME='BASEINFO' AND FILE_ID=5 and block_id>1159985 and segment_type='TABLE' ;

'ALTERTABLE'||SEGMENT_NAME||'MOVETABLESPACEBASEINFO_BAK;'
----------------------------------------------------------------------------------------------------------------------------
alter table ENTERPRISESERVICEINFO move tablespace baseinfo_bak;
alter table REGISTRYFEEDETAILEX move tablespace baseinfo_bak;
alter table ENTERPRISEROUTE move tablespace baseinfo_bak;
alter table REGISTRYAUTHINFO move tablespace baseinfo_bak;
alter table ENTERPRISEBASEINFO move tablespace baseinfo_bak;

SQL> alter table ENTERPRISESERVICEINFO move tablespace baseinfo_bak;
alter table REGISTRYFEEDETAILEX move tablespace baseinfo_bak;
alter table ENTERPRISEROUTE move tablespace baseinfo_bak;
alter table REGISTRYAUTHINFO move tablespace baseinfo_bak;
alter table ENTERPRISEBASEINFO move tablespace baseinfo_bak;
表已更改。

SQL>
表已更改。

SQL>
表已更改。

SQL>
表已更改。

告警日志中会出现下面的内容,索引需要重建

当索引不在同一个表空间时,没有报错信息
Thu Apr 24 14:20:21 2008
Some indexes or index [sub]partitions of table EUCPMANAGER.ENTERPRISEBASEINFO have been marked unusable


把下面的执行结果的语句执行所有重建
SELECT distinct 'alter INDEX '|| SEGMENT_NAME||' REBUILD TABLESPACE BASEINFO_BAK; ' FROM DBA_EXTENTS WHERE TABLESPACE_NAME='BASEINFO' AND FILE_ID=5 and block_id>1159985 and segment_type='INDEX' ;


alter INDEX PK_ENTERPRISEBASEINFO REBUILD TABLESPACE BASEINFO_BAK;
alter INDEX PK_REGISTRYINFO REBUILD TABLESPACE BASEINFO_BAK;
alter INDEX PK_REGISTRYFEEDETAILEX REBUILD TABLESPACE BASEINFO_BAK;
alter INDEX UNI_REGISTRYAUTHINFO REBUILD TABLESPACE BASEINFO_BAK;
alter INDEX UNI_REGISTRYAUTHINFO REBUILD TABLESPACE BASEINFO_BAK;
alter INDEX UNI_REGISTRYAUTHINFO REBUILD TABLESPACE BASEINFO_BAK;
alter INDEX UNI_REGISTRYAUTHINFO REBUILD TABLESPACE BASEINFO_BAK;
alter INDEX UNI_REGISTRYAUTHINFO REBUILD TABLESPACE BASEINFO_BAK;

再次修改数据文件大小
SQL> select max(block_id) from dba_extents where file_id=5 ;

MAX(BLOCK_ID)
-------------
3209

SQL> ALTER DATABASE DATAFILE '/data/eucpdb/eucpdb/BASEINFO.dbf' RESIZE 1000m;
数据库已更改。

数据库文件的空间已经调整成功了
SQL>

--把挪走的表在挪回来
SQL> alter table ENTERPRISESERVICEINFO move tablespace baseinfo;
alter table REGISTRYFEEDETAILEX move tablespace baseinfo;
alter table ENTERPRISEROUTE move tablespace baseinfo;
alter table REGISTRYAUTHINFO move tablespace baseinfo;
alter table ENTERPRISEBASEINFO move tablespace baseinfo;
alter table registryinfo move tablespace baseinfo;
表已更改。
SQL>
表已更改。

--重建索引
SQL>
SQL>
SQL> ALTER INDEX PK_REGISTRYINFO REBUILD TABLESPACE BASEINFO;
ALTER INDEX AK_REGISTRYCODE_REGISTRYINFO REBUILD TABLESPACE BASEINFO;
ALTER INDEX PK_ENTERPRISEBASEINFO REBUILD TABLESPACE BASEINFO;
ALTER INDEX PK_ENTERPRISESERVICEINFO REBUILD TABLESPACE BASEINFO;
ALTER INDEX UNI_REGISTRYAUTHINFO REBUILD TABLESPACE BASEINFO;
ALTER INDEX PK_REGISTRYFEEDETAILEX REBUILD TABLESPACE BASEINFO;
索引已更改。

SQL> SELECT COUNT(*) FROM DBA_SEGMENTS WHERE TABLESPACE_NAME='BASEINFO_BAK' ;

COUNT(*)
----------
0

--已经没有对象在新建的这个表空间了。现在删除掉
SQL> drop tablespace baseinfo_bak;

表空间已删除。

到此调整已经结束了。
其实调整方法有很多,如用imp/exp等

当用下面语句查到的segment_type=index时,只需删除再重建就可以了

select segment_name,segment_type,tablespace_name,extent_id,bytes,blocks from dba_extents where file_id= and block_id=' ';

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/14075938/viewspace-478078/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/14075938/viewspace-478078/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值