为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。
【DM版本】:DM8 03134284194-20240703-234060-20108
【操作系统】:CentOS 7
【CPU】:Intel
【问题描述】*:数据库表delete数据后不会改变表大小,插入新数据后也不会复用空间,表大小继续增长。
1、表初始大小:
2、插入1000行数据后,表大小:
3、删除1000行数据后,表大小:
4、再插入1000行数据后表大小:
之前我做过类似的实验关于Oracle和达梦数据库delete与insert空间重用机制,结论是:
1、达梦数据库delete之后重新insert分配的族是一族增长的,不会进行空间复用,或者说不完全复用。
2、Oracle在 DELETE + INSERT 场景下,段空间会被复用,也可以通过/+ append/跳过查找空闲块的步骤,避免对已经删除空间的复用直接追加到表中。

查一下 UNDO_RETENTION 参数的配置值
SELECT * FROM V$DM_INI WHERE PARA_NAME = 'UNDO_RETENTION'在删除数据后,等过了 UNDO_RETENTION 配置值秒数后,再查看表的大小,看看是否开始变小了。
可以做一个简单的测试,比如我手头测试环境,UNDO_RETENTION 参数设置为90,也就是回滚段数据保留90秒,这样数据库在删除记录并提交的90秒(貌似不是非常准,有点误差)后开始对回滚段进行回收,并同步回收表上空闲页。
测试脚本如下:
--测试表 DROP TABLE IF EXISTS T_HTTST; CREATE TABLE T_HTTST ( A INT, B VARCHAR2(100), C INT ); / DECLARE V_INFO VARCHAR2(200); BEGIN --先打印初始状态空表的大小 PRINT( TO_N_CHAR(-1,4) || TO_CHAR(SYSTIMESTAMP,'HH24:MI:SS.FF6')||' ' || ROUND(CAST(TABLE_USED_PAGES(USER,'T_HTTST') AS NUMBER) * PAGE / 1024 / 1024,2) ||'/' || ROUND(CAST(TABLE_USED_SPACE(USER,'T_HTTST') AS NUMBER) * PAGE / 1024 / 1024,2) ); INSERT INTO T_HTTST SELECT CEIL(RAND * 10000000),SF_RANDOM_STRING('A',10),CEIL(RAND * 10000000) CONNECT BY LEVEL <= 2000000; COMMIT; --打印插入数据后的表大小 PRINT( TO_N_CHAR(0,4) || TO_CHAR(SYSTIMESTAMP,'HH24:MI:SS.FF6')||' ' || ROUND(CAST(TABLE_USED_PAGES(USER,'T_HTTST') AS NUMBER) * PAGE / 1024 / 1024,2) ||'/' || ROUND(CAST(TABLE_USED_SPACE(USER,'T_HTTST') AS NUMBER) * PAGE / 1024 / 1024,2) ); DELETE FROM T_HTTST; COMMIT; --我这里 UNDO_RETENTION 设置为 90 ,所以最多跑120秒也就够了 FOR I IN 1 .. 120 LOOP --每隔一秒取一次表在删除数据后的大小 PRINT( TO_N_CHAR(I,4) || TO_CHAR(SYSTIMESTAMP,'HH24:MI:SS.FF6')||' ' || ROUND(CAST(TABLE_USED_PAGES(USER,'T_HTTST') AS NUMBER) * PAGE / 1024 / 1024,2) ||'/' || ROUND(CAST(TABLE_USED_SPACE(USER,'T_HTTST') AS NUMBER) * PAGE / 1024 / 1024,2) ); SLEEP(1); END LOOP; END; /测试结果如下:
-1 15:36:57.574877 0.47/0.5 0 15:36:59.718065 82.94/83 1 15:37:02.244270 82.94/83 。。。这部分处于 UNDO_RETENTION 时间范围内的的都一样,略去。。。 83 15:38:31.130977 82.94/83 84 15:38:32.214846 82.94/83 85 15:38:33.259456 70.41/70.5 --这时能看出表的大小开始有变化,时间提前了,不知为啥 86 15:38:34.297551 42.91/43 87 15:38:35.315778 17.91/18 88 15:38:36.351653 0.47/0.5 --这时表已经恢复成最初大小 89 15:38:37.422969 0.47/0.5 90 15:38:38.497596 0.47/0.5 。。。后面的都一样,略去。。。