MOVE降低高水位 HWM



--创建实验表空间

SQL> create tablespace andy03 datafile '/home/oracle/app/oradata/orcl/andy03.dbf'  size 10M autoextend on next 30M; 

--创建实验数据

SQL> create table andy03 tablespace andy03  as select * from dba_objects ; 

SQL> insert into   andy03   select * from dba_objects ;

SQL> commit;

SQL> select BYTES/1024/1024,MAXBYTES/1024/1024 from Dba_Data_Files where tablespace_name ='ANDY03'; 

-- 模拟系列高水位变化

SQL>col name for a30

SQL> 

SELECT UPPER(F.TABLESPACE_NAME) " name",

D.TOT_GROOTTE_MB " size(M)",

D.TOT_GROOTTE_MB - F.TOTAL_BYTES " used(M)",

TO_CHAR(ROUND((D.TOT_GROOTTE_MB - F.TOTAL_BYTES) / D.TOT_GROOTTE_MB * 100,2),'990.99') || '%' "percent",

F.TOTAL_BYTES "current_free_size(M)",

(SELECT free_space_mb+free_allocate_mb FROM dba_tablespace_free a where a.tablespace_name= f.tablespace_name) "total_ FREE_size",

D.TOT_GROOTTE_MB - F.MAX_BYTES "HWM(M)"

FROM (SELECT TABLESPACE_NAME,

ROUND(SUM(BYTES) / (1024 * 1024), 2) TOTAL_BYTES,

ROUND(MAX(BYTES) / (1024 * 1024), 2) MAX_BYTES

FROM SYS.DBA_FREE_SPACE

GROUP BY TABLESPACE_NAME) F,

(SELECT DD.TABLESPACE_NAME,

ROUND(SUM(DD.BYTES) / (1024 * 1024), 2) TOT_GROOTTE_MB

FROM SYS.DBA_DATA_FILES DD

GROUP BY DD.TABLESPACE_NAME) D

WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME

and f.tablespace_name='ANDY03'

ORDER BY 3 desc;



 name                             size(M)    used(M) percent  current_free_size(M) total_ FREE_size  HWM(M)

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

ANDY03                                 40         22   55.00%                   18       32745.9844      22



SQL> create table andy04 tablespace andy03 as select * from dba_objects; 

SQL> 

SELECT UPPER(F.TABLESPACE_NAME) " name",

D.TOT_GROOTTE_MB " size(M)",

D.TOT_GROOTTE_MB - F.TOTAL_BYTES " used(M)",

TO_CHAR(ROUND((D.TOT_GROOTTE_MB - F.TOTAL_BYTES) / D.TOT_GROOTTE_MB * 100,2),'990.99') || '%' "percent",

F.TOTAL_BYTES "current_free_size(M)",

(SELECT free_space_mb+free_allocate_mb FROM dba_tablespace_free a where a.tablespace_name= f.tablespace_name) "total_ FREE_size",

D.TOT_GROOTTE_MB - F.MAX_BYTES "HWM(M)"

FROM (SELECT TABLESPACE_NAME,

ROUND(SUM(BYTES) / (1024 * 1024), 2) TOTAL_BYTES,

ROUND(MAX(BYTES) / (1024 * 1024), 2) MAX_BYTES

FROM SYS.DBA_FREE_SPACE

GROUP BY TABLESPACE_NAME) F,

(SELECT DD.TABLESPACE_NAME,

ROUND(SUM(DD.BYTES) / (1024 * 1024), 2) TOT_GROOTTE_MB

FROM SYS.DBA_DATA_FILES DD

GROUP BY DD.TABLESPACE_NAME) D

WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME

and f.tablespace_name='ANDY03'

ORDER BY 3 desc;

name                             size(M)    used(M) percent  current_free_size(M) total_ FREE_size  HWM(M)

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

ANDY03                                 40         33   82.50%                    7       32734.9844      33



SQL> truncate table andy03;



SQL> 

SELECT UPPER(F.TABLESPACE_NAME) " name",

D.TOT_GROOTTE_MB " size(M)",

D.TOT_GROOTTE_MB - F.TOTAL_BYTES " used(M)",

TO_CHAR(ROUND((D.TOT_GROOTTE_MB - F.TOTAL_BYTES) / D.TOT_GROOTTE_MB * 100,2),'990.99') || '%' "percent",

F.TOTAL_BYTES "current_free_size(M)",

(SELECT free_space_mb+free_allocate_mb FROM dba_tablespace_free a where a.tablespace_name= f.tablespace_name) "total_ FREE_size",

D.TOT_GROOTTE_MB - F.MAX_BYTES "HWM(M)"

FROM (SELECT TABLESPACE_NAME,

ROUND(SUM(BYTES) / (1024 * 1024), 2) TOTAL_BYTES,

ROUND(MAX(BYTES) / (1024 * 1024), 2) MAX_BYTES

FROM SYS.DBA_FREE_SPACE

GROUP BY TABLESPACE_NAME) F,

(SELECT DD.TABLESPACE_NAME,

ROUND(SUM(DD.BYTES) / (1024 * 1024), 2) TOT_GROOTTE_MB

FROM SYS.DBA_DATA_FILES DD

GROUP BY DD.TABLESPACE_NAME) D

WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME

and f.tablespace_name='ANDY03'

ORDER BY 3 desc;



 name                             size(M)    used(M) percent  current_free_size(M) total_ FREE_size  HWM(M)

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

ANDY03                                 40      12.06   30.15%                27.94       32755.9244   19.06



-- 说明truncate table后,统计信息发生了变化,查询的 HWM 不是真实的(此时 HWM 值 = 表空间大小 - 表空间对象实际物理空间总和)。

SQL> alter database datafile 10 resize 20M;

alter database datafile 10 resize 20M

*

ERROR at line 1:

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



-- 执行成功说明 真实的 HWM 为历史上实际最大值(33 M 为上面操作查询的值)。

SQL> alter database datafile 10 resize 33M;



Database altered.



-- 查询指定表空间内对象的块号

SQL> select  segment_name,block_id,blocks FROM dba_extents where Tablespace_name ='ANDY03' order by block_id desc;

-- 查询表空间内所有对象

SQL> col SEGMENT_NAME for a25

SQL> 

SELECT t.owner, t.segment_name,SUM(bytes)/1024/1024 "SIZE(M)", t.SEGMENT_TYPE From dba_segments t

WHERE t.tablespace_name = 'ANDY03'

GROUP BY t.owner,t.segment_name,t.SEGMENT_TYPE

ORDER BY SUM(bytes) desc;



OWNER                          SEGMENT_NAME                 SIZE(M) SEGMENT_TYPE

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

SYS                            ANDY04                            11 TABLE

SYS                            ANDY03                         .0625 TABLE



-- 一一开启所有对象 move 。 (按对象 block_id 由小到大 依次 move)



SQL> alter table andy04  move;



说明:

table在进行move操作时,我们只能对它进行select的操作。反过来说,当我们的一个session对table进行DML操作且没有commit时,  

在另一个session中是不能对这个table进行move操作的,否则oracle会返回这样的错误信息:ORA-00054  

  

SQL> 

SELECT UPPER(F.TABLESPACE_NAME) " name",

D.TOT_GROOTTE_MB " size(M)",

D.TOT_GROOTTE_MB - F.TOTAL_BYTES " used(M)",

TO_CHAR(ROUND((D.TOT_GROOTTE_MB - F.TOTAL_BYTES) / D.TOT_GROOTTE_MB * 100,2),'990.99') || '%' "percent",

F.TOTAL_BYTES "current_free_size(M)",

(SELECT free_space_mb+free_allocate_mb FROM dba_tablespace_free a where a.tablespace_name= f.tablespace_name) "total_ FREE_size",

D.TOT_GROOTTE_MB - F.MAX_BYTES "HWM(M)"

FROM (SELECT TABLESPACE_NAME,

ROUND(SUM(BYTES) / (1024 * 1024), 2) TOTAL_BYTES,

ROUND(MAX(BYTES) / (1024 * 1024), 2) MAX_BYTES

FROM SYS.DBA_FREE_SPACE

GROUP BY TABLESPACE_NAME) F,

(SELECT DD.TABLESPACE_NAME,

ROUND(SUM(DD.BYTES) / (1024 * 1024), 2) TOT_GROOTTE_MB

FROM SYS.DBA_DATA_FILES DD

GROUP BY DD.TABLESPACE_NAME) D

WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME

and f.tablespace_name='ANDY03'

ORDER BY 3 desc;



name                             size(M)    used(M) percent  current_free_size(M) total_ FREE_size  HWM(M)

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

ANDY03                                 33      12.06   36.55%                20.94       32755.9244      13

-- move后,可resize 。 (原因 block_id 发生了变化)

SQL>  alter database datafile 10 resize 13M;



Database altered.



SQL> 

SELECT UPPER(F.TABLESPACE_NAME) " name",

D.TOT_GROOTTE_MB " size(M)",

D.TOT_GROOTTE_MB - F.TOTAL_BYTES " used(M)",

TO_CHAR(ROUND((D.TOT_GROOTTE_MB - F.TOTAL_BYTES) / D.TOT_GROOTTE_MB * 100,2),'990.99') || '%' "percent",

F.TOTAL_BYTES "current_free_size(M)",

(SELECT free_space_mb+free_allocate_mb FROM dba_tablespace_free a where a.tablespace_name= f.tablespace_name) "total_ FREE_size",

D.TOT_GROOTTE_MB - F.MAX_BYTES "HWM(M)"

FROM (SELECT TABLESPACE_NAME,

ROUND(SUM(BYTES) / (1024 * 1024), 2) TOTAL_BYTES,

ROUND(MAX(BYTES) / (1024 * 1024), 2) MAX_BYTES

FROM SYS.DBA_FREE_SPACE

GROUP BY TABLESPACE_NAME) F,

(SELECT DD.TABLESPACE_NAME,

ROUND(SUM(DD.BYTES) / (1024 * 1024), 2) TOT_GROOTTE_MB

FROM SYS.DBA_DATA_FILES DD

GROUP BY DD.TABLESPACE_NAME) D

WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME

and f.tablespace_name='ANDY03'

ORDER BY 3 desc;



 name                             size(M)    used(M) percent  current_free_size(M) total_ FREE_size  HWM(M)

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

ANDY03                                 13      12.06   92.77%                  .94       32755.9244   12.06