问题起因:
同事从生产导出一个dmp,给新系统测试用。由于测试环境的表空间比较紧张。先用delete清空掉了部分表的数据,
发现表空间没有释放。接着又执行了truncate,但奇怪的是truncdate后这些表所占的表空间并没有释放。
最后发现是INITIAL_EXTENT在作怪。
下面模拟一下问题的现象,及解决过程。
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as testtest
--1.T_IMP_TRUNCATE表中没有数据。
SQL> select count(1) from T_IMP_TRUNCATE;
COUNT(1)
----------
0
--2.但T_IMP_TRUNCATE占用了104MB的空间
SQL> SELECT SUM(T.BYTES) / 1024 / 1024 MB
2 FROM USER_SEGMENTS T
3 WHERE T.SEGMENT_NAME = 'T_IMP_TRUNCATE';
MB
----------
104
--3.truncate掉表T_IMP_TRUNCATE
SQL> truncate table T_IMP_TRUNCATE;
Table truncated
--4.分析表T_IMP_TRUNCATE
SQL> ANALYZE TABLE T_IMP_TRUNCATE COMPUTE STATISTICS;
Table analyzed
--5.发现表空间依然没有释放
SQL> SELECT SUM(T.BYTES) / 1024 / 1024 MB
2 FROM USER_SEGMENTS T
3 WHERE T.SEGMENT_NAME = 'T_IMP_TRUNCATE';
MB
----------
104
--6.检查T_IMP_TRUNCATE表的INITIAL_EXTENT参数将近100MB
SQL> SELECT T.TABLE_NAME, T.INITIAL_EXTENT/1024/1024 mb
2 FROM USER_TABLES T
3 WHERE T.TABLE_NAME = 'T_IMP_TRUNCATE'
4 ;
TABLE_NAME MB
------------------------------ ----------
T_IMP_TRUNCATE 99.0
--7.决定对T_IMP_TRUNCATE表进行收缩shrink
--a.启用行迁移
SQL> alter table T_IMP_TRUNCATE enable row movement;
--b.shrink表T_IMP_TRUNCATE
SQL> alter TABLE T_IMP_TRUNCATE shrink SPACE;
--c.关闭行迁移
SQL> alter table T_IMP_TRUNCATE DISABLE row movement;
Table altered
--8.shrink后T_IMP_TRUNCATE表空间已释放
SQL> SELECT SUM(T.BYTES) / 1024 / 1024 MB
2 FROM USER_SEGMENTS T
3 WHERE T.SEGMENT_NAME = 'T_IMP_TRUNCATE';
MB
----------
0.1875
SQL>