1 概述
表空间瘦身是数据库空间治理中的常见操作:当表空间内大量数据被删除或迁出后,数据文件仍保持较大尺寸,造成磁盘空间浪费。常规做法是将表迁移至目标表空间,再通过 RESIZE 收缩原表空间数据文件,从而释放磁盘空间。
本文基于一次完整的实验操作记录,演示在达梦数据库中执行表空间瘦身的全过程:分析 JEECG 表空间的对象分布,使用目标表空间 JEECG_TEST,将 37 张表迁移过去,收缩 JEECG 表空间数据文件,再将表移回原表空间,并对比操作前后的表空间状态。
2 实验环境与初始状态
2.1 登录数据库
使用 disql 以 SYSDBA 身份登录数据库实例(端口 15236):
/dmdbms/bin/disql SYSDBA/’“Dameng@1234”’:15236
服务器[LOCALHOST:15236]:处于普通打开状态
登录使用时间 : 13.071(ms)
disql V8
实例名通过 SF_GET_PARA_STRING_VALUE 查询得到为 DM:
SQL> SELECT SF_GET_PARA_STRING_VALUE(1,'INSTANCE_NAME') AS 实例名;
2.2 查看表空间与数据文件
联合查询 VTABLESPACE 与 VDATAFILE,查看各表空间数据文件的路径、大小、剩余空间与使用率(执行号 1601):
SQL> SELECT SF_GET_PARA_STRING_VALUE(1,'INSTANCE_NAME') AS 实例名,A.NAME AS 表空间名,B.PATH AS 数据文件路径,(B.TOTAL_SIZE*PAGE/1024/1024)AS 文件大小MB,(B.FREE_SIZE*PAGE/1024/1024)AS 剩余大小MB,(CAST((B.TOTAL_SIZE-B.FREE_SIZE)*100/B.TOTAL_SIZE AS NUMERIC(2,0))||'%') AS 使用率,DECODE(B.AUTO_EXTEND,'0','关闭','1','打开') AS 自动扩展,B.NEXT_SIZE AS 扩展大小MB FROM V$TABLESPACE A,V$DATAFILE B WHERE A.ID = B.GROUP_ID;
查询结果显示,实验环境共有 6 个表空间。其中 JEECG 表空间的数据文件 /dmdata/DM/jeecg.DBF 大小为 512MB、剩余 407MB、使用率 20%,自动扩展已打开、扩展步长 2048MB,是本次瘦身操作的目标表空间。其余表空间的情况为:TEMP 74MB、使用率 4%;ROLL 128MB、使用率 8%;MAIN 128MB、使用率 0%;SYSTEM 276MB、使用率 56%。
3 分析 JEECG 表空间对象分布
通过 vextents、vsegment_infos、dba_objects、dba_indexes 关联查询,分析 JEECG 表空间中已分配簇对应的对象(只看已分配的簇,按簇 ID 倒序取前 20 条,执行号 1602):
SQL> select o.owner 模式名称,
e.extent_id 簇id,
case o.object_type
when 'INDEX' then (select i.table_name from dba_indexes i where i.index_name = o.object_name LIMIT 1)
when 'TABLE' then o.object_name
else null
end AS 表名
from v$extents e join v$segment_infos s on e.seg_id = e.seg_id join dba_objects o on o.object_id = s.obj_id join
dba_indexes i on i.index_name = o.object_name where e.ts_id = (select id from v$tablespace where name = 'JEECG')
and e.state <> 'FREE' -- 只看已分配的簇
order by extent_id desc limit 20;
查询返回 20 行。结果显示,JEECG 表空间承载了 QRTZ 定时任务系列表(如 QRTZ_FIRED_TRIGGERS、QRTZ_SIMPROP_TRIGGERS)以及大量业务表(如 sys_notice、plan_records、gen_table、gen_table_column、followup_records 等),同一对象可能占用多个簇。这些对象即为本次迁移的对象范围。
4 创建目标表空间与用户
创建目标表空间 jeecg_test(数据文件 jeecg_test.DBF,初始 1024MB,自动扩展、步长 1024MB、无上限),同时创建同名用户并授予 DBA 权限:
SQL> create tablespace jeecg_test datafile 'jeecg_test.DBF' SIZE 1024 autoextend on next 1024 maxsize unlimited;
SQL> create user jeecg_test identified by "Dameng@1234";
SQL> grant dba to jeecg_test;
执行结果:第一条 create tablespace 语句返回错误 [-3401] 表空间[JEECG_TEST]已存在,说明实验环境中已存在同名表空间,无需重复创建;create user 与 grant dba 语句均执行成功(执行号 1603、1604)。
第1 行附近出现错误[-3401]:表空间[JEECG_TEST]已存在.
操作已执行(执行号 1603、1604)
因此直接使用已存在的 jeecg_test 表空间作为本次迁移的目标表空间。
5 迁移表到目标表空间
5.1 迁移 QRTZ 系列表
第一批将 JEECG 表空间中的 10 张 QRTZ 系列表迁移至 JEECG_TEST:
SQL> ALTER TABLE JEECG.QRTZ_CALENDARS MOVE TABLESPACE JEECG_TEST;
SQL> ALTER TABLE JEECG.QRTZ_BLOB_TRIGGERS MOVE TABLESPACE JEECG_TEST;
SQL> ALTER TABLE JEECG.QRTZ_TRIGGERS MOVE TABLESPACE JEECG_TEST;
SQL> ALTER TABLE JEECG.QRTZ_JOB_DETAILS MOVE TABLESPACE JEECG_TEST;
SQL> ALTER TABLE JEECG.QRTZ_SCHEDULER_STATE MOVE TABLESPACE JEECG_TEST;
SQL> ALTER TABLE JEECG.QRTZ_CRON_TRIGGERS MOVE TABLESPACE JEECG_TEST;
SQL> ALTER TABLE JEECG.QRTZ_PAUSED_TRIGGER_GRPS MOVE TABLESPACE JEECG_TEST;
SQL> ALTER TABLE JEECG.QRTZ_SIMPLE_TRIGGERS MOVE TABLESPACE JEECG_TEST;
SQL> ALTER TABLE JEECG.QRTZ_SIMPROP_TRIGGERS MOVE TABLESPACE JEECG_TEST;
SQL> ALTER TABLE JEECG.QRTZ_FIRED_TRIGGERS MOVE TABLESPACE JEECG_TEST;
上述语句均返回操作已执行,迁移成功。
5.2 迁移业务表
第二批迁移 27 张业务表(带引号形式指定表名与目标表空间):
SQL> ALTER TABLE "JEECG"."sys_config" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sys_dept" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sequence_config" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."followup_records" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."gen_table" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."gen_table_column" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."plan_records" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sequence_record" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."db_deployment_info" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sys_dict_data" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sys_idgen_config" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sys_dict_type" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sys_job_log" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sys_job" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sys_logininfor" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sys_menu" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sys_notice" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sys_oper_log" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sys_post" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sys_role_dept" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sys_role" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sys_role_menu" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sys_user" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sys_user_online" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."QRTZ_LOCKS" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sys_user_role" MOVE TABLESPACE "JEECG_TEST";
SQL> ALTER TABLE "JEECG"."sys_user_post" MOVE TABLESPACE "JEECG_TEST";
上述语句均返回操作已执行,迁移成功。至此,共 37 张表从 JEECG 表空间迁入 JEECG_TEST 表空间。
5.3 确认迁移结果
查询 DBA_TABLES 确认迁移结果(执行号 1635):
SQL> select * from DBA_TABLES where tablespace_name = 'JEECG_TEST';
查询返回 10 行,均为 QRTZ 系列表(QRTZ_CALENDARS、QRTZ_BLOB_TRIGGERS、QRTZ_TRIGGERS、QRTZ_JOB_DETAILS、QRTZ_SCHEDULER_STATE、QRTZ_CRON_TRIGGERS、QRTZ_PAUSED_TRIGGER_GRPS、QRTZ_SIMPLE_TRIGGERS、QRTZ_SIMPROP_TRIGGERS、QRTZ_FIRED_TRIGGERS),状态均为 VALID。该查询发生在迁移过程中,反映的是首批 QRTZ 表的迁移结果。
6 收缩原表空间
6.1 设置 UNDO_RETENTION
收缩前,将回滚信息保留时间 UNDO_RETENTION 调整为 10 秒,促使过期的回滚信息尽快释放,便于后续观察回滚表空间的空间回收情况:
SQL> SP_SET_PARA_DOUBLE_VALUE(1, 'UNDO_RETENTION', 10);
DMSQL 过程已成功完成
6.2 生成索引重建语句
迁移后,通过 dba_indexes 检查 JEECG 表空间中是否仍存在索引,并拼装索引重建语句(执行号 1680):
SQL> SELECT 'ALTER INDEX "' || owner || '"."' || index_name || '" REBUILD JEECG_TEST;' AS rebuild_sql
FROM dba_indexes
WHERE tablespace_name = 'JEECG'
AND owner = 'JEECG';
查询返回未选定行,说明表迁移后 JEECG 表空间中已无残留索引,无需执行重建操作。
6.3 收缩数据文件
使用 RESIZE 将 JEECG 表空间的数据文件从 512MB 收缩至 128MB(执行号 1681):
SQL> ALTER TABLESPACE "JEECG" RESIZE DATAFILE '/dmdata/DM/jeecg.DBF' TO 128;
DMSQL 过程已成功完成
6.4 收缩后状态
再次执行表空间查询,收缩后的状态为:JEECG 数据文件 128MB、剩余 127MB、使用率 0%;JEECG_TEST 数据文件 1024MB、剩余 919MB、使用率 10%;ROLL 表空间使用率由 8% 升至 15%(回滚信息在 UNDO_RETENTION 调整后暂未完全释放);SYSTEM 仍为 56%。
7 将表移回原表空间
7.1 生成移回语句
通过 dba_tables 生成将表从 JEECG_TEST 移回 JEECG 的语句(执行号 1684):
SQL> SELECT 'ALTER TABLE "' || owner || '"."' || table_name || '" MOVE TABLESPACE "JEECG";' AS move_back_sql
FROM dba_tables
WHERE tablespace_name = 'JEECG_TEST'
AND owner = 'JEECG';
共生成 37 条移回语句,与迁出的表数量一致,覆盖了此前迁移的全部 QRTZ 表与业务表。
7.2 执行移回
按生成的语句顺序执行 37 条 ALTER TABLE … MOVE TABLESPACE 语句,全部返回操作已执行(执行号 1685 至 2421),移回操作完成。
8 最终状态对比与总结
8.1 表空间前后变化
实验结束时再次执行表空间查询(执行号 2422),各表空间状态为:JEECG 数据文件 2176MB、剩余 2071MB、使用率 4%;JEECG_TEST 数据文件 1024MB、剩余 1023MB、使用率 0%;TEMP 74MB、使用率 4%;ROLL 128MB、使用率 17%;MAIN 128MB、使用率 0%;SYSTEM 276MB、使用率 56%。
对比操作前后:JEECG 表空间数据文件由初始的 512MB(使用率 20%)收缩至 128MB(使用率 0%);37 张表移回后,128MB 无法容纳回迁数据,数据文件在自动扩展机制下扩展到 2176MB(使用率 4%),最终尺寸反而大于初始状态。JEECG_TEST 表空间在表全部移回后剩余空间由 919MB 回升至 1023MB,使用率降至 0%。
8.2 结论与注意事项
本次实验完整走通了表空间瘦身的常规流程,即分析对象分布、使用目标表空间、迁移表、收缩原表空间数据文件、再按需回迁。该流程适用于数据清理后需要压缩表空间占用空间的场景。
操作过程中有以下几点值得注意。第一,重复创建表空间报错 -3401 属正常提示,表示目标表空间已存在,直接使用即可。第二,MOVE TABLESPACE 移动的是表的数据段,索引归属会随移动发生变化,收缩前应通过 dba_indexes 确认原表空间是否还有残留索引。
第三,RESIZE 收缩目标不能小于表空间内数据实际占用的空间。第四,收缩前应评估回迁后的容量需求:本次实验中 JEECG 数据文件收缩至 128MB 后回迁 37 张表,因容量不足触发自动扩展(扩展步长 2048MB),数据文件由 128MB 扩展到 2176MB,最终空间占用反而大于初始的 512MB;若希望保持收缩效果,可在回迁前关闭自动扩展或预留足够空间。
第五,UNDO_RETENTION 影响回滚信息的保留时长,调整后回滚表空间的回收节奏会发生变化(实验中 ROLL 使用率由 8% 升至 17%),生产环境调整前需评估对依赖回滚信息的功能的影响。
文章
阅读量
获赞
