如何回收已删除LOB的存储空间

Jim*_*son 6 oracle

我有一个LOB表空间.目前持有9GB的12GB可用.而且,据我所知,删除记录不会回收表空间中的任何存储.(这是通过监视存储的简单方法 - 针对user_extents的查询,这是我作为非DBA所允许的所有内容)我担心处理进一步处理.

我担心的是空间不足 - 我们在12GB的桌面空间可用大约9 GB,我想知道在要求更多空间之前如何回收空间.

LOB列存储在单独的表空间中,但允许"存储在行中"用于小型表空间.

这是Oracle 11.1,数据位于同一个表中的CLOB和BLOB列中.LOB索引段(SYS_IL ...)很小,所有存储都在数据段中(SYS_LOB ...)

我们试过purge和coalesce并没有得到任何地方 - 在user_extents中相同的字节数.

"改变表xxx移动"将起作用,但是我们需要有一个地方将其移动到有足够空间容纳修改后的数据.当然,我们还需要在非工作时间完成这项工作并重建索引,但这很容易.

复制好数据并进行截断,然后将其复制回来也是有效的.但这几乎就是"alter table"命令的作用.

我是否遗漏了一些简单的方法来缩减内容并恢复存储?或者是"改变表xxx移动"的最佳方法?或者这是一个非问题,Oracle会在需要时从已删除的lob行中获取空间吗?

Jea*_*ard 9

这个问题很老,但从来没有一个有效的答案,可能对很多人有用,所以这里是我遇到这个问题时找到的解决方案.

你是对的,删除LOB不会回收tablescape中的任何存储.

在删除LOB之前和之后运行此查询将得到相同的结果

select bytes
    from user_segments
    where tablespace_name = yourTableSpace
      and segment_name = yourTableName; 
Run Code Online (Sandbox Code Playgroud)

阅读这篇 Oracle文档,我发现你需要执行以下语句

ALTER TABLE yourLobTable MODIFY LOB (yourLobColumn) (SHRINK SPACE);
Run Code Online (Sandbox Code Playgroud)

这将缩小BASICFILELOB细分市场.

现在,如果您重新执行查询

select bytes
    from user_segments
    where tablespace_name = yourTableSpace
      and segment_name = yourTableName; 
Run Code Online (Sandbox Code Playgroud)

您会注意到该空间已释放到表空间,并且可以根据需要重新使用该空间.

现在,对于那些想要释放磁盘空间的用户,请注意数据文件不会自动重新调整大小,并且仍会保留磁盘上的完整大小.

但在重新调整数据文件大小之前,请确保使用这些查询释放段中未使用的空间(从之前所述的文档中删除)(使用您需要的那个)

ALTER TABLE table DEALLOCATE UNUSED KEEP integer;
ALTER INDEX index DEALLOCATE UNUSED KEEP integer;
ALTER CLUSTER cluster DEALLOCATE UNUSED KEEP integer;
Run Code Online (Sandbox Code Playgroud)

请注意,该KEEP子句是可选的,允许您指定段中保留的空间量.您可以通过检查DBA_FREE_SPACE视图来验证是否释放了释放的空间.

现在重新调整数据文件的大小,

ALTER DATABASE DATAFILE yourDatafile.dbf resize 500M
Run Code Online (Sandbox Code Playgroud)

请注意,调整大小时可以缩小的最大大小取决于数据文件中最后一个数据块的位置.因此,在删除大量数据之后,很有可能无法真正重新调整大小.然后,最简单的方法是导出数据并在另一个表空间中重新导入,然后删除旧的表空间.导入数据时,Oracle会尽可能地打包它们.

如果你想释放更多的空间,你可以清除临时表空间,有时会占用大量空间(我的数据库为5GB).使用以下语句检查其大小:

SELECT tablespace_name, file_name, bytes
  FROM dba_temp_files WHERE tablespace_name like 'TEMP%';
Run Code Online (Sandbox Code Playgroud)


Gar*_*ers 1

一般来说,一旦将一个盘区分配给表,它就会保持分配状态。如果将其他数据插入表中,则可以重新使用表中的空白空间。然而,很难从表内回收空间,因为表可能具有例如块1到100,而空块在块50-75中,或者空块是1、3、5、7等。

问题是,您是否担心表内的空间被重新使用,或者您是否需要为表空间中的其他对象释放空间,或者您是否需要能够收缩表空间数据文件?