达梦数据库MAIN表空间导致磁盘满问题的处理和总结

前言

在达梦数据库使用中,建议对数据库表空间使用进行规划,业务用户创建单独的表空间使用。

如果不创建单独的用户表空间会遇到什么问题呢?通过下面的问题和测试说明合理的表空间规划是有必要的。

问题

某开发项目组使用DM8 1-2-192 版本。近期发现数据库目录所在磁盘已满,想通过删除【drop table】部分表释放磁盘空间,发现磁盘空间没有释放,咨询如何释放磁盘空间。

通过操作系统命令df -h逐步查询确认是哪个文件占用磁盘空间大,是数据文件还是其他文件占用的磁盘空间比较大,如下截图是MAIN.DBF文件占用236G,导致/u01目录使用率超90%触发磁盘告警。

通过管理工具查看MAIN表空间使用率,经查MAIN表空间使用率是0.25%,截图如下:

通过面截图说明项目组删除的表之前在MAIN表空间内使用的簇已经释放,但是表空间对应的MAIN.DBF数据文件占用磁盘空间并没有变化。这现象和DM8 管理员手册[DM 逻辑结构概述]章节中释放后的簇被视为空闲簇,可以供其他对象使用描述是一致的。也就是说删除表会在空间内部释放簇,不会改变表空间数据文件大小。

接下来尝试通过RESIZE缩小MAIN表空间来释放MAIN表空间数据文件磁盘空间。

通过RESIZE缩容MAIN表空间失败,如下截图所示,报错【无法回收簇】:

MAIN表空间满无法通过RESIZE回收,那么其他表空间是否可以呢?

接下来我们测试验证下。

测试

在测试环境使用DM8 1-2-192 版本库创建表空间TEST进行resize测试。测试的思路模拟MAIN表空间使用和回收场景,在TEST表空间创建测试表,写入大量数据,然后删除测试表,再RESIZE缩小表空间。

创建TEST表空间,关闭自动扩展,设置大小为128M。

复制代码
SQL> create tablespace "TEST" datafile '/dm8/data/TEST01.DBF' size 128 autoextend off;
操作已执行
已用时间: 57.363(毫秒). 执行号:4689300.
SQL>

通过系统命令du -sm查看TEST表空间TEST01.DBF文件大小是128M。

复制代码
[dmdba@owumvyu4iuuzaxxp-0004 data]$ du -sm *
2504    DAMENG
2000    DM01
64      LCPTTBS01.DBF
64      LCPTTBS02.DBF
100     TEMP01.DBF
128     TEST01.DBF
[dmdba@owumvyu4iuuzaxxp-0004 data]$

创建测试表TEST.TAB01:

复制代码
SQL> CREATE TABLE TEST.TAB01
(
ID INT,
NAME CLOB
)
STORAGE(ON TEST);
操作已执行
已用时间: 6.792(毫秒). 执行号:4694900.
SQL>

通过下面程序向测试表TEST.TAB01写入数据,直到报错【磁盘空间不足】。

复制代码
SQL> declare
begin
  for i in 1..10000 loop
      insert into TEST.TAB01 values(1,lpad('表空间',30000,'缩容测试'));
          commit;
  end loop;
end;
[-523]:磁盘空间不足.
已用时间: 00:00:08.835. 执行号:0.
SQL>

通过下面SQL语句查看TEST表空间使用率:

复制代码
SELECT a.tablespace_name "表空间名称",
total / (1024 * 1024) "表空间大小(M)",
free / (1024 * 1024) "表空间剩余大小(M)",
(total - free) / (1024 * 1024 ) "表空间使用大小(M)",
total / (1024 * 1024 * 1024) "表空间大小(G)",
free / (1024 * 1024 * 1024) "表空间剩余大小(G)",
(total - free) / (1024 * 1024 * 1024) "表空间使用大小(G)",
round((total - free) / total, 4) * 100 "使用率 %"
FROM (SELECT tablespace_name, SUM(bytes) free
FROM dba_free_space
GROUP BY tablespace_name) a,
(SELECT tablespace_name, SUM(bytes) total
FROM dba_data_files
GROUP BY tablespace_name) b
WHERE a.tablespace_name = b.tablespace_name;

结果如下,TEST表空间使用率是93.65%:

删除TEST.TAB01测试表:

复制代码
SQL> drop table TEST.TAB01;
操作已执行
已用时间: 15.803(毫秒). 执行号:4694906.
SQL>

再次查看TEST表空间使用率为0.78%:

查看TEST表空间数据文件大小为128M,同样没有因为drop表释放磁盘空间。

复制代码
[dmdba@owumvyu4iuuzaxxp-0004 data]$ du -sm *
2504    DAMENG
2000    DM01
64      LCPTTBS01.DBF
64      LCPTTBS02.DBF
100     TEMP01.DBF
128     TEST01.DBF
[dmdba@owumvyu4iuuzaxxp-0004 data]$

尝试RESIZE缩容TEST表空间大小:

复制代码
SQL> ALTER TABLESPACE TEST RESIZE DATAFILE '/dm8/data/TEST01.DBF' to 64;
操作已执行
已用时间: 34.071(毫秒). 执行号:4723300.
SQL> quit

查看TEST表空间数据文件大小,显示已经成功RESIZE 为64M,相当于释放了64M磁盘空间。

复制代码
[dmdba@owumvyu4iuuzaxxp-0004 data]$ du -sm *
2504    DAMENG
2000    DM01
64      LCPTTBS01.DBF
64      LCPTTBS02.DBF
100     TEMP01.DBF
64      TEST01.DBF

总结

通过上面问题和测试说明DM8 1-2-192 版本创建MAIN之外的数据库表空间是可以通过RESIZE进行缩容释放磁盘空间,但是MAIN表空间无法通过RESIZE进行缩容释放磁盘空间。

针对上面MAIN表空间导致磁盘满问题,建议项目组将数据先导出,删除实例和数据文件,再初始化新实例,创建单独用户表空间再导入数据,释放磁盘空间也合理的使用表空间。

为了方便表空间维护管理,再次建议要合理地规划并创建单独的表空间用来存放业务数据,如果遇到磁盘满可以通过RESIZE进行缩容释放磁盘空间。

相关推荐
艾德金的溪1 小时前
redis-7.4.6部署安装
前端·数据库·redis·缓存
小光学长1 小时前
基于Vue的2025年哈尔滨亚冬会志愿者管理系统5zqg6m36(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
前端·数据库·vue.js
我的offer在哪里2 小时前
Redis
数据库·redis·缓存
点灯小铭2 小时前
基于单片机的多模式自动洗衣机设计与实现
数据库·单片机·嵌入式硬件·毕业设计·课程设计
潜心编码2 小时前
基于python的仓库管理系统
数据库
herinspace2 小时前
如何设置电脑分辨率和显示缩放
服务器·数据库·智能手机·电脑
biubiubiu07062 小时前
Ubuntu中定时任务测试
数据库·postgresql
程序新视界3 小时前
在MySQL中,一条SQL语句的执行全流程是怎样的?
数据库·后端·mysql
todoitbo4 小时前
我用 TRAE 做了一个不一样的 MySQL MCP
数据库·mysql·adb·ai工具·mcp·trae·mysql-mcp