千家信息网

缩小表空间文件,节省磁盘

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,在我管的系统中,数据库磁盘经常只剩下20G左右,以前是删除数据库服务器中的日志,日志做了定时清理之后,发现表空间经常出现表空间不足的情况,每次都是通过扩充表空间来解决问题,但是加了几次之后,服务器的磁
千家信息网最后更新 2026年11月01日缩小表空间文件,节省磁盘

在我管的系统中,数据库磁盘经常只剩下20G左右,以前是删除数据库服务器中的日志,日志做了定时清理之后,发现表空间经常出现表空间不足的情况,每次都是通过扩充表空间来解决问题,但是加了几次之后,服务器的磁盘不够用了,就开始清理数据库中的数据。清理了数据之后,发现表空间实际占用率很小,用不到那么多的磁盘,于是想到把用到的磁盘释放出来。

在处理的过程中,发现truncate表只能够减小表空间占用率,并不能释放磁盘通过请教别人,了解到有下面方法可以释放磁盘。


方法一:

查看表空间对应的数据文件大小

select FILE_NAME,FILE_ID,TABLESPACE_NAME,BYTES/1024/1024 mb,BLOCKS from dba_data_files where


TABLESPACE_NAME='TFR_DATA';

查看数据文件中数据处在最大位置

select max(block_id) from dba_extents where file_id=9;

计算表空间实际需要多大空间

select 1354880*8/1024 from dual;

设置表空间大小为该值

ALTER DATABASE DATAFILE '/u01/oradata/FOSSDB/datafile/o1_mf_tfr_data_9ymk9p5n_.dbf' RESIZE 10600M;

这种方法在我之前的文章中写到过。这种方法也是有缺陷的,表空间中实际没有很多数据,例如只有100M数据,但是这种方法resize的时候,发现只能够resize到10G左右,并没有释放出很大的空间。

方法二:

缩小数据文件尺寸报ORA-03297的处理办法

ORA-03297: 文件包含在请求的 RESIZE 值以外使用的数据


最近历史数据库磁盘空间不足,而有一个表空间有50个G容量,但是实际只占100m的空间,

使用ALTER TABLE table SHRINK SPACE CASCAD后大部分数据文件可以调整,当试图调整其中一个数据文件尺寸的时候报

RA-03297: file contains used data beyond requested RESIZE value

说明这个文件不能通过降低hwm来释放空间了。******************************************



数据库版本:oracle 10.2.1

--找到数据文件对应的文件号*********

SQL>select file#,name from v$datafile where name like '%BASEINFO.dbf';

5 /data/eucpdb/eucpdb/BASEINFO.dbf


找到文件中最大的块号

SQL>select max(block_id) from dba_extents where file_id=5 ;************************


1213833


--查看数据库块大小

SQL>show parameter db_block_size


db_block_size integer 8192


计算一下文件中最大使用块占用的位置

SQL>select 1213833*8/1024 from dual;


9483.0703125 M


--为了验证上面做法的准确性,下面做一个试验


--调整前数据文件大小为10000M

--现在调整数据库文件为9500M

SQL>ALTER DATABASE DATAFILE '/data/eucpdb/eucpdb/BASEINFO.dbf' RESIZE 9500M

2 /


数据库已更改


--调整文件为 9400m


SQL>ALTER DATABASE DATAFILE '/data/eucpdb/eucpdb/BASEINFO.dbf' RESIZE 9400M

2 /



SQL> ALTER DATABASE DATAFILE '/data/eucpdb/eucpdb/BASEINFO.dbf' RESIZE 9400M;

ALTER DATABASE DATAFILE '/data/eucpdb/eucpdb/BASEINFO.dbf' RESIZE 9400M

*

第 1 行出现错误:

ORA-03297: 文件包含在请求的 RESIZE 值以外使用的数据


--看来了上面的计算是准确的

解决方法

查看表空间中有哪些对象

select * from DBA_SEGMENTS where TABLESPACE_NAME='BASEINFO';

select * from DBA_tables;



select FILE_NAME,FILE_ID,TABLESPACE_NAME,BYTES/1024/1024 mb,BLOCKS from dba_data_files where


TABLESPACE_NAME='TFR_DATA';

查看FILE_ID


SQL> select segment_name,segment_type,tablespace_name,extent_id,bytes,blocks from dba_extents where file_id=5 and block_id='1213833';


SEGMENT_NAME SEGMENT_TYPE TABLESPACE_NAME EXTENT_ID BYTES BLOCKS

------------------------------ ------------------ ------------------------------ ---------- ---------- ----------

REGISTRYINFO TABLE BASEINFO 25 524288 64


SQL>


SQL> ALTER TABLE eucpmanager.REGISTRYINFO SHRINK SPACE CASCADE;


表已更改。



创建一个新的表空间,把block_id比较高的几个表移出表空间


SQL> CREATE SMALLFILE TABLESPACE "BASEINFO_BAK" DATAFILE '/data/eucpdb/eucpdb/baseinfo_bak.dbf' SIZE 100M LOGGING EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO

2 /


表空间已创建。



SQL> alter user eucpmanager quota unlimited on BASEINFO_BAK;


用户已更改。使得数据库中表的所属用户能够操作新建的表空间。否则不能把表移到新的表空间中



把block_id比较高的几个表移动到新的表空间


SELECT DISTINCT SEGMENT_NAME FROM DBA_EXTENTS WHERE TABLESPACE_NAME='BASEINFO' AND FILE_ID=5 and segment_type='TABLE' ;


SQL> SELECT distinct 'alter table '|| SEGMENT_NAME||' move tablespace baseinfo_bak; ' FROM DBA_EXTENTS WHERE TABLESPACE_NAME='BASEINFO' AND FILE_ID=5 and segment_type='TABLE' ;


'ALTERTABLE'||SEGMENT_NAME||'MOVETABLESPACEBASEINFO_BAK;'

----------------------------------------------------------------------------------------------------------------------------

alter table ENTERPRISESERVICEINFO move tablespace baseinfo_bak;

alter table REGISTRYFEEDETAILEX move tablespace baseinfo_bak;

alter table ENTERPRISEROUTE move tablespace baseinfo_bak;

alter table REGISTRYAUTHINFO move tablespace baseinfo_bak;

alter table ENTERPRISEBASEINFO move tablespace baseinfo_bak;


SQL> alter table ENTERPRISESERVICEINFO move tablespace baseinfo_bak;

alter table REGISTRYFEEDETAILEX move tablespace baseinfo_bak;

alter table ENTERPRISEROUTE move tablespace baseinfo_bak;

alter table REGISTRYAUTHINFO move tablespace baseinfo_bak;

alter table ENTERPRISEBASEINFO move tablespace baseinfo_bak;

表已更改。


SQL>

表已更改。


SQL>

表已更改。


SQL>

表已更改。


告警日志中会出现下面的内容,索引需要重建

Thu Apr 24 14:20:21 2008

Some indexes or index [sub]partitions of table EUCPMANAGER.ENTERPRISEBASEINFO have been marked unusable



把下面的执行结果的语句执行所有重建

SELECT distinct 'alter INDEX '|| SEGMENT_NAME||' REBUILD TABLESPACE BASEINFO_BAK; ' FROM DBA_EXTENTS WHERE TABLESPACE_NAME='BASEINFO' AND FILE_ID=5 and segment_type='INDEX' ;

alter INDEX PK_ENTERPRISEBASEINFO REBUILD TABLESPACE BASEINFO_BAK;

alter INDEX PK_REGISTRYINFO REBUILD TABLESPACE BASEINFO_BAK;

alter INDEX PK_REGISTRYFEEDETAILEX REBUILD TABLESPACE BASEINFO_BAK;

alter INDEX UNI_REGISTRYAUTHINFO REBUILD TABLESPACE BASEINFO_BAK;

alter INDEX UNI_REGISTRYAUTHINFO REBUILD TABLESPACE BASEINFO_BAK;

alter INDEX UNI_REGISTRYAUTHINFO REBUILD TABLESPACE BASEINFO_BAK;

alter INDEX UNI_REGISTRYAUTHINFO REBUILD TABLESPACE BASEINFO_BAK;

alter INDEX UNI_REGISTRYAUTHINFO REBUILD TABLESPACE BASEINFO_BAK;



再次修改数据文件大小



SQL> select max(block_id) from dba_extents where file_id=5 ;


MAX(BLOCK_ID)

-------------

3209


SQL> ALTER DATABASE DATAFILE '/data/eucpdb/eucpdb/BASEINFO.dbf' RESIZE 1000m;


数据库已更改。


数据库文件的空间已经调整成功了


SQL>


--把挪走的表在挪回来



SQL> alter table ENTERPRISESERVICEINFO move tablespace baseinfo;

alter table REGISTRYFEEDETAILEX move tablespace baseinfo;

alter table ENTERPRISEROUTE move tablespace baseinfo;

alter table REGISTRYAUTHINFO move tablespace baseinfo;

alter table ENTERPRISEBASEINFO move tablespace baseinfo;

alter table registryinfo move tablespace baseinfo;

表已更改。


SQL>

表已更改。



--重建索引

SQL>

SQL>

SQL> ALTER INDEX PK_REGISTRYINFO REBUILD TABLESPACE BASEINFO;

ALTER INDEX AK_REGISTRYCODE_REGISTRYINFO REBUILD TABLESPACE BASEINFO;

ALTER INDEX PK_ENTERPRISEBASEINFO REBUILD TABLESPACE BASEINFO;

ALTER INDEX PK_ENTERPRISESERVICEINFO REBUILD TABLESPACE BASEINFO;

ALTER INDEX UNI_REGISTRYAUTHINFO REBUILD TABLESPACE BASEINFO;

ALTER INDEX PK_REGISTRYFEEDETAILEX REBUILD TABLESPACE BASEINFO;


索引已更改。



SQL> SELECT COUNT(*) FROM DBA_SEGMENTS WHERE TABLESPACE_NAME='BASEINFO_BAK' ;


COUNT(*)

----------

0


已经没有对象在新建的这个表空间了。现在删除掉


SQL> drop tablespace baseinfo_bak;


表空间已删除。


但是,在操作的过程中,出现一个非常难搞的问题,

SELECT COUNT(*) FROM DBA_EXTENDS WHERE TABLESPACE_NAME='USERS' ;


COUNT(*)

----------

0


select max(block_id) from dba_extents where file_id=9;

这样查看也是什么都没有,但是resize的时候就是报错,ORA-03297: 文件包含在请求的 RESIZE 值以外使用的数据。

处理方法:

SQL> SELECT COUNT(*) FROM DBA_SEGMENTS WHERE TABLESPACE_NAME='USERS' ;

这里要查看DBA_SEGMENTS,DBA_TABLES,DBA_INDEX这几个表,DBA_EXTENTS太小了,不全面,查看的时候发现数据虽然删除了,但是保留在了回收站中,要在PLSQL命令窗口执行如下命令 purge dba_recyclebin.执行后就能够resize了。

这是绝对百度不到的,问别人也不好想到这里。还是要经验呀。

这样查看表空间中的对象为0,

到此调整已经结束了。

其实调整方法有很多,如用imp/exp等




异常处理


查看一个表属于哪个用户

select owner from dba_tables where table_name='表名';

SQL> create tablespace wulili datafile '/u01/app/oracle/oradata/dpweb/wulili.dbf' size 1024M autoextend on;

create tablespace wulili datafile '/u01/app/oracle/oradata/dpweb/wulili.dbf' size 1024M autoextend on

ERROR at line 1:

ORA-01119: error in creating database file '/u01/app/oracle/oradata/dpweb/wulili.dbf'

ORA-27040: file create error, unable to create file

Linux-x86_64 Error: 2: No such file or directory

Additional information: 1

solution:give exact path of datafile inplace of $ORACLE_HOME.


like

Create Tablespace CLOUD_DATA datafile '/u01/app/oradata/cloud_data01.dbf' size 1000M

SQL> alter table tb_auto shrink space;

alter table tb_auto shrink space

*

第 1 行出现错误:

ORA-10636: ROW MOVEMENT is not enabled

SQL> alter table tb_auto enable row movement;

数据 空间 文件 数据库 方法 调整 磁盘 大小 实际 时候 处理 最大 对象 日志 用户 索引 面的 位置 命令 尺寸 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 花魁咖啡 奇酷互联网科技公司 善班互联网科技有限公司 蓝色互联网科技 上海电发互联网科技有限公司 中国互联网有什么科技含量 以后互联网后是啥科技 顶级互联网科技成果有哪些 移动互联网科技股 厦门比较好的科技互联网公司 互联网金融科技展 沐思想互联网科技有限公司 互联网企业科技类企业如何做账 郑州欣桑互联网科技有限公司 长沙渺峰互联网科技有限公司 同城互联网络科技 互联网科技职业技能培训学校 互联网时代高科技布局 广东猫王互联网科技有限公司电话 如何强化互联网金融科技 涨乐互联网科技 圆梦互联网科技 小马过河互联网科技 腾讯科技 互联网女皇 沃里互联网科技 朱啸虎曾投资哪些互联网科技企业 特约风豹互联网科技为什么扣费 烟台灵鸽互联网科技有限公司 半导体行业属于互联网高科技类吗 平安好医生打造互联网科技医疗
0