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

LOB字段空间回收

DBA码农 2021-04-21
1276

二话不说,先看实验

  • 首先创建一个目录,上传一张图片。用于测试保存到数据库中

[oracle@test11 pic]$ pwd
/home/oracle/pic
[oracle@test11 pic]$ ls -l
total 172
-rw-r--r-- 1 oracle oinstall 170556 Dec 23  2017 space.jpg


  • 创建测试表

CREATE TABLE TEST_LOB (ID NUMBER, FILE_NAME VARCHAR2(45), IMAGE BLOB, TIMESTAMP  DATE);
CREATE SEQUENCE TEST_LOB_SEQ;
CREATE OR REPLACE DIRECTORY IMAGES_DIR AS '/home/oracle/pic';
CREATE OR REPLACE PROCEDURE LOAD_BLOB_FROM_FILE_IMAGE
AS
    DEST_LOC    BLOB;
    FILE_NAME   TEST_LOB.FILE_NAME%TYPE  := 'space.jpg';
    SRC_LOC     BFILE := BFILENAME('IMAGES_DIR', FILE_NAME);
BEGIN
    INSERT INTO TEST_LOB (ID, FILE_NAME, IMAGE, TIMESTAMP)
        VALUES (TEST_LOB_SEQ.NEXTVAL, FILE_NAME, EMPTY_BLOB(), SYSDATE)
        RETURNING IMAGE INTO DEST_LOC;
    DBMS_LOB.OPEN(SRC_LOC, DBMS_LOB.LOB_READONLY);
    DBMS_LOB.OPEN(DEST_LOC, DBMS_LOB.LOB_READWRITE);
    DBMS_LOB.LOADFROMFILE(
          DEST_LOB => DEST_LOC
        , SRC_LOB  => SRC_LOC
        , AMOUNT   => DBMS_LOB.GETLENGTH(SRC_LOC));
    DBMS_LOB.CLOSE(DEST_LOC);
    DBMS_LOB.CLOSE(SRC_LOC);
    COMMIT;
END;

  • 插入1000行记录

BEGIN
    FOR I IN 1 .. 1000
    LOOP
        LOAD_BLOB_FROM_FILE_IMAGE();
    END LOOP;
END;


SQL> SELECT count(*) FROM TEST_LOB;
  COUNT(*)
----------
      1000
SQL>

 

IMAGE为BLOB 字段,保存了一张图片:

LOB字段大小为 174063616

  • 删除一半的记录

LOB字段大小空间并没有变化。还是174063616

  • 再次插入1000行

LOB 字段大小增大到 348127232

  • 执行收缩表空间

ALTER TABLE TEST_LOB MODIFY LOB (IMAGE) (SHRINK SPACE);

居然大小没有发生改变:还是348127232

说明alter shrink 的方法对LOB 字段没有作用


创建另外一个测试表,上面的测试步骤重新执行一次

CREATE TABLE TEST_LOB_SECURE (ID NUMBER, FILE_NAME VARCHAR2(45), IMAGE BLOB, TIMESTAMP  DATE) LOB(IMAGE) STORE AS SECUREFILE
   TABLESPACE TBS_TS2;

同样插入1000行记录,LOB字段大小为 201523200

删除500行,然后插入1000行

空间缩小了70M


总结:通过上面的实验可以看到。DELETE表中的数据后,并不会释放LOB空间。重新插入记录也不会重用之前的空间。然后LOB字段的undo 管理又是依靠LOB本身空间去维护,不是使用数据库的空间。所以在生成实际使用过程中 ,LOB 字段所占空间非常容易越来越大。


一下三种方法可以回收LOB类型所占空间:

* Export drop the table import
* CREATE TABLE ... AS SELECT
* ALTER TABLE ... MOVE 


move 操作需要注意执行完后,收集统计信息,重建索引,并且执行过程中会产生大量归档,物理IO,并且最好在维护时间操作等等


最核心的建议是:LOB字段在OTLP系统里面能不用就不要使用,通过其他办法去存储大对象。


不用,哪里还有考虑空间问题呢。

文章转载自DBA码农,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论