暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle的存储信息-区间信息

原创 eygle 2019-10-14
748

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简要说明了一个数据文件的空间示意。


image.png


这和段空间的使用和收缩非常类似,可以通过如下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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论