代码之家  ›  专栏  ›  技术社区  ›  Jim Hudson

如何回收已删除LOB的存储

  •  6
  • Jim Hudson  · 技术社区  · 14 年前

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

    我担心的只是空间不足——表空间可用的12 GB中大约有9 GB可用,我想在要求更多空间之前,先弄清楚如何回收空间。

    LOB列存储在一个单独的表空间中,但是对于较小的列,允许使用“在行存储”。

    这是Oracle11.1,数据在同一个表的CLOB和BLOB列中。LOB索引段(sys_il…)很小,所有存储都在数据段(sys_lob…)中。

    我们尝试了清除和合并,但没有得到任何地方——用户数据块中相同数量的字节。

    “改变表XXX移动”将有效,但我们需要有足够的空间来移动它,以便修改数据。当然,我们也需要在非工作时间内完成这项工作并重建索引,但这很容易。

    复制出好的数据并进行截断,然后再将其复制回来,也会起作用。但这几乎就是“alter table”命令所做的。

    我是不是错过了一些简单的方法来缩小物品的体积,把它们放回去?或者“改变表XXX移动”是最好的方法?或者这不是问题,Oracle会在需要时从已删除的LOB行中收回空间?

    2 回复  |  直到 10 年前
        1
  •  9
  •   Jean-François Savard    10 年前

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

    您是对的,删除LOB不会回收Tablescape中的任何存储。

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

    select bytes
        from user_segments
        where tablespace_name = yourTableSpace
          and segment_name = yourTableName; 
    

    阅读 this Oracle文档,我发现您需要执行以下语句

    ALTER TABLE yourLobTable MODIFY LOB (yourLobColumn) (SHRINK SPACE);
    

    它会收缩 BASICFILE LOB段。

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

    选择字节
    来自用户段
    其中tablespace_name=yourtablespace
    段名称=您的表名称;
    

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

    现在,对于那些想释放磁盘空间的人,请注意,数据文件不会自动重新调整大小,并且仍将保持磁盘的完整大小。

    但是,在重新调整数据文件的大小之前,请确保使用这些查询(使用所需的查询)释放段中未使用的空间(如前所述从同一个文档中窃取该空间)。

    ALTER TABLE table DEALLOCATE UNUSED KEEP integer;
    ALTER INDEX index DEALLOCATE UNUSED KEEP integer;
    ALTER CLUSTER cluster DEALLOCATE UNUSED KEEP integer;
    

    注意, KEEP 子句是可选的,允许您指定段中保留的空间量。您可以通过检查 DBA_FREE_SPACE 查看。

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

    ALTER DATABASE DATAFILE yourDatafile.dbf resize 500M
    

    请注意,调整大小时可以收缩的最大大小是基于数据文件中最后一个数据块的位置。因此,删除大量数据后,很可能无法真正调整大小。然后,最简单的方法是导出数据并在另一个表空间中重新导入,然后删除旧的表空间。导入数据时,Oracle将尽可能多地对其进行打包。

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

    SELECT tablespace_name, file_name, bytes
      FROM dba_temp_files WHERE tablespace_name like 'TEMP%';
    
        2
  •  1
  •   Gary Myers    14 年前

    通常,一旦一个数据块分配给一个表,它就保持分配状态。如果在表中插入了其他数据,则可以重新使用表中的空白空间。但是,很难从表中回收空间,因为表可能有块1到100,空块在块50-75中,或者空块为1、3、5、7等。

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