oracle回收表空间
发布时间:2018-12-04
有时可能我们会有这样一个需求,客户说某个表空间基本不用了,让我们对其进行空间回收。我们查询到表空间使用率确实很低,只有百分之几。
那么我们应该怎么样去把其他的那些空间回收回来呢?
这时,如果我们直接对数据文件进行resize,可能会报错。
ALTER DATABASE DATAFILE 'D:\ora_tablespace\GCOMM2.dbf' RESIZE 5000M;
ORA-03297: file contains used data beyond requested RESIZE value
分析原因:
数据库最大块的block_id较大:
SELECT MAX(block_id)
FROM dba_extents
WHERE tablespace_name = 'GCOMM2';
MAX(BLOCK_ID)
-------------
994816
也就是说,目前我们能回收表空间到当前最大块之后,db_block_size=8192
SELECT 994816*8192/1024/1024 FROM dual;
994816*8192/1024/1024
---------------------
7772
即我们当前resize最多只能resize到7772M左右。
1.此时,我们可以将该表空间中的数据通过expdp导出来tablespace=GCOMM2,然后在数据库中删除该表空间includ content,再重建较小的表空间,再把数据impdp导入进去。
2.找到block最大的对象,将其移动到其他表空间,再次进行resize。
比如我要reisize到50M,则需要将block_id>6400的所有对象移动到其他表空间。然后再次进行resize操作。
SELECT distinct owner,segment_name
FROM dba_extents
WHERE tablespace_name = 'GCOMM2'
AND segment_type = 'TABLE'
AND file_id = 11
AND block_id > 6400;
那么我们应该怎么样去把其他的那些空间回收回来呢?
这时,如果我们直接对数据文件进行resize,可能会报错。
ALTER DATABASE DATAFILE 'D:\ora_tablespace\GCOMM2.dbf' RESIZE 5000M;
ORA-03297: file contains used data beyond requested RESIZE value
分析原因:
数据库最大块的block_id较大:
SELECT MAX(block_id)
FROM dba_extents
WHERE tablespace_name = 'GCOMM2';
MAX(BLOCK_ID)
-------------
994816
也就是说,目前我们能回收表空间到当前最大块之后,db_block_size=8192
SELECT 994816*8192/1024/1024 FROM dual;
994816*8192/1024/1024
---------------------
7772
即我们当前resize最多只能resize到7772M左右。
1.此时,我们可以将该表空间中的数据通过expdp导出来tablespace=GCOMM2,然后在数据库中删除该表空间includ content,再重建较小的表空间,再把数据impdp导入进去。
2.找到block最大的对象,将其移动到其他表空间,再次进行resize。
比如我要reisize到50M,则需要将block_id>6400的所有对象移动到其他表空间。然后再次进行resize操作。
SELECT distinct owner,segment_name
FROM dba_extents
WHERE tablespace_name = 'GCOMM2'
AND segment_type = 'TABLE'
AND file_id = 11
AND block_id > 6400;