deallocate unused :僅適用于釋放HWM高水位以上的空間,而無(wú)法釋放高水位以下的空間;比如對(duì)表預(yù)分配的空間
創(chuàng)新互聯(lián)公司主要從事網(wǎng)頁(yè)設(shè)計(jì)、PC網(wǎng)站建設(shè)(電腦版網(wǎng)站建設(shè))、wap網(wǎng)站建設(shè)(手機(jī)版網(wǎng)站建設(shè))、成都響應(yīng)式網(wǎng)站建設(shè)公司、程序開(kāi)發(fā)、網(wǎng)站優(yōu)化、微網(wǎng)站、小程序定制開(kāi)發(fā)等,憑借多年來(lái)在互聯(lián)網(wǎng)的打拼,我們?cè)诨ヂ?lián)網(wǎng)網(wǎng)站建設(shè)行業(yè)積累了豐富的做網(wǎng)站、成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、網(wǎng)絡(luò)營(yíng)銷(xiāo)經(jīng)驗(yàn),集策劃、開(kāi)發(fā)、設(shè)計(jì)、營(yíng)銷(xiāo)、管理等多方位專(zhuān)業(yè)化運(yùn)作于一體。
使用說(shuō)明和方法,官方文檔有說(shuō)明,如下:
Use the deallocate_unused_clause to explicitly deallocate unused space at the end of
a database object segment and make the space available for other segments in the
tablespace.
You can deallocate unused space using the following statements:
■ ALTER CLUSTER (see ALTER CLUSTER on page 10-5)
■ ALTER INDEX: to deallocate unused space from the index, an index partition, or an
index subpartition (see ALTER INDEX on page 10-78)
■ ALTER MATERIALIZED VIEW: to deallocate unused space from the overflow segment
of an index-organized materialized view (see ALTER MATERIALIZED VIEW on
page 11-3)
■ ALTER TABLE: to deallocate unused space from the table, a table partition, a table
subpartition, the mapping table of an index-organized table, the overflow segment
of an index-organized table, or a LOB storage segment (see ALTER TABLE on
page 12-2)
一、測(cè)試環(huán)境:
Oracle11.2.0.4
使用admin用戶(hù)在test表空間新建一張測(cè)試分區(qū)表,并提前對(duì)子分區(qū)預(yù)分配一些空間,然后插入少量的數(shù)據(jù),最后使用:alter table .....deallocate unused;來(lái)釋放未使用的空間
二、開(kāi)始測(cè)試
①:查看測(cè)試環(huán)境表空間使用情況:
SQL> set linesize 2500 SQL> set pagesize 300 SQL> select a.tablespace_name "表空間名稱(chēng)",100 - round((nvl(b.bytes_free, 0) / a.bytes_alloc) * 100, 2) "占用率(%)",round(a.bytes_alloc / 1024 / 1024, 2) "容量(M)",round(nvl(b.bytes_free, 0) / 1024 / 1024, 2) "空閑(M)",round((a.bytes_alloc - nvl(b.bytes_free, 0)) / 1024 / 1024, 2) "使用(M)",to_char(sysdate, 'yyyy-mm-dd hh34:mi:ss') "采樣時(shí)間" from (select f.tablespace_name,sum(f.bytes) bytes_alloc,sum(decode(f.autoextensible, 'YES', f.maxbytes, 'NO', f.bytes)) maxbytes from dba_data_files f group by tablespace_name) a,(select f.tablespace_name, sum(f.bytes) bytes_free from dba_free_space f group by tablespace_name) b where a.tablespace_name = b.tablespace_name order by 2 desc; ??????????????? ?????????(%) ??????(M) ??????(M) ??????(M) ???????????? ------------------------------ ------------ ---------- ---------- ---------- ------------------- SYSAUX 94.41 510 28.5 481.5 2017-08-07 17:01:20 SYSTEM 93.24 800 54.06 745.94 2017-08-07 17:01:20 USERS 26.25 5 3.69 1.31 2017-08-07 17:01:20 UNDOTBS1 17.97 470 385.56 84.44 2017-08-07 17:01:20 TEST .05 20480 20470 10 2017-08-07 17:01:20
SQL> show user USER is "ADMIN" ----測(cè)試用的用戶(hù)
②:創(chuàng)建測(cè)試分區(qū)表:test_emp
SQL> create table test_emp (TMP_UPSTATE_CASEKEY char(14),TMP_NUM_STATUS_ID number(38),updated_date date) 2 partition by range(TMP_NUM_STATUS_ID) 3 (partition pt_1 values less than(1000000) ) nologging; Table created.
③:給pt_1分區(qū)表預(yù)分配10G的空間:
SQL> alter table test_EMP modify PARTITION pt_1 ALLOCATE EXTENT (size 10240m); Table altered.
④:收集該分區(qū)表的統(tǒng)計(jì)信息,并查看該表的block塊占用情況
SQL> exec dbms_stats.gather_table_stats(ownname =>'ADMIN',tabname =>'TEST_EMP',cascade=>TRUE); PL/SQL procedure successfully completed. SQL> select B.SEGMENT_NAME, B.blocks,B.blocks * 8096 / 1024 / 1024, A.BLOCKS,A.blocks * 8096 / 1024 / 1024, A.EMPTY_BLOCKS from user_tables a, USER_SEGMENTS B WHERE TABLE_NAME = 'TEST_EMP' AND A.TABLE_NAME = B.SEGMENT_NAME; SEGMENT_NAME BLOCKS B.BLOCKS*8096/1024/1024 BLOCKS A.BLOCKS*8096/1024/1024 EMPTY_BLOCKS --------------------------------------------------------------------------------- ---------- ----------------------- ---------- ----------------------- ------------ TEST_EMP 1315840 10159.5313 0 0 0 SQL> SELECT segment_name, SUM(bytes) / 1024 / 1024 Mbytes FROM dba_segments WHERE PARTITION_NAME = 'PT_1' GROUP BY segment_name; SEGMENT_NAME MBYTES --------------------------------------------------------------------------------- ---------- TEST_EMP 10288 BIN$VibHVCPfDL/gU8gCqMDDfw==$0 8
---從上面可以看出,test_emp分區(qū)表的大小是10G,而占用的blocks有1315840個(gè);
⑤:向分區(qū)表插入一些數(shù)據(jù),并查看該表的大小
SQL> create or replace procedure proc_casekey_upstate 2 as 3 casekey char(14); 4 begin 5 for i in 1..10000 loop 6 casekey := 'TMP'||lpad(i,7,0); 7 insert into test_emp values(casekey, 1, sysdate); 8 end loop; 9 commit; 10 end; 11 / Procedure created. SQL> exec proc_casekey_upstate; ---執(zhí)行存儲(chǔ)過(guò)程插入數(shù)據(jù) PL/SQL procedure successfully completed. SQL> exec dbms_stats.gather_table_stats(ownname =>'ADMIN',tabname =>'TEST_EMP',cascade=>TRUE); ---收集該表的統(tǒng)計(jì)信息 PL/SQL procedure successfully completed. SQL> select B.SEGMENT_NAME, B.blocks,B.blocks * 8096 / 1024 / 1024, A.BLOCKS,A.blocks * 8096 / 1024 / 1024, A.EMPTY_BLOCKS from user_tables a, USER_SEGMENTS B WHERE TABLE_NAME = 'TEST_EMP' AND A.TABLE_NAME = B.SEGMENT_NAME; SEGMENT_NAME BLOCKS B.BLOCKS*8096/1024/1024 BLOCKS A.BLOCKS*8096/1024/1024 EMPTY_BLOCKS --------------------------------------------------------------------------------- ---------- ----------------------- ---------- ----------------------- ------------ TEST_EMP 1315840 10159.5313 46 .355163574 0 SQL> SELECT segment_name, SUM(bytes) / 1024 / 1024 Mbytes FROM dba_segments WHERE PARTITION_NAME = 'PT_1' GROUP BY segment_name; SEGMENT_NAME MBYTES --------------------------------------------------------------------------------- ---------- TEST_EMP 10288 BIN$VibHVCPfDL/gU8gCqMDDfw==$0 8
--注意:從上面可以看出,該表的大小是10G,但是該表占用blocks只有46個(gè),顯然 有很多空間沒(méi)有被使用,
⑥:釋放未被使用的空間(我對(duì)該操作過(guò)了10046事件,在實(shí)際操作中只需執(zhí)行:alter table test_emp modify partition pt_1 deallocate unused; )
SQL> alter session set tracefile_identifier='10046'; SQL> alter session set events '10046 trace name context forever,level 12'; ---開(kāi)啟10046事件 Session altered. SQL> SQL> alter table test_emp modify partition pt_1 deallocate unused; ---執(zhí)行該命令釋放子分區(qū)未被使用的空間; Table altered. SQL> alter session set events '10046 trace name context off'; ---關(guān)閉10046事件 Session altered. SQL> select value from v$diag_info where name='Default Trace File'; VALUE -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- /opt/oracle/diag/rdbms/dbs/dbs/trace/dbs_ora_3263_10046.trc
⑦:驗(yàn)證空間是否被釋放:
SQL> select B.SEGMENT_NAME, B.blocks,B.blocks * 8096 / 1024 / 1024, A.BLOCKS,A.blocks * 8096 / 1024 / 1024, A.EMPTY_BLOCKS from user_tables a, USER_SEGMENTS B WHERE TABLE_NAME = 'TEST_EMP' AND A.TABLE_NAME = B.SEGMENT_NAME; SEGMENT_NAME BLOCKS B.BLOCKS*8096/1024/1024 BLOCKS A.BLOCKS*8096/1024/1024 EMPTY_BLOCKS --------------------------------------------------------------------------------- ---------- ----------------------- ---------- ----------------------- ------------ TEST_EMP 1024 7.90625 46 .355163574 0 SQL> SELECT segment_name, SUM(bytes) / 1024 / 1024 Mbytes FROM dba_segments WHERE PARTITION_NAME = 'PT_1' GROUP BY segment_name; SEGMENT_NAME MBYTES --------------------------------------------------------------------------------- ---------- TEST_EMP 16 BIN$VibHVCPfDL/gU8gCqMDDfw==$0 8 ------------------------------ ------------ ---------- ---------- ---------- ------------------- SYSAUX 94.44 510 28.38 481.63 2017-08-07 17:19:30 SYSTEM 93.24 800 54.06 745.94 2017-08-07 17:19:30 USERS 26.25 5 3.69 1.31 2017-08-07 17:19:30 UNDOTBS1 5.73 470 443.06 26.94 2017-08-07 17:19:30 TEST .05 20480 20470 10 2017-08-07 17:19:30
從上面可以看出,該表的大小變成了16M,而blocks也有1024個(gè);表未被使用的空間已經(jīng)釋放,而且表空間可用大小也已經(jīng)變大: