ORA-03297 When Resizing a Datafile by Finding the Table Highwatermark

APPLIES TO:

Oracle Database - Enterprise Edition - Version 8.1.5.0 and later
Information in this document applies to any platform.



GOAL

In a number of cases it is desired to shrink an oversized datafile. The challenge is then up to find to which size the datafile can be shrunk? Using the trial and error approach will likely give:

SQL> alter database datafile '/oradata/v112/users01.dbf' resize 117248K;
alter database datafile '/oradata/v112/users01.dbf' resize 117248K
*
ERROR at line 1:
ORA-03297: file contains used data beyond requested RESIZE value


The error is due to fact that there are allocated extents between the size to resize/shrink to and the end-of-file (might be space management blocks, so not necessary belonging to a segment).

SOLUTION

Two options do exist to find the highwater mark of a datafile:

- checking backwards for free space at end of file (proven to be the fastest)

- check highest allocated extent in datafile (it might be that space management blocks are above last allocated extend)

 

In case there are blocking segments for resizing/shrinking the datafiles the attached SQL-script: show_segment_above_size.sql will show the segments which do have extents above the desired size.

The script will show the 'blocking' segments for the resize, no block_id/location is shown due to fact that whole segments needs to be 'moved/cleaned up/...' in order to free up the extents thus enabling the desized resize.

 

1) checking backwards for free space at end of file

Due to added functionality (different blocksizes for tablespaces) the script has been split into:

- Oracle version 9 and higher

- Oracle version 8 and lower

REM Script is meant for Oracle version 9 and higher
REM -----------------------------------------------

set serveroutput on
exec dbms_output.enable(1000000);

declare

cursor c_dbfile is
select f.tablespace_name,f.file_name,f.file_id,f.blocks,t.block_size
,decode(t.allocation_type,'UNIFORM',t.initial_extent/t.block_size,0) uni_extent
,decode(t.allocation_type,'UNIFORM',(128+(t.initial_extent/t.block_size)),128) file_min_size
from dba_data_files f,
dba_tablespaces t
where f.tablespace_name = t.tablespace_name
and t.status = 'ONLINE'
order by f.tablespace_name,f.file_id;

cursor c_freespace(v_file_id in number) is
select block_id, block_id+blocks max_block
from dba_free_space
where file_id = v_file_id
order by block_id desc;

/* variables to check settings/values */
dummy number;
checkval varchar2(10);
block_correction number;

/* running variable to show (possible) end-of-file */
file_min_block number;

/* variables to check if recycle_bin is on and if extent as checked is in ... */
recycle_bin boolean:=false;
extent_in_recycle_bin boolean;

/* exception handler needed for non-existing tables note:344940.1 */
sqlstr varchar2(100);
table_does_not_exist exception;
pragma exception_init(table_does_not_exist,-942);

/* variable to spot space wastage in datafile of uniform tablespace */
space_wastage number;

begin

/* recyclebin is present in Oracle 10.2 and higher and might contain extent as checked */
begin
select value into checkval from v$parameter where name = 'recyclebin';
if checkval = 'on'
then
recycle_bin := true;
end if;
exception
when no_data_found
then
recycle_bin := false;
end;

/* main loop */
for c_file in c_dbfile
loop
/* initialization of loop variables */
dummy :=0;
extent_in_recycle_bin := false;
file_min_block := c_file.blocks;

begin

space_wastage:=0; /* reset for every file check */

<<check_free>>

for c_free in c_freespace(c_file.file_id)
loop
/* if blocks is an uneven value there is a need to correct 
with -1 to compare with end-of-file which is even */
block_correction := (0-mod(c_free.max_block,2));
if file_min_block = c_free.max_block+block_correction
then

/* free extent is at end so file can be resized */
file_min_block := c_free.block_id;

/* Uniform sized tablespace check if space at end of file
is less then uniform extent size */
elsif (c_file.uni_extent !=0) and ((c_file.blocks - c_free.max_block) < c_file.uni_extent) 
then

/* uniform tablespace which has a wastage of space in datafile 
due to fact that space at end of file is smaller than uniform extent size */

space_wastage:=c_file.blocks - c_free.max_block;
file_min_block := c_free.block_id;

else
/* no more free extent at end of file, file cannot be further resized */
exit check_free;
end if;
end loop;
end;

/* check if file can be resized, minimal size of file 128 {+ initial_extent} blocks */
if (file_min_block = c_file.blocks) or (c_file.blocks <= c_file.file_min_size)
then

dbms_output.put_line('Tablespace: '||c_file.tablespace_name||' Datafile: '||c_file.file_name);
dbms_output.put_line('cannot be resized no free extents found');
dbms_output.put_line('.');

else

/* file needs minimal no of blocks which does vary over versions, 
using safe value of 128 {+ initial_extent} */
if file_min_block < c_file.file_min_size
then
file_min_block := c_file.file_min_size;
end if;


dbms_output.put_line('Tablespace: '||c_file.tablespace_name||' Datafile: '||c_file.file_name);
dbms_output.put_line('current size: '||(c_file.blocks*c_file.block_size)/1024||'K'||' can be resized to: '||round((file_min_block*c_file.block_size)/1024)||'K (reduction of: '||round(((c_file.blocks-file_min_block)/c_file.blocks)*100,2)||' %)');


/* below is only true if recyclebin is on */
if recycle_bin
then
begin
sqlstr:='select distinct 1 from recyclebin$ where file#='||c_file.file_id;
execute immediate sqlstr into dummy;

if dummy > 0
then

dbms_output.put_line('Extents found in recyclebin for above file/tablespace');
dbms_output.put_line('Implying that purge of recyclebin might be needed in order to resize');
dbms_output.put_line('SQL> purge tablespace '||c_file.tablespace_name||';');
end if;
exception
when no_data_found
then null;
when table_does_not_exist
then null;
end;
end if;
dbms_output.put_line('SQL> alter database datafile '''||c_file.file_name||''' resize '||round((file_min_block*c_file.block_size)/1024)||'K;');

if space_wastage!=0
then
dbms_output.put_line('Datafile belongs to uniform sized tablespace and is not optimally sized.');
dbms_output.put_line('Size of datafile is not a multiple of NN*uniform_extent_size + overhead');
dbms_output.put_line('Space that cannot be used (space wastage): '||round((space_wastage*c_file.block_size)/1024)||'K');
dbms_output.put_line('For optimal usage of space in file either resize OR increase to: '||round(((c_file.blocks+(c_file.uni_extent-space_wastage))*c_file.block_size)/1024)||'K');
end if;

dbms_output.put_line('.');

end if;

end loop;

end;
/


*) The absolute minimum size of a datafile varies per version/tablespace type. 
     In above case 128*8K (=1Mb) is used, but this might be too low.

Example output for Oracle version 9 and higher:

Tablespace: TEST Datafile: +DG1/test01.dbf
current size: 11264K can be resized to: 4096K (reduction of: 63.64 %)
Extents found in recyclebin for above file/tablespace
Implying that purge of recyclebin might be needed in order to resize
SQL> purge tablespace TEST;
SQL> alter database datafile '+DG1/test01.dbf' resize 4096K;
Datafile belongs to uniform sized tablespace and is not optimally sized.
Size of datafile is not a multiple of NN*uniform_extent_size + overhead
Space that cannot be used (space wastage): 1024K
For optimal usage of space in file either resize OR increase to: 13312K
.
Tablespace: TEST Datafile: +DG2/test02.dbf
current size: 10240K can be resized to: 4096K (reduction of: 60 %)
SQL> alter database datafile '+DG2/test02.dbf' resize 4096K;
.
Tablespace: UNDOTBS1 Datafile: /oradata/v1122/undotbs01.dbf
current size: 660480K can be resized to: 103424K (reduction of: 84.34 %)
SQL> alter database datafile '/oradata/v1122/undotbs01.dbf' resize 103424K;
.
Tablespace: USERS Datafile: /oradata/v1122/users01.dbf
cannot be resized no free extents found


 

REM Script is meant for Oracle version 8 and lower
REM ----------------------------------------------

set serveroutput on
exec dbms_output.enable(1000000);

declare

cursor c_dbfile is
select f.tablespace_name,f.file_name,f.file_id,f.blocks
from dba_data_files f,
dba_tablespaces t
where f.tablespace_name = t.tablespace_name
and t.status = 'ONLINE'
order by f.tablespace_name,f.file_id;

cursor c_freespace(v_file_id in number) is
select block_id, block_id+blocks max_block
from dba_free_space
where file_id = v_file_id
order by block_id desc;

/* variables to check settings/values */
block_correction number;
block_size number;

/* running variable to show (possible) end-of-file */
file_min_block number;

begin

select value into block_size from v$parameter where name='db_block_size';

/* main loop */
for c_file in c_dbfile
loop
/* initialization of loop variables */
file_min_block := c_file.blocks;

begin

<<check_free 

for c_free in c_freespace(c_file.file_id)
loop
/* if blocks is an uneven value there is a need to correct with -1 to compare with end-of-file which is even */
block_correction := (0-mod(c_free.max_block,2));
if file_min_block = c_free.max_block+block_correction
then

/* free extent is at end so file can be resized */
file_min_block := c_free.block_id;

else
/* no more free extent at end of file, file cannot be further resized */
exit check_free;
end if;
end loop;
end;

/* check if file can be resized, minimal size of file 16 blocks */
if (file_min_block = c_file.blocks) or (c_file.blocks <= 16)
then

dbms_output.put_line('Tablespace: '||c_file.tablespace_name||' Datafile: '||c_file.file_name);
dbms_output.put_line('cannot be resized no free extents found');
dbms_output.put_line('.');

else

/* file needs minimal no of blocks which does vary over versions */
if file_min_block < 16
then
file_min_block := 16;
end if;

dbms_output.put_line('Tablespace: '||c_file.tablespace_name||' Datafile: '||c_file.file_name);
dbms_output.put_line('current size: '||(c_file.blocks*block_size)/1024||'K'||' can be resized to: '||round((file_min_block*block_size)/1024)||'K (reduction of: '||round(((c_file.blocks-file_min_block)/c_file.blocks)*100,2)||' %)');
dbms_output.put_line('SQL> alter database datafile '''||c_file.file_name||''' resize '||round((file_min_block*block_size)/1024)||'K;');
dbms_output.put_line('.');

end if;

end loop;

end;
/

Example output for Oracle version 8 and lower:

Tablespace: SYSTEM Datafile:
/refresh/64bit/app/oracle/oradata/REF817U6/system01.dbf
cannot be resized no free extents found
.
Tablespace: TEMP Datafile: /refresh/64bit/app/oracle/oradata/REF817U6/temp01.dbf
current size: 69632K can be resized to: 128K (reduction of: 99.82 %)
SQL> alter database datafile
'/refresh/64bit/app/oracle/oradata/REF817U6/temp01.dbf' resize 128K;


2. Check highest allocated extent in datafile (likely slow when having many extents)

column file_name format a50; 
column tablespace_name format a15; 
column highwater format 9999999999; 
set pagesize 9999 

select a.tablespace_name 
,a.file_name 
,(b.maximum+c.blocks-1)*d.db_block_size highwater 
from dba_data_files a 
,(select file_id,max(block_id) maximum 
from dba_extents 
group by file_id) b 
,dba_extents c 
,(select value db_block_size 
from v$parameter 
where name='db_block_size') d 
where a.file_id = b.file_id 
and c.file_id = b.file_id 
and c.block_id = b.maximum 
order by a.tablespace_name,a.file_name 

Output from option Number 2:

TABLESPACE_NAME FILE_NAME HIGHWATER 
--------------- -------------------------------------------------- ----------- 
BIGPARTYWEEK1 /ots1/app/oracle/product/8.1.7/dbs/bw1.dbf 49152 
IFS_LOB_N /ots3/oradata/v817/oradata/v817/ifs_lob_n.dbf 157294592 
IFS_MAIN /ots3/oradata/v817/oradata/v817/ifs_main.dbf 23027712 
OEM_REPOSITORY /ots1/oradata/v817/oradata/v817/oem_repository.dbf 56492032 
RBS /ots1/oradata/v817/oradata/v817/rbs01.dbf 230170624 

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

转载于:http://blog.itpub.net/12798004/viewspace-1990633/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Freemake Video Converter 是一款功能强大的免费视频转换软件,支持众多的视音频、DVD 及图片格式,基本输出格式包括 AVI、MP4、WMV、MKV、3GP、DVD、Blu-ray、MP3 及 iPod、iPhone、iPad、Android 等设备格式。 Freemake Video Converter 支持 CUDA 技术,能实现更高效的视频编码,同时由于是基于.NET Framework 4开发,Freemake 的界面非常之精美、可观易用。 新版 Freemake Video Converter 在视频编辑方面有所增强,支持视频切割剪辑功能,比如切割合并视频、多段切割,以及视频旋转和视频翻转等,另外在输出配置方面有了彻底改进,附带很多的预先定义配置,并可自定义,只是它需要安装 .NET 运行库,这一点足以让很多用户望而却步了,不过它的界面和操作也确实赏心悦目。 Freemake Video Converter 功能特点 直接从超过50个网站转换在线视频 Freemake是仅有的的免费视频转换器,可以通过YouTube、Facebook、Vimeo、Dailymotion、等超过50个支持的网站,复制粘贴网址直接获取在线视频,下载YouTube到itunes中并转换成任何格式或可用装置。所有支持的网站 输出到AVI、WMV、MP4、MKV、FLV、3GP、MP3 免费转换视频到最受欢迎的视频格式。 翻录DVD 电影(未保护)为AVI、WMV、MP4、MPEG、MKV、FLV、SWF、3GP。转换视频到Flash 并直接嵌入到您的网页。使用我们的免费视频转换器转换视频和音频文件到MP3。 免费转换到iPod、iPhone、iPad、PSP、PS3、Android 为苹果、索尼和安卓设备优化视频。免费转换视频到iPod Classic、iPod Touch、iPod Nano、iPod 5G、iPhone、iPad、Sony PSP、PS2、PS3、BlackBerry、Xbox、Apple TV、Android移动设备、智能手机等。 使用CUDA和DXVA最快转换视频格式 Freemake是唯一整合CUDA和DXVA技术的免费视频转换软件,它以较少的CPU使用率进行最快的的视频转换。软件自动监测最佳转换参数并切换CUDA和DXVA的开关来获取更好的转换结果。 默认启用NVIDIA CUDA技术,能实现更高效的视频编码;它还支持Flash/SWF动画的转换。 Freemake Video Converter的缺点:如视频编辑功能相对较弱,只支持简单的剪切和翻转;输出配置也不能自定义,只能使用内置的。 Freemake Video Converter 输入格式众多,具体情况如下: 视频格式:avi, mp4, wmv, mkv, dvd, mpg, 3gp, flv, swf, tod, mts, mov, m4v, rm, qt, ts, amv, avs, bik, bnk, cavs, cdg, dpg, dv1394, dxa, ea, ffm, film, film_cpk, flc, flh, fli, flm, flt, flx, gxf, h261, h263, h264, mj2, mjpg, mkm, mtv, mxf, nc, nut, nuv, ogm, ogv, pva, r3d, rax, rms, rmx, rpl, rtsp, sdp, smk, thp, vc1, vfw, vro 音频格式:mp3, aac, ogg, wma, wav, flac, m4a, amr, au, aif, aiff, aifc, ac3, adts, alaw, apc, ape, caf, dts, gsd, gsm, mka, mlp, mmf, m4r, mp1, mp2, mpeg3, mpc, mp , m2a, nut, oma, qcp, ra, rmj, shn, tta, voc, w64, wv, xa 图片格式:bmp, jpg, gif, png, tif, anm, dpx, jpg, pam, pbm, pcx, pgm, ppm, sgi, sr, ras, tga, txd Freemake Video Converter截图

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值