ORACLE 11g 生产中高水位线(HWM)处理

数据库中表不断的insert,delete,update,致使表和索引出现碎片。这会致使HWM以前有不少的空闲空间,而oracle在作全表扫描的时候会读取HWM一下的全部块,这样会产生更多的IO,影响性能。数据库

oracle提供了shrink space碎片整理的功能,对于索引要采起rebuild online的方式进行碎片整理。安全

高水位的管理机制

高水位的管理机制在 MSSM 和 ASSM 中不一样,在以往的手动段空间管理中(MSSM),高水位标记 HWM,一个段分红三部分,header block,used block(row data),unusedblock,其中 used block 和 unused block 之间的分界线就是高水位标记 HWM,当进行全表扫描的时候,会扫描到 HWM 下的全部数据块,即便 used block 中不少数据被删除了,全表扫描仍是以HWM为准。oracle

 

在自动段管理(ASSM)中,利用位图来代替空闲列表,当会话向表插入数据时,数据库只格式一个单独的位图块,而不是像 MSSM 中那样,会预先格式化一组块。在ASSM表空间中,除了一个 HWM 外,还有一个低 HWM。在 MSSM 中,HWM 推动时,全部的块都会格式化并当即生效,这样 Oracle 就能够安全的读取这些块。可是对于 ASSM,当 HWM推动时,Oracle 并不会当即格式全部的块,只是在第一次使用的时候才会对这些块进行格式化。也就是说,在第一次使用的的时候,即进行 insert 操做时,数据会插入到块中的任意水位线,位于低水位线(LHMW)和高水位线(HHMW)之间。所以在这个区域的许多块就不会被格式化。性能

背景

生产中这S_OPERATELOG, S_T_RTNRP_STATUS, S_T_SEND_REPORT三张表实际使用量不大(即truncate分区后),表空间数据文件仍是占用很高,几个T,现须要释放不用的空间。ui

 

生产中遇到的案例

如下是生产中的三张表,且都是按天生成的分区表(不足一个月的数据,一年数据量很大)spa

select segment_name,round(sum(bytes / 1024 / 1024 / 1024), 2) Gblog

  from user_segments索引

 where segment_name init

       ('S_OPERATELOG', 'S_T_RTNRP_STATUS', 'S_T_SEND_REPORT') group by segment_name;io

  

能够看出使用的并非很大。

 

查看表使用的表空间

select owner, table_name, tablespace_name

  from dba_tables

 where owner = 'SMART'

   AND TABLE_NAME in

       ('S_OPERATELOG', 'S_T_RTNRP_STATUS', 'S_T_SEND_REPORT')

       UNION

 select TABLE_OWNER,TABLE_NAME,TABLESPACE_NAME

  from dba_Tab_Partitions

 where

  TABLE_OWNER='SMART'

   AND TABLE_NAME in

       ('S_OPERATELOG', 'S_T_RTNRP_STATUS', 'S_T_SEND_REPORT')     

 

查看表空间使用状况:

select tablespace_name,

ROUND(sum(bytes / 1024 / 1024 / 1024),2) G,ROUND(sum(maxbytes / 1024 / 1024 / 1024),2) max_G

  from dba_data_files

 where file_name like '+FDATADG%'

 GROUP BY TABLESPACE_NAME ORDER BY 2 DESC;

 

 

能够看出几个表空间占用空间很大,尤为是前三个表空间。

查看表空间数据文件状况:

SELECT a.tablespace_name,

       a.file_name,

       round(a.bytes/1024/1024/1024,2) AS "current_bytes(GB)",

       round(a.bytes/1024/1024/1024 - b.resize_to/1024/1024/1024,2) AS "shrink_by_bytes(GB)",

       round(b.resize_to/1024/1024/1024,2) AS "resize_to_bytes(GB)"

FROM   dba_data_files a,

       (SELECT file_id, MAX((block_id+blocks-1)*&v_block_size) AS resize_to

        FROM   dba_extents

        GROUP by file_id) b

WHERE  a.file_id = b.file_id

and a.TABLESPACE_NAME in

 (

'SMART_OPLOG01',

'SMART_NRRPSTA01',

'SMART_NRRPSTA02',

'SMART_NSNRP01',

'SMART_NSNRP02'

)

ORDER BY a.tablespace_name, a.file_name;

块大小是16K的。16384

 

 

后三列表示当前占用大小,可以收缩大小,最小的resize大小。

处理办法:

1)    Shrink对应的表

注意:因为在线上,不能进行有表锁的操做,因此我并无采用这种办法

alter table TABLE_NAME enable ROW MOVEMENT;--启动行移动功能

alter table TABLE_NAME shrink space compact;  --只整理碎片 不回收空间

-- 重置高水位,此时不能有DML操做

alter table TABLE_NAME shrink space; --整理碎片并回收空间,并调整水位线。业务少时执行

alter table TABLE_NAME disable ROW MOVEMENT;--关闭行移动

 

2)    Resize 数据文件

select  ' alter database datafile '''||file_name ||''' resize 43g;' from dba_data_files where tablespace_name

   in (

   'SMART_NRRPSTA01'

   );

 

 

收缩前表空间使用以下:

 

 

收缩后表空间使用以下:

 

 

磁盘组使用以下:

 

原+FDATADG磁盘中使用达到96%,释放了20%的空间。

相关文章
相关标签/搜索