Oracle9i - move

在 Oracle10g 中,可以使用 shrink 來收縮表,而在 Oracle9i 中,可以使用 move:
 
SQL> select * from v$version;
 
BANNER
--------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
PL/SQL Release 9.2.0.1.0 - Production
CORE    9.2.0.1.0       Production
TNS for 32-bit Windows: Version 9.2.0.1.0 - Production
NLSRTL Version 9.2.0.1.0 - Production
-- 創建測試表
SQL> create table test_yct as select * from dba_objects;
 
表已創建。
 
SQL> insert into test_yct select * from test_yct;
 
已創建29607行。
 
SQL> /
 
已創建59214行。
 
SQL> /
 
已創建118428行。
 
SQL> /
 
已創建236856行。
 
SQL> commit;
 
提交完成。
 
-- 查看錶的數據量和存儲空間大小
SQL> select count(*) from test_yct;
 
  COUNT(*)
----------
    473712
 
SQL> select bytes/1024/1024 from user_segments where segment_name='TEST_YCT';
 
BYTES/1024/1024
---------------
             51
 
-- 刪除部分數據,再次查看該表:存儲空間不變。
SQL> delete test_yct where rownum < 400000;
 
已刪除399999行。
 
SQL> commit;
 
提交完成。
 
SQL> select count(*) from test_yct;
 
  COUNT(*)
----------
     73713
 
SQL> select bytes/1024/1024 from user_segments where segment_name='TEST_YCT';
 
BYTES/1024/1024
---------------
             51
-- move 該表,存儲空間被收縮
SQL> alter table test_yct move;
 
表已更改。
 
SQL> select count(*) from test_yct;
 
  COUNT(*)
----------
     73713
 
SQL> select bytes/1024/1024 from user_segments where segment_name='TEST_YCT';
 
BYTES/1024/1024
---------------
              8
 
move 的原理,就是在該表空間上再開闢一個新的臨時段,來重新裝載一份這個表的數據,裝載完畢後,再刪除舊段。類似於 create table ... as select * from ...。所以要注意該表空間中有足夠的空間來存儲新的數據段。下面我測試一個空間不夠的情況:
 
-- 創建表空間、用戶,及測試表
SQL> create tablespace tp_movetest datafile 'd:\tp_movetest1.dbf' size 60m;
 
表空間已創建。
 
SQL> create user movetest identified by test default tablespace tp_movetest;
 
用戶已創建
 
SQL> grant dba to movetest;
 
授權成功。
 
SQL> conn movetest/test
已連接。
SQL> create table test_yct as select * from dba_objects;
 
表已創建。
 
SQL> insert into test_yct select * from test_yct;
 
已創建29608行。
 
SQL> /
 
已創建59216行。
 
SQL> /
 
已創建118432行。
 
SQL> /
 
已創建236864行。
 
SQL> commit;
 
提交完成。
 
SQL> select count(*) from test_yct;
 
  COUNT(*)
----------
    473728
 
SQL> select bytes/1024/1024 from user_segments where segment_name='TEST_YCT';
 
BYTES/1024/1024
---------------
             51
 
-- 刪除數據:存儲空間並沒有收縮
SQL> delete test_yct where rownum < 300000;
 
已刪除299999行。
 
SQL> commit;
 
提交完成。
 
SQL> select bytes/1024/1024 from user_segments where segment_name='TEST_YCT';
 
BYTES/1024/1024
---------------
             51
 
-- 查看此時該表空間的剩餘空間:大約剩餘9M
SQL> select TABLESPACE_NAME,FILE_ID,BLOCK_ID,BYTES/1024/1024 "size(M)",BLOCKS,RELATIVE_FNO
  2  from dba_free_space where tablespace_name='TP_MOVETEST';
 
TABLESPACE_NAME                   FILE_ID   BLOCK_ID    size(M)     BLOCKS RELATIVE_FNO
------------------------------ ---------- ---------- ---------- ---------- ------------
TP_MOVETEST                               15       6537          8.9375       1144           15
 
-- 執行 move 失敗:無法擴展臨時段
SQL> alter table test_yct move;
alter table test_yct move
            *
ERROR 位於第 1 行:
ORA-01652: 無法通過128(在表空間TP_MOVETEST中)擴展 temp 段
 
-- 增大表空間,move 成功。
SQL> alter database datafile 'd:\tp_movetest1.dbf' resize 80m;
 
數據庫已更改。
 
SQL> alter table test_yct move;
 
表已更改。
 
-- 表已被收縮
SQL> select bytes/1024/1024 from user_segments where segment_name='TEST_YCT';
 
BYTES/1024/1024
---------------
             19
 
-- 查看錶空間此時的剩餘空間:舊段佔用的51M空間被釋放;新開闢的段佔用了19M,剩餘大約10M。
SQL> select TABLESPACE_NAME,FILE_ID,BLOCK_ID,BYTES/1024/1024 "size(M)",BLOCKS,RELATIVE_FNO
  2  from dba_free_space where tablespace_name='TP_MOVETEST';
 
TABLESPACE_NAME                   FILE_ID   BLOCK_ID    size(M)     BLOCKS RELATIVE_FNO
------------------------------ ---------- ---------- ---------- ---------- ------------
TP_MOVETEST                            15                 9           51         6528           15
TP_MOVETEST                            15             8969     9.9375         1272           1
鏈接:http://blog.chinaunix.net/space.php?uid=298599&do=blog&id=2443067
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章