Oracle 删除数据后释放数据文件所占磁盘空间

测试的时候向数据库中插入了大量的数据,测试完成后删除了测试用户以及其全部数据,但是数据文件却没有缩小。经查阅资料之后发现这是 Oracle “高水位”所致,那么怎么把这些数据文件的大小降下来呢?解决办法如下:

概念:

表空间的相关知识请见这里,详细的介绍了 Oracle 数据库的存储结构。

高水位:High Water Mark (HWM),是段(Segment)的一个指标,界定了段(Segment)曾经配置过的 block 水位。

据说,随着数据的 insert,所使用段(Segment)的数据块(data block)也不断增加,这时候高水位(HWM)也随着上升。当数据被删除后(无论是 delete 还是 truncate table)虽然被占用的数据块(data block)已经相应减少,但是高水位(HWM)并不会随之下降。当高水位(HWM)下存在大量的空白数据块(data block)时,如果发生全表扫描(Full Table Scan, FTS)就会造成很多额外的 IO。因为全表扫描(FTS)的时候读取段(Segment)中的数据块(data block)会一直读取到高水位(HWM)才结束。高水位(HWM)就是段(Segment)中数据块(data block)有没有使用的分界线,所以全表扫描(FTS)所花费的时间不但不会因为数据的删除而减少,反而会增加。(关于此段查询效率的内容有待验证,笔者未亲自验证。不过可以确定的是高水位确实不会随着数据的删除而下降。)

降低高水位的正确做法是先降低HWM,再确定实际占有大小,再resize数据文件。

数据文件比较多,我们用其中一个较大的文件做为 Demo,其它数据文件如法炮制即可。我选择的文件是:D:\oracle\product\10.2.0\oradata\orcl\USERS01.DBF 1.4GB 左右。

1.登录 sqlplus:

语法:sqlplus username/[email protected]:port/sid

例:sqlplus system/[email protected]:1521/orcl

2.查询这个数据文件的编号:

SQL> select file#, name from v$datafile;

FILE# NAME
------------------------------------------------------------------------------------------

1 D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSTEM01.DBF

2 D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\UNDOTBS01.DBF

3 D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSAUX01.DBF

4 D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\USERS01.DBF

可以看到,我们要操作的数据文件的编号是4。

2.根据文件 ID 查询这个数据文件最大数据块(data block)的编号:(似乎这个最大编号可以代表该数据文件中数据块的数量,这一点有待考证。)

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

MAX(BLOCK_ID)
-------------
65673

3.计算该表空间实际占用的空间:

--查询数据块的大小,单位是 byte

SQL> show parameter db_block_size;

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_block_size integer 8192

--8192 byte = 8 kb

--接下来计算该表空间占用的物理空间

SQL> select 65673 * 8 / 1024 from dual;

65673*8/1024
------------
513.070313

--实际占用的物理空间是 513MB 多点

4.最后一步,把我们的数据文件尺寸修改得比这个表空间实际占用的物理空间大点就行了:

SQL> alter database datafile ‘D:\oracle\product\10.2.0\oradata\orcl\USERS01.DBF‘ resize 600m;

数据库已更改。

OK,数据文件从修改前的 1.4GB 变成了 600MB。对于其它的数据文件,大家也知道如何收缩了吧?

转载:http://www.cnblogs.com/chuyuhuashi/p/3548260.html

参考文献:

Oracle表空间(tablespaces)http://www.cnblogs.com/fnng/archive/2012/08/12/2634485.html

Oracle降低HWM的集中方法 http://hi.baidu.com/wschao2005/item/5383388fb2e21fc8b17154b1

修改oracle数据文件大小 http://www.2cto.com/database/201204/126864.html

oracle删除数据后,空间不释放如何解决??? http://bbs.csdn.net/topics/310046810

时间: 2024-12-13 05:59:03

Oracle 删除数据后释放数据文件所占磁盘空间的相关文章

Winform开窗,筛选数据后返回数据的方法

在开发中,经常需要打开另一个窗体(简写为"开窗"),然后在开窗中进行数据筛选,选中需要的数据,最后将值传递给本原来的窗体.而且,这个开窗可以重复用于多个地方,其效果如同日历控件的弹出窗口.如下图所示: 测试环境 vs2008 基本思路 1.创建一个窗体类. (1)为该类添加用于传递值的属性. (2)为该类添加一个事件,用于通知调用方值已经准备好. (3)在窗体类的某个函数中,如单元格双击处理函数中,为属性赋值,并引发这个事件. 2.调用该窗体类. (1)定义一个全局的窗体类对象. (2

du--查看文件or目录占磁盘空间

du  DIR:查看目录及目录下每个子目录和文件占磁盘空间的大小,都会一一显示出来 options:-h  以易读的方式显示 -s  只显示这个目录占磁盘空间的大小 -b  以byte方式显示大小,这时候是显示了文件or目录的真实大小 --max-depth=num ,只统计几级目录,1表示只统计该目录下的文件

Jquery 实现动态添加table tr 和删除tr 以及checkbox的全选 和 获取添加TR删除TR后的数据

关于jquery实现动态添加table tr的问题我也不多说了 上面代码很多地方都有注释的 关于返回的 编辑后的table 数据 我这里想说的是我直接把他保存成一个连接起来的字符串了 格式 str=XXX | XXX | XXX , XXX | XXX | XXX , XXX | XXX | XXX 你也可以保存成对象类型的  我是为了方便后台的操作才这样做的 话不多说直接代码: <html> <head> <meta http-equiv="Content-Typ

Spring-Batch处理MySQL数据后存到CSV文件

1 介绍 用Spring Batch实现了个简单的需求,从MySQL中读取用户表数据,根据生日计算年龄,将结果输出到csv文件. 1.1 准备表及数据 user test; DROP TABLE IF EXISTS `test_user`; CREATE TABLE `test_user` ( `id` int(11) NOT NULL auto_increment, `name` varchar(45) NOT NULL default '', `birthday` datetime defa

SQL 查询数据后行数据合并为列

SQL 将查询后得到的多行数据中的某一列转为一列,如原查找后的结果为: USER_NAME 张三 李四 王五 现要将其合并为: CUSTOMER 张三,李四,王五 SQL语句如下:select STUFF((select ','+USER_NAME from tbale where USER_NAME = '' for xml path('')), 1, 1, '') CUSTOMER 其中,stuff为sql封装好的一个方法函数,用于删除指定长度的字符并在指定的起始点插入另一组字符. 语法:S

C# DataGridView控件绑定数据后清空数据

在清除DataGridview的数据时: 1.DataSource为NULL(DataGridView.DataSource= null;)这样会将DataGridView的列也删掉. 2.用DataGridview.Rows.Clear();  提示"不能清除此列表"!!!!! 以上都不是想要的结果.想要满足保持原有的列,就是重新绑定之前的DataTable,然后清除DataTable中的数据,如下: DataTable  dt  =  (DataTable)dataGridView

mybatis+mysql insert添加数据后返回数据主键id

1.根据useGeneratedKeys获取返回值,部分数据库不支持 修改mybatis xml <insert id="insertUser" useGeneratedKeys="true" keyProperty="id" parameterType="com.entity.user"> insert into test (name) values (#{name}) </insert> useGe

sqlserver错误&quot;试图扩大物理文件时,MODIFY FILE 遇到操作系统错误 112(磁盘空间不足。)。&quot;处理

正常还原的时候报错: Microsoft SQL-DMO (ODBC SQLState: 42000)---------------------------试图扩大物理文件时,MODIFY FILE 遇到操作系统错误 112(磁盘空间不足.).未能创建一个或多个文件.请考虑使用 WITH MOVE 选项来标识有效位置.RESTORE DATABASE 操作异常终止. 但硬盘空间很足够! -------------------------------------------------------

关于mysql 删除数据后物理空间未释放

OPTIMIZE TABLE 当您的库中删除了大量的数据后,您可能会发现数据文件尺寸并没有减小.这是因为删除操作后在数据文件中留下碎片所致.OPTIMIZE TABLE 是指对表进行优化.如果已经删除了表的一大部分数据,或者如果已经对含有可变长度行的表(含有 VARCHAR . BLOB 或 TEXT 列的表)进行了很多更改,就应该使用 OPTIMIZE TABLE 命令来进行表优化.这个命令可以将表中的空间碎片进行合并,并且可以消除由于删除或者更新造成的空间浪费 .OPTIMIZE TABLE