数据文件Resize引起的ORA-03297报错

项目组同事在进行海量数据的POC实验,结果发现数据文件增长过快,超过了规划范围。笔者在数据清空之后,要进行文件缩小操作,释放掉占用的空间。

 

1、  故障现象

 

首先,我们将数据文件大小约为4G,是自动拓展后的结果。

 

 

SQL> select file_name, bytes/1024/1024/1024 from dba_data_files where tablespace_name='NBSMIGIND';

 

FILE_NAME                                                                        BYTES/1024/1024/1024

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

/nbstdata04/oradata/NBSTEST/nbsdata/nbsmigind01.dbf                                        3.91015625

 

 

该文件是表空间nbsmigind下的唯一数据文件,其中的对象段空间只有约500M左右。

 

 

SQL> select count(*),sum(bytes)/1024/1024 from dba_segments where tablespace_name='NBSMIGIND';

 

  COUNT(*) SUM(BYTES)/1024/1024

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

        62                  525

 

 

那么,现在希望将数据文件缩小到2G左右。我们这种场景通常会使用resize命令完成。

 

 

SQL> alter database datafile '/nbstdata04/oradata/NBSTEST/nbsdata/nbsmigind01.dbf' resize 2000m;

 

alter database datafile '/nbstdata04/oradata/NBSTEST/nbsdata/nbsmigind01.dbf' resize 2000m

ORA-03297: 文件包含在请求的 RESIZE 值以外使用的数据

 

 

系统报错ORA-03297。当前段segment所占用的空间明显小于2G,那么为什么不能进行缩减呢?

 

2、问题分析

 

首先,我们可以检查一下这个错误号码的含义。

 

 

[oracle@bspdev ~]$ oerr ora 03297

03297, 00000, "file contains used data beyond requested RESIZE value"

// *Cause:  Some portion of the file in the region to be trimmed is

//          currently in use by a database object

// *Action: Drop or move segments containing extents in this region prior to

//          resizing the file, or choose a resize value such that only free

//          space is in the trimmed.

 

 

从含义上看,好象是说存在这样的对象,它的位置大小要超过希望缩小的位置。这个解释,显然不是针对容量而言,因为对象的总容量显然要小于2G空间。

 

经过研究分析,可以猜到一些端倪。

 

Oracle的段对象是通过一系列的extents组合而成,每个extent内部是连续的数据block。而各个extent之间的关系是分割的,可能分布在多个文件的多个非连续的位置上。

 

一个文件中,存在若干个数据块。文件的块号block_id是针对特定的文件而言的。如果一个文件很大,那么其中最大的block_id自然大,反之则小。

 

调整Oracle对象物理地址的方法,就是将对象的物理位置重新定位整合,到一个新的位置上去。比如,我们在数据表HWM过高的时候,可以使用move或者shrink space命令调节,将数据行重新整合。对索引index对象,我们可以rebuild操作。

 

Oracle数据文件的resize操作,本质上就是将文件的水位线强制下调,从而释放掉不用的空间。那么,如果在下调过程中,虽然中间有很多空闲位置,但存在对象恰好分配在很高的文件位置上,就会引起ORA-03297错误。因为resize命令没有将段对象移动的效用。

 

3、问题解决

 

 

那么,猜想是否成立呢?我们检查一下表空间nbsmigind中段分区的分配情况,按照block_id进行划分。

 

 

SQL> select segment_name, block_id from dba_extents where tablespace_name='NBSMIGIND' order by block_id desc;

 

SEGMENT_NAME                                           BLOCK_ID

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

PK_BSD_TRANS_SEQ_NUMBER                                  483200

PK_BSD_TRANS_SEQ_NUMBER                                  465920

PK_BSD_TRANS_SEQ_NUMBER                                  449536

PK_BSD_TRANS_SEQ_NUMBER                                  433024

IDX_BSD_TRANS_INC_FILE_SEQ                                 177408

PK_BSD_TRANS_SEQ_NUMBER                                  176512

IDX_BSD_TRANS_ERROR_AGTBILLP                              93184

PK_BSD_ITRY_SEQ_NUMBER                                     93056

IDX_BSD_TRANS_ERROR_TRANS_ID                              92928

PK_BSD_TRANS_ERROR_SEQ_NUMBER                            92800

IDX_BSD_FBOX_TRANS_ID                                       92672

IDX_BSD_TRANS_ERROR_AGTBILLP                              92544

IDX_BSD_TAX_TRANS_ID                                        92416

IDX_BSD_TRANS_ERROR_INC_FILE                               92288

(篇幅原因,有省略…..)

 

 

block_id分布上看,可以发现其中的两三个对象的block_id突然性的增加到176000以上和40000以上。而其他的对象block_id大都只分布在90000以下。那么,是不是因为这些对象的“孤悬海外”引起的故障问题呢?

 

问题对象主要是索引段,采用rebuild方式暂时将其转移到其他表空间中,再进行处理。

 

 

SQL> alter index PK_BSD_TRANS_SEQ_NUMBER rebuild tablespace nbsmigtbl;

Index altered

 

SQL> alter index IDX_BSD_TRANS_INC_FILE_SEQ rebuild tablespace nbsmigtbl;

Index altered

 

SQL> alter index PK_BSD_TRANS_SEQ_NUMBER rebuild tablespace nbsmigtbl;

Index altered

 

 

此时,再次进行空间调整,结果为:

 

 

SQL> alter database datafile '/nbstdata04/oradata/NBSTEST/nbsdata/nbsmigind01.dbf' resize 2000m;

 

Database altered

 

 

调整成功,最后别忘了将转移的对象调回来。

 

 

SQL> alter index PK_BSD_TRANS_SEQ_NUMBER rebuild tablespace nbsmigind;

Index altered

 

SQL> alter index IDX_BSD_TRANS_INC_FILE_SEQ rebuild tablespace nbsmigind;

Index altered

 

SQL> alter index PK_BSD_TRANS_SEQ_NUMBER rebuild tablespace nbsmigind;

Index altered

 

 

 

为了防止此类事情再次发生,暂时还是关闭自动拓展功能。

 

 

SQL> alter database datafile '/nbstdata04/oradata/NBSTEST/nbsdata/nbsmigtbl01.dbf' autoextend off;

Database altered

 

 

4、结论

 

从官方角度,对resize缩小文件的场景,是有其他的标准操作。Oracle是建议先将所有对象转移到一个临时位置上,之后缩小resize文件。最后再将对象转移回原表空间。

 

笔者实际上就是占了越界对象少的情况,取巧而为。

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

转载于:http://blog.itpub.net/17203031/viewspace-712019/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值