0
点赞
收藏
分享

微信扫一扫

Oracle 表碎片处理

在生产中经常会遇到频繁更新的表,时间久了之后就会产生较多的碎片。

产生的碎片的根本原因就是因为表上dml较多,导致出现这种情况最操蛋的原因就是开发在处理表时不严谨。

比如在全量同步表时候,经常性的操作就是delete from t ;insert into t;然后循环往复。

正确的做法是truncate table t ;insert into t ;

以上只是背景,最重要的是问题出现了,我们怎么去处理这种情况。

对于Oracle来说,处理表碎片的方式有:

1、shrink space

2、move tablespace

3、导入导出

4、cats

5、在线重定义

这篇主要记录下有关alter table ... shrink来回收表碎片的问题

有两种方式:

alter table table_name shrink space ;
alter table table_name shrink space compact;

对于alter table shrink ,很多人疑问的是,我使用shrink table回收了表碎片,但是数据文件和表空间的空间貌似没有任何变化。这其实是对shrink table的原理不理解导致的。

shrink table只是针对表本身,而数据文件的空间在创建表空间或者数据文件的时候就已经确定了。

使用shrink的限制:

a、alter table ... shrink语句不能结合其他alter table语句使用

b、不能用于clustered table或者任何有long属性列的表

c、不支持基于函数索引、域索引及位图索引的表

d、不能用于压缩表

e、不能用于on commit物化视图的主表,Rowid物化视图必须在收缩操作后重新生成

操作:

在使用alter table shrink之前,需要开启表的行移动属性

alter table table_name enable row movement ;
alter table table_name shrink space ;(整理碎片并回收空间)
alter table table_name shrink space compact;(只整理碎片,不回收空间)
alter table table_name disable row movement ;
完成之后不需要重建索引,做完之后收集统计信息。
cascade:缩小表及其索引,并移动高水位线,释放空间
compact:仅仅是缩小表和索引,并不移动高水位线,不释放空间
alter table table_name shrink space 相当于带cascade参数

总结:

alter table ... shrink需要满足:

表位于Locally Managed Tablespace(本地管理表空间),以便自动段空间管理可用

表所在的表空间必须使用Automatic Segment Space Management(自动段空间管理)

select t.SEGMENT_SPACE_MANAGEMENT,t.EXTENT_MANAGEMENT,t.* from dba_tablespaces t

表的row movement属性必须开启(除非是索引组织表)

==============================

相关脚本:

查看位于ASSM表空间的表的空闲空间

The following process may be used at any time to determine the amount of free space within a table in an ASSM tablespace

注意在使用时将<SCHEMA>、<OBJECT NAME>、<OBJECT TYPE>替换为你的实际值

set serveroutput on

declare
TOTAL_BLOCKS number;
TOTAL_BYTES number;
UNUSED_BLOCKS number;
UNUSED_BYTES number;
LAST_USED_EXTENT_FILE_ID number;
LAST_USED_EXTENT_BLOCK_ID number;
LAST_USED_BLOCK number;

begin
dbms_space.unused_space(
'<SCHEMA>',
'<OBJECT NAME>',
'<OBJECT TYPE>',
TOTAL_BLOCKS,
TOTAL_BYTES,
UNUSED_BLOCKS,
UNUSED_BYTES,
LAST_USED_EXTENT_FILE_ID,
LAST_USED_EXTENT_BLOCK_ID,
LAST_USED_BLOCK);

dbms_output.put_line('TOTAL_BLOCKS = '||TOTAL_BLOCKS);
dbms_output.put_line('UNUSED_BLOCKS = '||UNUSED_BLOCKS);
end;
/

The following procedure may be used at any time to see the block allocations for a table stored in an ASSM tablespace

注意在使用时将<SCHEMA>、<OBJECT NAME>、<OBJECT TYPE>替换为你的实际值

set serveroutput on

declare
v_unformatted_blocks number;
v_unformatted_bytes number;
v_fs1_blocks number;
v_fs1_bytes number;
v_fs2_blocks number;
v_fs2_bytes number;
v_fs3_blocks number;
v_fs3_bytes number;
v_fs4_blocks number;
v_fs4_bytes number;
v_full_blocks number;
v_full_bytes number;

begin
dbms_space.space_usage (
'<SCHEMA>',
'<OBJECT NAME>',
'<OBJECT TYPE>',
v_unformatted_blocks,
v_unformatted_bytes,
v_fs1_blocks,
v_fs1_bytes,
v_fs2_blocks,
v_fs2_bytes,
v_fs3_blocks,
v_fs3_bytes,
v_fs4_blocks,
v_fs4_bytes,
v_full_blocks,
v_full_bytes);

dbms_output.put_line('Unformatted Blocks = '||v_unformatted_blocks);
dbms_output.put_line('Blocks with 00-25% free space = '||v_fs1_blocks);
dbms_output.put_line('Blocks with 26-50% free space = '||v_fs2_blocks);
dbms_output.put_line('Blocks with 51-75% free space = '||v_fs3_blocks);
dbms_output.put_line('Blocks with 76-100% free space = '||v_fs4_blocks);
dbms_output.put_line('Full Blocks = '||v_full_blocks);

end;
/

参考文档:

Why is no space released after an ALTER TABLE ... SHRINK? (Doc ID 820043.1)

举报

相关推荐

0 条评论