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

SHRINK SPACE:在线收缩表、LOB、IOT段的大小

原创 章芋文 2019-11-06
10333

从10g开始,可以通过alter table shrink space命令来在线收缩段空间,相对于MOVE来说,对应用的影响更小。

示例

以下是alter table shrink space示例。

-- Enable row movement. ALTER TABLE scott.emp ENABLE ROW MOVEMENT; -- Recover space and amend the high water mark (HWM). ALTER TABLE scott.emp SHRINK SPACE; -- Recover space, but don't amend the high water mark (HWM). ALTER TABLE scott.emp SHRINK SPACE COMPACT; -- Recover space for the object and all dependant objects. ALTER TABLE scott.emp SHRINK SPACE CASCADE;
复制

该COMPACT选项允许收缩操作分为两个阶段。首先,使用COMPACT选项移动行,但不调整高水位线(HWM),因此不会使解析的SQL语句失效。之后再通过不带COMPACT命令来调整HWM,此时相关的SQL语句都需要重新解析。

LOB、IOT收缩命令如下:

-- Shrink a LOB segment (basicfile only). ALTER TABLE table_name MODIFY LOB(lob_column) (SHRINK SPACE); ALTER TABLE table_name MODIFY LOB(lob_column) (SHRINK SPACE CASCADE); -- Shrink an IOT overflow segment. ALTER TABLE iot_name OVERFLOW SHRINK SPACE;
复制

相关内容

找出大的segment

通过DBA|ALL|USER_SEGMENTS视图找到较大的segment。以下示例使用top-n查询来显示20个最大的segment。

SET LINESIZE 200 COLUMN owner FORMAT A30 COLUMN segment_name FORMAT A30 COLUMN tablespace_name FORMAT A30 COLUMN size_mb FORMAT 99999999.00 SELECT * FROM (SELECT owner, segment_name, segment_type, tablespace_name, ROUND(bytes/1024/1024,2) size_mb FROM dba_segments ORDER BY 5 DESC) WHERE ROWNUM <= 20;
复制

以下top-n查询来获取有关LOB段的大小。

SET LINESIZE 200 COLUMN owner FORMAT A30 COLUMN table_name FORMAT A30 COLUMN column_name FORMAT A30 COLUMN segment_name FORMAT A30 COLUMN tablespace_name FORMAT A30 COLUMN size_mb FORMAT 99999999.00 SELECT * FROM (SELECT l.owner, l.table_name, l.column_name, l.segment_name, l.tablespace_name, ROUND(s.bytes/1024/1024,2) size_mb FROM dba_lobs l JOIN dba_segments s ON s.owner = l.owner AND s.segment_name = l.segment_name ORDER BY 6 DESC) WHERE ROWNUM <= 20;
复制

行迁移

ALTER TABLE … SHRINK SPACE命令在现有块之间移动行以压缩数据,因此在尝试收缩段之前,需要启用行迁移。您可以通过查询[DBA|ALL|USER]_TABLES视图的ROW_MOVEMENT列来检查是否已启用行迁移。

SELECT row_movement FROM user_tables WHERE table_name = 'EMP'; ROW_MOVE -------- DISABLED SQL>
复制

使用以下命令启用行迁移:

ALTER TABLE emp ENABLE ROW MOVEMENT;
复制

再次查询是否启用:

SELECT row_movement FROM user_tables WHERE table_name = 'EMP'; ROW_MOVE -------- ENABLED SQL>
复制

SecureFile LOBs

使用basicfile LOB时,收缩命令可以正常运行。为了证明这一点,我们需要创建一个包含basicfile LOB列的表。

DROP TABLE lob_tab PURGE; CREATE TABLE lob_tab ( id NUMBER, data CLOB ) LOB(data) STORE AS BASICFILE (DISABLE STORAGE IN ROW); INSERT INTO lob_tab VALUES (1, 'ONE'); COMMIT;
复制

我们可以看到两个收缩命令正常工作。

SQL> ALTER TABLE lob_tab MODIFY LOB(data) (SHRINK SPACE); Table altered. SQL> ALTER TABLE lob_tab MODIFY LOB(data) (SHRINK SPACE CASCADE); Table altered. SQL>
复制

现在,使用securefile LOB列重新创建表。

DROP TABLE lob_tab PURGE; CREATE TABLE lob_tab ( id NUMBER, data CLOB ) LOB(data) STORE AS SECUREFILE (DISABLE STORAGE IN ROW); INSERT INTO lob_tab VALUES (1, 'ONE'); COMMIT;
复制

现在,第一个命令失败,但是添加该CASCADE选项似乎使其起作用。

SQL> ALTER TABLE lob_tab MODIFY LOB(data) (SHRINK SPACE); ALTER TABLE lob_tab MODIFY LOB(data) (SHRINK SPACE) * ERROR at line 1: ORA-10635: Invalid segment or tablespace type SQL> ALTER TABLE lob_tab MODIFY LOB(data) (SHRINK SPACE CASCADE); Table altered. SQL>
复制

不过第二个命令不起作用,securefile LOB段未缩小。
如果要收缩securefile LOB段,需要使用move或者在线重定义。在以下示例中,将MOVE到相同的表空间。

ALTER TABLE lob_tab MOVE LOB(data) STORE AS (TABLESPACE users);
复制

注意事项和限制

在执行收缩操作之前,需要考虑以下事项。

  • 移动行可能会导致基于Rowid的触发器出现问题。
  • Rowid的物化视图必须在收缩操作后重新构建。
  • 收缩过程仅适用于启用了自动段空间管理的表空间中的对象。
  • 不能将SHRINK SPACE子句与其他任何ALTER TABLE子句组合使用。
  • 不能收缩cluster或cluster table。
  • 不能收缩包含LONG类型字段的对象。
  • 不能收缩包含函数索引、domain索引或位图联接索引的表。
  • 不能收缩包含ON COMMIT物化视图的表
  • 索引组织表的映射表不受收缩的影响。
  • 不能收缩压缩表,除非使用高级行压缩(ROW STORE COMPRESS ADVANCED)。
  • 对表的收缩操作不会级联到LOB字段。需要分开处理。
  • 不能收缩securefile LOB段。
  • 在某些情况下,更改表中行的排列可能会对性能产生负面影响。在做出任何决定之前,请彻底测试。
  • 在进行任何结构性更改(例如移动)之后,请记住检查不可用的索引。您可以使用unusuable_indexes.sql脚本来查找它们。如果有,需要重建。
最后修改时间:2019-12-02 09:30:33
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
1人已赞赏
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论