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

Oracle 通过从具有LOB列的分区表中截断/丢弃分区来回收可用空间

askTom 2017-03-07
994

问题描述

嗨,团队,

我有一个分区表几乎300GB的数据与LOB列,其中包含总表大小的90-95% 数据。具有创建的130分区的分区表,当前有20个具有数据的分区。分区表有1个全局索引和1个本地分区索引。我们正在使用应用程序进行性能测试,在该应用程序中,我们需要删除旧的分区数据以释放空间以用于下一次运行。

1.我尝试过使用drop存储的截断分区来释放空间。

"alter table 截断分区P1丢弃存储;"

然后我重建了全球指数。我检查了dba_free_space,它显示了可用空间,但是在dba_extation中检查HWM时,它仍然设置为高值,并且在表空间中未显示可用空间。

因此,我尝试了缩小LOB列的分区,如下所示

alter table 启用行移动;
ALTER TABLE 修改分区P1收缩空间压缩;
ALTER TABLE 修改分区P1收缩空间;
ALTER TABLE 修改LOB() (收缩空间级联);
alter table 禁用行移动;

并再次重建全局索引,并为所有分区重建本地索引,但空间不会释放。

所以,我试着缩小整个表格如下

alter table 启用行移动;
ALTER TABLE 收缩空间紧凑;
ALTER TABLE 缩小空间;
ALTER TABLE 修改LOB() (收缩空间级联);
alter table 禁用行移动;

并再次重建全局索引,并为所有分区重建本地索引。这次空间被释放了。

2.我尝试了删除分区的替代方法

alter table drop partition (P1);

并使用更新的全局和本地索引执行与上述相同的活动,但没有运气。

同样,我必须缩小表并在所有分区表上重建全局和本地索引以释放空间。


3.我也尝试过将分区表移动到其他表空间,并在从分区表截断分区后恢复到原始表空间。但也没有运气。


我已经在我的实验室环境中测试了这个场景。收缩工作正常,就像我的实验室环境中数据较少一样。但是在300GB大小的表中,可能需要很长时间,而索引重建也需要很长时间。加上收缩也会锁定对象。

您能否帮助或建议通过删除/截断旧分区来回收空间的最佳方法。

专家解答

抱歉,我不确定你的意思。我在一个空的表空间中做了下面的演示。你可以看到当我截断一个分区,或者当我删除一个分区时,空间是免费的,如预期的。

SQL> create table t1 (
  2    c1 int,
  3    c2 char(1000),
  4    z1 clob,
  5    z2 clob
  6  )
  7  lob ( z1) store as basicfile z1lob,
  8  lob ( z2) store as basicfile z2lob
  9  partition by range ( c1 )
 10  (
 11    partition p1 values less than ( 5000 ),
 12    partition p2 values less than ( 10000 )
 13  )
 14  tablespace demo;

Table created.

SQL>
SQL> declare
  2    c clob;
  3  begin
  4    c := rpad('x',32700,'x');
  5
  6    insert into t1
  7    select
  8      rownum,
  9      rownum,
 10      'small clob',
 11      c
 12    from dual
 13    connect by level < 10000;
 14    commit;
 15  end;
 16  /

PL/SQL procedure successfully completed.

SQL>
SQL> create index t1_ix on t1 ( c1 );

Index created.

SQL>
SQL> col partition_name format a30
SQL> set lines 200
SQL> select segment_name, partition_name, bytes
  2  from user_segments
  3  where tablespace_name = 'DEMO'
  4  order by 1;

SEGMENT_NAME                   PARTITION_NAME                      BYTES
------------------------------ ------------------------------ ----------
SYS_IL0000101171C00003$$       SYS_IL_P786                       1048576
SYS_IL0000101171C00003$$       SYS_IL_P785                       1048576
SYS_IL0000101171C00004$$       SYS_IL_P790                       1048576
SYS_IL0000101171C00004$$       SYS_IL_P789                       1048576
T1                             P2                                7340032
T1                             P1                                7340032
Z1LOB                          SYS_LOB_P783                      1048576
Z1LOB                          SYS_LOB_P784                      1048576
Z2LOB                          SYS_LOB_P787                    409993216
Z2LOB                          SYS_LOB_P788                    409993216

10 rows selected.

SQL>
SQL> alter table t1 truncate partition p1;

Table truncated.

SQL>
SQL> select segment_name, partition_name, bytes
  2  from user_segments
  3  where tablespace_name = 'DEMO'
  4  order by 1;

SEGMENT_NAME                   PARTITION_NAME                      BYTES
------------------------------ ------------------------------ ----------
SYS_IL0000101171C00003$$       SYS_IL_P786                       1048576
SYS_IL0000101171C00003$$       SYS_IL_P785                       1048576
SYS_IL0000101171C00004$$       SYS_IL_P790                       1048576
SYS_IL0000101171C00004$$       SYS_IL_P789                       1048576
T1                             P2                                7340032
T1                             P1                                1048576 <== space released
Z1LOB                          SYS_LOB_P783                      1048576
Z1LOB                          SYS_LOB_P784                      1048576
Z2LOB                          SYS_LOB_P787                      2097152 <=== space released
Z2LOB                          SYS_LOB_P788                    409993216

10 rows selected.

SQL>
SQL> alter table t1 drop partition p2;

Table altered.

SQL>
SQL> select segment_name, partition_name, bytes
  2  from user_segments
  3  where tablespace_name = 'DEMO'
  4  order by 1;

SEGMENT_NAME                   PARTITION_NAME                      BYTES
------------------------------ ------------------------------ ----------
SYS_IL0000101171C00003$$       SYS_IL_P785                       1048576
SYS_IL0000101171C00004$$       SYS_IL_P789                       1048576
T1                             P1                                1048576
Z1LOB                          SYS_LOB_P783                      1048576
Z2LOB                          SYS_LOB_P787                      2097152

5 rows selected.  <== segments entirely removed
复制


「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论