DBA_EXTENTS视图记录了Segment中区的分配情况,可以通过查询这个视图获得数据库中每个区的分配情况:
SQL> select segment_name,file_id,extent_id,block_id,blocks 2 from dba_extents where segment_name='OBJ$'; SEGMENT_NAME FILE_ID EXTENT_ID BLOCK_ID BLOCKS -------------------- ---------- ---------- ---------- ---------- OBJ$ 1 0 121 8 OBJ$ 1 1 5241 8 OBJ$ 1 2 5721 8 OBJ$ 1 3 5857 8 OBJ$ 1 4 6281 8 OBJ$ 1 5 6953 8 OBJ$ 1 6 9209 8 OBJ$ 1 7 11681 8 OBJ$ 1 8 12801 8 OBJ$ 1 9 14713 8 OBJ$ 1 10 17009 8 OBJ$ 1 11 24889 8 OBJ$ 1 12 25081 8 OBJ$ 1 13 26961 8 OBJ$ 1 14 27425 8 OBJ$ 1 15 29553 8 OBJ$ 1 16 30729 128 17 rows selected.
如前文曾经介绍过的,我们可以通过这个视图观察本地管理表空间的空间分配规律(AUTOALLOCATE和UNIFORM SIZE)。作为DBA经常会面对的一个问题是,调整数据文件的大小,通常调整文件大小的命令如下:
Alter database datafile ‘<datafile>’ resize [size];
如果是扩大一个文件,那么通常只要空间足够并且未超过操作系统的限制,是很简单的,但是如果需要收缩一个文件,可能大家经常会遇到如下一个提示:
SQL> alter database datafile '/opt/oracle/oradata/eygle/undotbs01.dbf' resize 100M; alter database datafile '/opt/oracle/oradata/eygle/undotbs01.dbf' resize 100M * ERROR at line 1: ORA-03297: file contains used data beyond requested RESIZE value
这个提示的意思是,在指定收缩的100MB之外,还存有数据,这样就不能够Resize到指定的大小。那么如何判断一个文件实际使用空间的大小呢?
通过dba_extents视图,可以做到精确判断,由于段的空间分配是以区为单位进行的,所以只要找到一个数据文件上最后一个区间占用的位置,就可以计算出一个数据文件的HWM。图5-10简要说明了一个数据文件的空间示意。
这和段空间的使用和收缩非常类似,可以通过如下SQL来确定不同文件可以进行收缩的空间:
SQL> col name for a40 SQL> col resizecmd for a80 SQL> select a.file#, 2 a.name, 3 a.bytes / 1024 / 1024 CurrentMB, 4 ceil(HWM * a.block_size) / 1024 / 1024 ResizeTo, 5 (a.bytes - HWM * a.block_size) / 1024 / 1024 ReleaseMB, 6 'alter database datafile ''' || a.name || ''' resize ' || 7 ceil(HWM * a.block_size) / 1024 / 1024 || 'M;' ResizeCmd 8 from v$datafile a, 9 (SELECT file_id, MAX(block_id + blocks - 1) HWM 10 FROM DBA_EXTENTS 11 GROUP BY file_id) b 12 where a.file# = b.file_id(+) 13 And (a.bytes - HWM * a.block_size) >0 14 order by 5 15 / FILE# NAME CURRENTMB RESIZETO RELEASEMB ---------- ---------------------------------------- ---------- ---------- ---------- RESIZECMD -------------------------------------------------------------------------------- 1 /opt/oracle/oradata/eygle/system01.dbf 211.070313 211.0625 .0078125 alter database datafile '/opt/oracle/oradata/eygle/system01.dbf' resize 212M; 2 /opt/oracle/oradata/eygle/undotbs01.dbf 125 120.0625 4.9375 alter database datafile '/opt/oracle/oradata/eygle/undotbs01.dbf' resize 121M; 4 /opt/oracle/oradata/eygle/users.dbf 10 1.125 8.875 alter database datafile '/opt/oracle/oradata/eygle/users.dbf' resize 2M;
现在就可以根据查询结果进行数据文件的收缩:
SQL> alter database datafile '/opt/oracle/oradata/eygle/undotbs01.dbf' resize 121M; Database altered.
当然Resize对于文件中间的自由空间无能为力,为了释放更多的空间,可以尝试将文件末尾的对象移走,以使得自由空间调整到文件末尾,从而可以通过Resize释放这些空间,这非常类似于操作系统的空间整理与分区调整。通过以下SQL可以简单地查询出每个数据文件最末端存储的对象:
SQL> col segment_name for a30 SQL> col semgent_type for a20 SQL> select /*+ rule */ owner,segment_name,segment_type from dba_extents 2 where (file_id,block_id) in 3 (select file_id,max(block_id) from dba_extents group by file_id); OWNER SEGMENT_NAME SEGMENT_TYPE ------------------------------ ------------------------------ ------------------ SYS I_H_OBJ#_COL# INDEX SYS _SYSSMU7$ TYPE2 UNDO SYS ALERT_QT TABLE EYGLE EYGLE TABLE BOSSMGR SMS_ORG_HS_MO_0609 TABLE DBMON DBA_IOEXTEND_DAY TABLE 6 rows selected
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。