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

简介:

在我管的系统中,数据库磁盘经常只剩下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;


本文转自aaa超超aaa 51CTO博客,原文链接:http://blog.51cto.com/10983441/1791131

相关文章
|
Java 开发者 Spring
Spring Cloud Gateway 中,过滤器的分类有哪些?
Spring Cloud Gateway 中,过滤器的分类有哪些?
603 3
|
数据可视化 Ubuntu 机器人
WebViz可视化工具的应用
WebViz可视化 Webviz是一个基于Web的可视化工具,意味着您可以通过浏览器/APP访问它,而不需要安装额外的软件。这对于远程访问和团队协作非常方便。 Foxglove是一个开源的工具包,包括线上和线下版。旨在简化机器人系统的开发和调试。它提供了一系列用于构建机器人应用程序的功能。 本节将介绍如何使用Foxglove进行数据查看,以及话题通信。 为了实现OriginBot与Foxglove的连接,我们需要在OriginBot上搭建ROS环境。请确保您的机器人是OriginBot(视觉版/导航版),并且您的PC运行的是Ubuntu(≥20.04)或Windows(>=10)。
311 6
|
前端开发 图形学 开发者
【独家揭秘】那些让你的游戏瞬间鲜活起来的Unity UI动画技巧:从零开始打造动态按钮,提升玩家交互体验的绝招大公开!
【9月更文挑战第1天】在游戏开发领域,Unity 是最受欢迎的游戏引擎之一,其强大的跨平台发布能力和丰富的功能集让开发者能够迅速打造出高质量的游戏。优秀的 UI 设计对于游戏至关重要,尤其是在手游市场,出色的 UI 能给玩家留下深刻的第一印象。Unity 的 UGUI 系统提供了一整套解决方案,包括 Canvas、Image 和 Button 等组件,支持添加各种动画效果。
1271 3
|
Oracle 关系型数据库
Oracle中decode 以及ROW_NUMBER() OVER() 函数等其它相关函数用法
Oracle中decode 以及ROW_NUMBER() OVER() 函数等其它相关函数用法
596 0
|
数据安全/隐私保护 Python
Python中的MD5加密“解密”
Python中的MD5加密“解密”
623 0
|
Rust 安全 JavaScript
Rust 和 WebAssembly 搞大事啦!代码在浏览器中运行,这波操作简直逆天!
【8月更文挑战第31天】《Rust 与 WebAssembly:将 Rust 代码运行在浏览器中》介绍了 Rust 和 WebAssembly 的强大结合。Rust 是一门安全高效的编程语言,而 WebAssembly 则是新兴的网页技术标准,两者结合使得 Rust 代码能在浏览器中运行,带来更高的性能和安全性。文章通过示例代码展示了如何将 Rust 函数编译为 WebAssembly 格式并在网页中调用,从而实现复杂高效的应用程序,同时确保了内存安全性和跨平台兼容性,为开发者提供了全新的可能性。
648 0
|
缓存 监控 Linux
Linux系统的tty架构及UART驱动详解
Linux系统的tty架构及UART驱动详解
2865 0
|
存储 网络协议 网络安全
RTMP协议详解及Wiresahrk抓包分析(一)
RTMP协议详解及Wiresahrk抓包分析
1920 2
|
域名解析 安全 Java
SpringBoot启动的时候初始化的线程池默认配置tomcat
SpringBoot启动的时候初始化的线程池默认配置tomcat
1033 1