首先,可以通过下面的sql statement来查看表空间的使用情况。注意,该语句是在10g下测试过。

  1. SELECT
  2. FREE.TABLESPACE_NAME, FREE.FREE_SPACE/TOTAL.TOTAL_SPACE
  3. FROM (select TABLESPACE_NAME,sum(bytes)/1024/1024 AS FREE_SPACE from dba_free_space group by TABLESPACE_NAME) FREE,
  4. (select TABLESPACE_NAME,sum(BYTES)/1024/1024 AS TOTAL_SPACE from dba_data_files group by TABLESPACE_NAME) TOTAL
  5. WHERE
  6. FREE.TABLESPACE_NAME=TOTAL.TABLESPACE_NAME;

  

在知道了表空间的使用情况后,我们可能希望对一些表空间做清理,使其datafile的尺寸变小。这时我们的做法是清理掉一些比较大的表,然后用resize命令来减小datafile的大小。

比如

truncate table scott.big;

alter database datafile '/opt/oradata/orcl/user.dbf' resize 10M;

但是有时你会遇到下面的这种情况。

  1. ERROR at line 1:
  2. ORA-03297: file contains used data beyond requested RESIZE value

  

这个错误看起来像是说你的datafile中没有足够的空间释放,但其实未必。下面通过实验来了解这个错误。

请耐心看完实验过程。

首先创建表空间和用户

  1. SQL> CREATE TABLESPACE reclaim_ts DATAFILE '/opt/oratop/oradata/c21upg10/reclaim_ts01.dbf' SIZE 1M AUTOEXTEND ON NEXT 1M;
  2.  
  3. Tablespace created.
  4.  
  5. SQL> CREATE USER reclaim_user IDENTIFIED BY reclaim_user DEFAULT TABLESPACE reclaim_ts QUOTA UNLIMITED ON reclaim_ts;
  6.  
  7. User created.
  8.  
  9. SQL> GRANT CREATE SESSION, CREATE TABLE TO reclaim_user;
  10.  
  11. Grant succeeded.
  12.  
  13. SQL> GRANT select on dba_objects to reclaim_user;
  14.  
  15. Grant succeeded.

然后创建表t1

  1. SQL> CONN reclaim_user/reclaim_user
  2. Connected.
  3. SQL> create table t1 as select * from dba_objects;
  4.  
  5. Table created.

创建完表后我们用sys登陆查看一下表空间中 extent的情况。

  1. SQL> SELECT segment_type, segment_name , FILE_ID, BLOCK_ID,blocks,BYTES/1024/1024 from dba_extents WHERE owner = 'RECLAIM_USER' order by block_id;
  2.  
  3. SEGMENT_TYPE SEGMENT_NAME FILE_ID BLOCK_ID BLOCKS BYTES/1024/1024
  4. ------------------------------------------------------ ---------------------------- ---------- ---------- ---------- ---------------
  5. TABLE T1 54 9 8 .0625
  6. TABLE T1 54 17 8 .0625
  7. TABLE T1 54 25 8 .0625
  8. TABLE T1 54 33 8 .0625
  9. TABLE T1 54 41 8 .0625
  10. TABLE T1 54 49 8 .0625
  11. TABLE T1 54 57 8 .0625
  12. TABLE T1 54 65 8 .0625
  13. TABLE T1 54 73 8 .0625
  14. TABLE T1 54 81 8 .0625
  15. TABLE T1 54 89 8 .0625
  16. TABLE T1 54 97 8 .0625
  17. TABLE T1 54 105 8 .0625
  18. TABLE T1 54 113 8 .0625
  19. TABLE T1 54 121 8 .0625
  20. TABLE T1 54 129 8 .0625
  21. TABLE T1 54 137 128 1
  22. TABLE T1 54 265 128 1
  23. TABLE T1 54 393 128 1
  24. TABLE T1 54 521 128 1
  25. TABLE T1 54 649 128 1
  26. TABLE T1 54 777 128 1

看到从block 9 开始 到 block 777 这一部分连续的block是t1占用的。 之前的8个block应该是datafile自己占用的。

然后我们再创建一个表t2,该表和t1一样 都是从dba_objects创建

  1. SQL> create table t2 as select * from dba_objects;
  2.  
  3. Table created.

OK, 创建完毕后用sys登陆一个session 把datafile 改成 autoextend off。

  1. SQL> alter database datafile '/opt/oratop/oradata/c21upg10/reclaim_ts01.dbf' AUTOEXTEND off;
  2.  
  3. Database altered.

这时候再去查看一下extent的使用情况

  1. SQL> SELECT segment_type, segment_name , FILE_ID, BLOCK_ID,blocks,BYTES/1024/1024 from dba_extents WHERE owner = 'RECLAIM_USER' order by block_id;
  2.  
  3. SEGMENT_TYPE SEGMENT_NAME FILE_ID BLOCK_ID BLOCKS BYTES/1024/1024
  4. ------------------------------------------------------ ---------------------------- ---------- ---------- ---------- ---------------
  5. TABLE T1 54 9 8 .0625
  6. TABLE T1 54 17 8 .0625
  7. TABLE T1 54 25 8 .0625
  8. TABLE T1 54 33 8 .0625
  9. TABLE T1 54 41 8 .0625
  10. TABLE T1 54 49 8 .0625
  11. TABLE T1 54 57 8 .0625
  12. TABLE T1 54 65 8 .0625
  13. TABLE T1 54 73 8 .0625
  14. TABLE T1 54 81 8 .0625
  15. TABLE T1 54 89 8 .0625
  16. TABLE T1 54 97 8 .0625
  17. TABLE T1 54 105 8 .0625
  18. TABLE T1 54 113 8 .0625
  19. TABLE T1 54 121 8 .0625
  20. TABLE T1 54 129 8 .0625
  21. TABLE T1 54 137 128 1
  22. TABLE T1 54 265 128 1
  23. TABLE T1 54 393 128 1
  24. TABLE T1 54 521 128 1
  25. TABLE T1 54 649 128 1
  26. TABLE T1 54 777 128 1
  27. TABLE T2 54 905 8 .0625
  28. TABLE T2 54 913 8 .0625
  29. TABLE T2 54 921 8 .0625
  30. TABLE T2 54 929 8 .0625
  31. TABLE T2 54 937 8 .0625
  32. TABLE T2 54 945 8 .0625
  33. TABLE T2 54 953 8 .0625
  34. TABLE T2 54 961 8 .0625
  35. TABLE T2 54 969 8 .0625
  36. TABLE T2 54 977 8 .0625
  37. TABLE T2 54 985 8 .0625
  38. TABLE T2 54 993 8 .0625
  39. TABLE T2 54 1001 8 .0625
  40. TABLE T2 54 1009 8 .0625
  41. TABLE T2 54 1017 8 .0625
  42. TABLE T2 54 1025 8 .0625
  43. TABLE T2 54 1033 128 1
  44. TABLE T2 54 1161 128 1
  45. TABLE T2 54 1289 128 1
  46. TABLE T2 54 1417 128 1
  47. TABLE T2 54 1545 128 1
  48. TABLE T2 54 1673 128 1

紧跟着T1的extent,从block 905开始到1673 是T2占用的。要注意T1在datafile中是排在T2的前面的。两个 表都占用896个block。出去segment就是888个block。

我们看一下现在datafile 的大小

  1. myserver[/export/home/oratop ] du -sh /opt/oratop/oradata/c21upg10/reclaim_ts01.dbf
  2. 15M /opt/oratop/oradata/c21upg10/reclaim_ts01.dbf

现在我们把T1 truncate掉,然后再看该数据文件中extent的使用情况

  1. SQL> conn reclaim_user/reclaim_user
  2. Connected.
  3. SQL> truncate table t1;
  4.  
  5. Table truncated.
  1. SQL> SELECT segment_type, segment_name , FILE_ID, BLOCK_ID,blocks,BYTES/1024/1024 from dba_extents WHERE owner = 'RECLAIM_USER' order by block_id;
  2.  
  3. SEGMENT_TYPE SEGMENT_NAME FILE_ID BLOCK_ID BLOCKS BYTES/1024/1024
  4. ------------------------------------------------------ ---------------------------- ---------- ---------- ---------- ---------------
  5. TABLE T1 54 9 8 .0625
  6. TABLE T2 54 905 8 .0625
  7. TABLE T2 54 913 8 .0625
  8. TABLE T2 54 921 8 .0625
  9. TABLE T2 54 929 8 .0625
  10. TABLE T2 54 937 8 .0625
  11. TABLE T2 54 945 8 .0625
  12. TABLE T2 54 953 8 .0625
  13. TABLE T2 54 961 8 .0625
  14. TABLE T2 54 969 8 .0625
  15. TABLE T2 54 977 8 .0625
  16. TABLE T2 54 985 8 .0625
  17. TABLE T2 54 993 8 .0625
  18. TABLE T2 54 1001 8 .0625
  19. TABLE T2 54 1009 8 .0625
  20. TABLE T2 54 1017 8 .0625
  21. TABLE T2 54 1025 8 .0625
  22. TABLE T2 54 1033 128 1
  23. TABLE T2 54 1161 128 1
  24. TABLE T2 54 1289 128 1
  25. TABLE T2 54 1417 128 1
  26. TABLE T2 54 1545 128 1
  27. TABLE T2 54 1673 128 1

可以看到T1除了一个 一个segment header不再占用block。 查看dba_free_space也可以看到

  1. SQL> select BLOCK_ID,BLOCKS,BYTES/1024/1024 from dba_free_space where file_id=54;
  2.  
  3. BLOCK_ID BLOCKS BYTES/1024/1024
  4. ---------- ---------- ---------------
  5. 17 888 6.9375
  6. 1801 120 .9375

这个视图的第一个free空间从第17个block开始共888个block。这是t1 truncate释放掉的,共6.9M。

第二个free空间从1801开始用120个block,这是T2到datafile的结尾处的空闲部分。

ok, 既然现在T1释放了6.9M, 结尾处还有接近0.9M的空间,那么我把文件缩小6m 也就是缩小到 15-6=9M 不过分吧?

我们试一下

  1. SQL> alter database datafile '/opt/oratop/oradata/c21upg10/reclaim_ts01.dbf' resize 9m;
  2. alter database datafile '/opt/oratop/oradata/c21upg10/reclaim_ts01.dbf' resize 9m
  3. *
  4. ERROR at line 1:
  5. ORA-03297: file contains used data beyond requested RESIZE value

有错误,显示不行。 resize这个选项只能把datafile中最后一部分free space释放出来。 向T1的这部分free space 因为是在中间,所以没办法释放。但是如果是后面的这0.9M,我们就可以释放掉。

  1. SQL> SELECT 14.1*1024 FROM DUAL;
  2.  
  3. 14.1*1024
  4. ----------
  5. 14438.4
  6.  
  7. SQL> alter database datafile '/opt/oratop/oradata/c21upg10/reclaim_ts01.dbf' resize 14439K;
  8.  
  9. Database altered.

  

那么,这种情况我们怎么处理呢?

两种方法

1. 创建新的表空间

2. move segment到新的表空间

3. drop原来的表空间

4. rename新的表空间使其名字和原来相同

让我们试试。

创建表空间

  1. SQL> create tablespace test DATAFILE '/opt/oratop/oradata/c21upg10/reclaim_ts_01_reorganize.dbf' size 1m autoextend on next 1m;
  2.  
  3. Tablespace created.

给用户赋权让用户可以在新的表空间创建表

  1. SQL> alter user reclaim_user default tablespace test;
  2.  
  3. User altered.
  4.  
  5. SQL> grant unlimited tablespace to reclaim_user;
  6.  
  7. Grant succeeded.

移动原来的表

  1. SQL> alter table reclaim_user.t1 move tablespace test;
  2.  
  3. Table altered.
  4.  
  5. SQL> alter table reclaim_user.t2 move tablespace test;
  6.  
  7. Table altered.

删掉原来的表空间

  1. SQL> DROP TABLESPACE reclaim_ts INCLUDING CONTENTS AND DATAFILES;
  2.  
  3. Tablespace dropped.

重命名表空间并修改datafile

  1. SQL> alter tablespace test rename to reclaim_ts;
  2.  
  3. Tablespace altered.
  4.  
  5. SQL> alter database datafile '/opt/oratop/oradata/c21upg10/reclaim_ts_01_reorganize.dbf' autoextend off;
  6.  
  7. Database altered.

查看数据文件大小

  1. myserver[/export/home/oratop ] du -sh /opt/oratop/oradata/c21upg10/reclaim_ts_01_reorganize.dbf
  2. 9.0M /opt/oratop/oradata/c21upg10/reclaim_ts_01_reorganize.dbf

  

查看表空间使用率及shrink 表空间的更多相关文章

  1. [转] 使用SQL脚本查看表空间使用率和使用dba_tablespace_usage_metrics视图的差别

    传统的SQL脚本查看表空间使用率,使用的关键视DBA_DATA_FILE和DBA_FREE_SPACE. Oracle 11g引入了DBA_TABLESPACE_USAGE_METRICS视图.其实, ...

  2. db2 查看表空间使用率

    1. 统计所有节点表空间使用率 select substr(TABLESPACE_NAME,1,20) as TBSPC_NAME,bigint(TOTAL_PAGES * PAGE_SIZE)/10 ...

  3. oracle表空间使用率统计查询

    今天发现有一张采样表从1月5号开始不记录数据了,所以想查看一下表空间使用率,在网上零零散散找了很多资料,现在记录如下,也不知道哪一个最准确.还有一个就是网上拷贝的sql代码格式太乱了,不好看,找到一个 ...

  4. SYSAUX表空间使用率高问题处理

    SYSAUX表空间做为SYSTEM表空间的辅助表空间,主要存放EM相关的内容以及表统计信息,AWR快照,审计信息等,而假设SYSAUX表空间在默认条件下你假设不做不论什么配置,随着时间的推移.会膨胀的 ...

  5. Oracle 11gR2 Database UNDO表空间使用率居高不下处理

    一.UNDO表空间监控图 Prometheus监控的到UNDO表空间使用率超过90%(90%为所有表空间告警阈值).从图中可以看到,多次增加UNDO表空间的DATAFILE,UNDO表空间达到40GB ...

  6. (转)oracle表空间使用率统计查询

    转自:http://www.cnblogs.com/xwdreamer/p/3511047.html 参考文献 文献1:http://blog.itpub.net/24104518/viewspace ...

  7. Oracle 11gR2 Database UNDO表空间使用率居高不下-转载

    客户的数据库是Oracle Database 11.2.0.3.0 for AIX 6.1 64bit的单机数据库.客户查询DBA_FREE_SPACE发现UNDO表空间的使用率高达98%以上.客户的 ...

  8. 查看Oracle当前用户下的信息(用户,表视图,索引,表空间,同义词,存储过程函数,约束条件)

    0.表空间 SQL>select username,default_tablespace from user_users; 查看当前用户的角色 SQL>select * from user ...

  9. [记录]Zabbix3.4配置监控Oracle12c的存活状态和表空间使用率

    Zabbix3.4配置监控Oracle的存活状态和表空间使用率 1.安装zabbix3.4 agent: # rpm -ivh http://repo.zabbix.com/zabbix/3.4/rh ...

随机推荐

  1. 406 Queue Reconstruction by Height 根据身高重建队列

    假设有打乱顺序的一群人站成一个队列. 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数. 编写一个算法来重建这个队列.注意:总人数少于1100人.示 ...

  2. Android Programming 3D Graphics with OpenGL ES (Including Nehe's Port)

    https://www3.ntu.edu.sg/home/ehchua/programming/android/Android_3D.html

  3. dive into python:模块的导入和搜索文件路径的配置

    1.Python中导入模块:import sys:相当于Java中的导入包.类. 比如,我们导入sys模块,使用:import sys; 2.Python中调用函数的时候,会从默认配置的库文件夹中(s ...

  4. self和super的区别

    (1)self调用自己方法,super调用父类方法 (2)self是类,super是预编译指令 (3)[self class]和[super class]输出是一样的 ①当使用 self 调用方法时, ...

  5. MySQL详解(18)-----------分页方法总结

    ---方法1: 直接使用数据库提供的SQL语句---语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N---适应场景: 适用于数据量较少的情况(元组百/千 ...

  6. PHP7中session_start 使用注意事项,会导致浏览器刷时页面数据不更新

    //PHP7中session_start 使用注意事项, session_start([ 'cache_limiter' => 'private', //在读取完毕会话数据之后马上关闭会话存储文 ...

  7. ecpilse将Web项目转变为Java工程

    转需: 用Eclipse开发项目的时候,把一个Web项目导入到Eclipse里会变成了一个Java工程,将无法在Tomcat中进行部署运行. 以下为将Java工程转变为Web项目的方法: 1.找到项目 ...

  8. HDU_1874_畅通工程续_最短路问题

    畅通工程续 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  9. 前端零基础快速入门JavaScript

    JavaScript代码可以直接嵌在网页的任何地方,不过通常我们都把JavaScript代码放到<head>中: <html><head> <script&g ...

  10. TypeError: 'TestCase' object is not iterable

    这个异常呢其实是因为我对list没有足够熟悉 我一开始很疑惑,明明已经正确返回testcase对象了呀,为啥会报TypeError: 'TestCase' object is not iterable ...