使用movetable收缩表空间
目的:收回目前沒有使用過的表空間,減小數據文件大小。
難點:插入的歷史數據可能分布在不同的磁盤位置上,所以無法確定resize datafile能不能成功執行。
解決方式:通過move一個tablespace上的所有對象到一個新的臨時表空間上來降低表的hwm,從而減少數據占用的實際磁盤大小。
?
select?tablespace_name,all_bytes,use_bytes, round(100*use_bytes/all_bytes,2),
free_bytes, round(100*free_bytes/all_bytes,2)
from(
select?/*+ rule use_hash(a,b,c) */?a.tablespace_name,
c.bytes/1024/1024?all_bytes,
a.bytes/1024/1024?use_bytes,
b.bytes/1024/1024?free_bytes
from?
?(select?tablespace_name,sum(bytes) bytes?from?dba_extents?group?by?tablespace_name) a,
?(?select?b.tablespace_name,sum(b.bytes) bytes?from??dba_free_space b?
???group?by?b.tablespace_name
???) b,?
(select?tablespace_name,sum(bytes) bytes
from?dba_data_files
group?by?tablespace_name) c?
where?a.tablespace_name = b.tablespace_name
??and?a.tablespace_name = c.tablespace_name
)
| 表空間 | 總大小 | 對象占用空間 | 占用比率 | free大小 | free比率 |
| CTL | 500 | 5.875 | 1.18 | 494.0625 | 98.81 |
| CWMLITE | 20 | 17.6875 | 88.44 | 2.25 | 11.25 |
| DP23 | 10 | 2.5 | 25 | 7.4375 | 74.38 |
| DRSYS | 20 | 9.625 | 48.13 | 10.3125 | 51.56 |
| DWD | 4000 | 337.1875 | 8.43 | 3662.75 | 91.57 |
| DWI | 6144 | 212.1875 | 3.45 | 5931.625 | 96.54 |
| EXAMPLE | 139.375 | 138.9375 | 99.69 | 0.375 | 0.27 |
| FBI | 200 | 120.875 | 60.44 | 79.0625 | 39.53 |
| OD | 500 | 93.125 | 18.63 | 406.8125 | 81.36 |
| ODM | 20 | 9.3125 | 46.56 | 10.625 | 53.13 |
| ODSD | 22528 | 1737.8125 | 7.71 | 20789.5 | 92.28 |
| ODSI | 12288 | 835.9375 | 6.8 | 11451.69 | 93.19 |
| RPTD | 1024 | 100.5 | 9.81 | 923.4375 | 90.18 |
| RPTI | 1024 | 222 | 21.68 | 801.9375 | 78.31 |
| SYSTEM | 1040 | 1033.6875 | 99.39 | 6.25 | 0.6 |
| TCLKING | 5 | 4.875 | 97.5 | 0.0625 | 1.25 |
| TODSD | 10240 | 1212.0625 | 11.84 | 9027.625 | 88.16 |
| TODSI | 10240 | 401.1875 | 3.92 | 9838.5 | 96.08 |
| UNDOTBS1 | 27055 | 731.578125 | 2.7 | 26323.19 | 97.3 |
| USERS | 82.5 | 82.375 | 99.85 | 0.0625 | 0.08 |
| XDB | 46.875 | 44.25 | 94.4 | 2.5625 | 5.47 |
?
?
測試步驟
1,??建立測試用表空間
SQL> create tablespace HWM
??2??datafile '/oradata/HWM01.dbf' size 5000M;
?
2,??move table對索引的影響
首先,賦權給將需要move的用戶DW。
SQL> alter user DW quota unlimited on HWM;
檢查對象當前大小
select?de.owner,de.segment_name,de.segment_type,de.tablespace_name,sum(de.blocks),sum(de.bytes)
from?dba_extents de
where?de.tablespace_name?like?'DW_'?and?SEGMENT_name?like?'%CREDIT%'
group?by?de.owner,de.segment_name,de.segment_type,de.tablespace_name
| 用戶 | 對象 | 類型 | 表空間 | blocks | bytes |
| DW | F_CREDIT | TABLE | DWD | 4736 | 38797312 |
| DW | F_CREDIT_U1 | INDEX | DWI | 6400 | 52428800 |
2.1?移動普通表對象到新建表空間HWM
SQL> alter table F_CREDIT move tablespace HWM;
Move一個表到另外一個表空間時,索引不會跟著一塊move,而且會失效。(LOB類型例外)
在創建失效的索引之前,使用到索引的查詢語句將會報錯。失效的索引需要使用rebuild來重現創建。
Alter index index_name rebuild;
Alter index pk_name rebuild;
如果我們需要move索引到另外一個表空間,則需要使用rebuild
Alter index index_name rebuild tablespace tbs_name;
Alter index pk_name rebuild tablespace tbs_name;
2.2 move分區表及索引
??和普通表一樣,索引也會失效,區別的僅僅是語法而已。
分區表move基本語法
如果是單級分區,則使用關鍵字partition,如果是多級分區,則使用subpartition替代partition。如果分區或分區索引比較大,可以使用并行move或rebuild,parallel(degree 2)。
select?'alter table '||owner||'.'||segment_name||' move partition '?||partition_name||' tablespace HWM; ',bytes
?from?dba_segments?where?segment_name =?'F_DISTRIBUTION'and?segment_type =?'TABLE PARTITION'
alter?table?DW.F_DISTRIBUTION?move?partition?F_DISTRIBUTION_P00?tablespace?HWM;?
alter?table?DW.F_DISTRIBUTION?move?partition?F_DISTRIBUTION_P01?tablespace?HWM;?
alter?table?DW.F_DISTRIBUTION?move?partition?F_DISTRIBUTION_P02?tablespace?HWM;?
alter?table?DW.F_DISTRIBUTION?move?partition?F_DISTRIBUTION_P03?tablespace?HWM;?
alter?table?DW.F_DISTRIBUTION?move?partition?F_DISTRIBUTION_P04?tablespace?HWM;?
alter?table?DW.F_DISTRIBUTION?move?partition?F_DISTRIBUTION_P05?tablespace?HWM;?
alter?table?DW.F_DISTRIBUTION?move?partition?F_DISTRIBUTION_P06?tablespace?HWM;?
alter?table?DW.F_DISTRIBUTION?move?partition?F_DISTRIBUTION_P07?tablespace?HWM;?
alter?table?DW.F_DISTRIBUTION?move?partition?F_DISTRIBUTION_P08?tablespace?HWM;?
alter?table?DW.F_DISTRIBUTION?move?partition?F_DISTRIBUTION_P09?tablespace?HWM;?
alter?table?DW.F_DISTRIBUTION?move?partition?F_DISTRIBUTION_P10?tablespace?HWM;?
alter?table?DW.F_DISTRIBUTION?move?partition?F_DISTRIBUTION_P11?tablespace?HWM;?
alter?table?DW.F_DISTRIBUTION?move?partition?F_DISTRIBUTION_P12?tablespace?HWM;?
alter?table?DW.F_DISTRIBUTION?move?partition?F_DISTRIBUTION_P13?tablespace?HWM;?
alter?table?DW.F_DISTRIBUTION?move?partition?F_DISTRIBUTION_PMAX?tablespace?HWM;
重建全局索引
Alter index global_index rebuild;
或
Alter index global_index rebuild tablespace tbs_name;
?
重建局部索引
Alter table tab_name modify partition partition_name rebuild unusable local indexes;
或
Alter index local_index_name rebuild partition partition_name tablespace tbs_name;
?
提示:
USER_PART_TABLES
USER_IND_PARTITIONS
USER_IND_SUBPARTITIONS
USER_LOB_PARTITIONS
USER_LOB_SUBPARTITIONS
USER_PART_INDEXES
USER_PART_LOBS
可查詢分區相關內容,同時,分區對象,也是segment,所以也可在dba_segments里查的到。
三:move LONG,LOB類型
據說DBMS_REDEFINITION包可以提供一些方便,沒用過。
IONG類型
long類型不能通過MOVE來傳輸
特別提示,盡量不要用LONG類型,特難管理。
參考:http://www.anysql.net/2005/12/long_vs_lob.html
1,LONG不能使用insert into ... select ...等帶select的模式。
如
create table t123 (id int,en long);
則
insert into t123(id,en) select * from t123;
報告錯誤,可以用pl/sql來幫助解決,如:
declare?
cursor cur_t123 is select * from t123;
use_t123 cur_t123%rowtype;
begin
open cur_t123;
loop
fetch cur_t123 into use_t123;
exit when cur_t123%notfound;
insert into t123(id,en) values (use_t123.id,use_t123.en);
end loop;
close cur_t123;
end;
/
對有LONG類型字段的表的轉移,可以使用:
create新表的方法。
* create一個新的表,存儲在需要轉移的表空間。
*?創建新的索引(使用tablespace?子句指定新的表空間)。
*?把數據轉移過來
方法一:用COPY的方法:
copy from bigboar/bigboar@bigboar_sid insert t123(id,en) using select id,en from t123;
方法二:PL/SQL(如上)
方法三:直接就把LONG轉換成CLOB類型
create table t321(id int,en clob) tablespace users;?
insert into t321(id,en) select id,to_lob(en) from t123;?
方法四:exp/imp
exp bigboar/bigboar file=a.dat tables=t123
imp bigboar/bigboar file=a.dat full=y IGNORE =y
* drop掉舊表。
* rename?新表為舊表表名。
IOB類型
在建立含有lob字段的表時,oracle會自動為lob字段建立兩個單獨的segment,一個用來存放數據(segment_type=LOBSEGMENT),另一個用來存
放索引(segment_type=LOBINDEX)。默認它們會存儲在和表一起的表空間。
我們對表MOVE時,LOG類型字段和該字段的索引不會跟著MOVE,必須要單獨來進行MOVE,語法如下如:
alter table t321 move tablespace users;
alter table t321 move lob(en) store as (tablespace users);
?
?
?
3,對一個表空間下的所有數據執行move table
CTL表空間的文件
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的使用movetable收缩表空间的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一个释放临时表空间的实例
- 下一篇: Undo TableSpace ②.回滚