前言
在达梦数据库使用中,建议对数据库表空间使用进行规划,业务用户创建单独的表空间使用。
如果不创建单独的用户表空间会遇到什么问题呢?通过下面的问题和测试说明合理的表空间规划是有必要的。
问题
某开发项目组使用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进行缩容释放磁盘空间。