oracle数据库表空间文件收缩实例
Oracle數據文件收縮實例
數據文件的作用
???
?
HWM的基本概念
???
?
?
查看數據文件的使用情況
包括內容:數據文件大小,已經used空間,free空間,hwm信息
select?/*+ ordered use_hash(a,b,c) */
a.file_id,a.file_name,a.filesize, b.freesize,
(a.filesize-b.freesize) usedsize,
?c.hwmsize,
?c.hwmsize - (a.filesize-b.freesize) unsedsize_belowhwm,
?a.filesize - c.hwmsize canshrinksize?
from?
(
select?file_id,file_name,round(bytes/1024/1024) filesize?from?dba_data_files
) a,
(
select?file_id,round(sum(dfs.bytes)/1024/1024) freesize?from?dba_free_space dfs
group?by?file_id
) b,
(
select?file_id,round(max(block_id)*8/1024) HWMsize?from?dba_extents
group?by?file_id) c
where?a.file_id = b.file_id
??and?a.file_id = c.file_id
order?by?unsedsize_belowhwm?desc
結果說明:
File_id?:?文件編號
File_name:?文件名稱
File_size:?數據文件占用磁盤空間大小
Freesize:文件中被標記為free的空間大小
Usedsize:?使用的空間大小。
Hwmsize:?已經分配出去的空間大小,如果希望通過alter database datafile … resize integerM回收空間,將需要這個值作為參考,不能回收到這個值之下,否則會報錯。
Freee_belowhwm_size:?在HWM(高水位標記線之下的空閑空間數),這個是理論上的可以回收的空間大小。
Curr_can_shrink:?這個是實際大小與HWM標記之間的差,就是還沒有分配出去的空間大小。
| file_id | file_name | filesize | freesize | usedsize | hwmsize | free_belowhwm_size | curr_can_shrink |
| 11 | /oradata/ODSD01.dbf | 2048 | 1908 | 140 | 2048 | 1908 | 0 |
| 12 | /oradata/ODSD02.dbf | 2048 | 1897 | 151 | 2048 | 1897 | 0 |
| 20 | /oradata/ODSD10.dbf | 2048 | 1897 | 151 | 2048 | 1897 | 0 |
| 16 | /oradata/ODSD06.dbf | 2048 | 1889 | 159 | 2048 | 1889 | 0 |
| 15 | /oradata/ODSD05.dbf | 2048 | 1888 | 160 | 2048 | 1888 | 0 |
| 19 | /oradata/ODSD09.dbf | 2048 | 1885 | 163 | 2048 | 1885 | 0 |
| 13 | /oradata/ODSD03.dbf | 2048 | 1884 | 164 | 2048 | 1884 | 0 |
| 17 | /oradata/ODSD07.dbf | 2048 | 1884 | 164 | 2048 | 1884 | 0 |
| 14 | /oradata/ODSD04.dbf | 2048 | 1813 | 235 | 2041 | 1806 | 7 |
| 34 | /oradata/DWD01.dbf | 4000 | 3701 | 299 | 2088 | 1789 | 1912 |
| 51 | /oradata/ODSD11.dbf | 2048 | 1963 | 85 | 1584 | 1499 | 464 |
| 21 | /oradata/ODSI01.dbf | 2048 | 1913 | 135 | 1617 | 1482 | 431 |
| 25 | /oradata/ODSI05.dbf | 2048 | 1910 | 138 | 1607 | 1469 | 441 |
| 22 | /oradata/ODSI02.dbf | 2048 | 1903 | 145 | 1606 | 1461 | 442 |
| 24 | /oradata/ODSI04.dbf | 2048 | 1909 | 139 | 1592 | 1453 | 456 |
| 23 | /oradata/ODSI03.dbf | 2048 | 1892 | 156 | 1603 | 1447 | 445 |
| 48 | /oradata/ODSI06.dbf | 2048 | 1925 | 123 | 1559 | 1436 | 489 |
| 30 | /oradata/TODSD05.dbf | 2048 | 1804 | 244 | 1315 | 1071 | 733 |
| 18 | /oradata/ODSD08.dbf | 2048 | 1881 | 167 | 1225 | 1058 | 823 |
| 27 | /oradata/TODSD02.dbf | 2048 | 1818 | 230 | 1244 | 1014 | 804 |
| 31 | /oradata/TODSI01.dbf | 2048 | 1977 | 71 | 936 | 865 | 1112 |
| 35 | /oradata/DWI01.dbf | 2048 | 1973 | 75 | 936 | 861 | 1112 |
| 32 | /oradata/TODSI02.dbf | 2048 | 1969 | 79 | 867 | 788 | 1181 |
| 43 | /oradata/DWI03.dbf | 2048 | 1975 | 73 | 802 | 729 | 1246 |
| 42 | /oradata/DWI02.dbf | 2048 | 1983 | 65 | 755 | 690 | 1293 |
| 39 | /oradata/TODSI04.dbf | 2048 | 1971 | 77 | 680 | 603 | 1368 |
| 26 | /oradata/TODSD01.dbf | 2048 | 1819 | 229 | 830 | 601 | 1218 |
| 40 | /oradata/TODSI05.dbf | 2048 | 1976 | 72 | 609 | 537 | 1439 |
| 28 | /oradata/TODSD03.dbf | 2048 | 1793 | 255 | 702 | 447 | 1346 |
| 37 | /oradata/TODSI03.dbf | 2048 | 1946 | 102 | 450 | 348 | 1598 |
| 29 | /oradata/TODSD04.dbf | 2048 | 1793 | 255 | 485 | 230 | 1563 |
| 33 | /oradata/CTL01.dbf | 500 | 494 | 6 | 21 | 15 | 479 |
| 10 | /oradata/xdb01.dbf | 47 | 3 | 44 | 46 | 2 | 1 |
| 1 | /oradata/system01.dbf | 1040 | 6 | 1034 | 1034 | 0 | 6 |
| 3 | /oradata/cwmlite01.dbf | 20 | 2 | 18 | 18 | 0 | 2 |
| 4 | /oradata/drsys01.dbf | 20 | 10 | 10 | 10 | 0 | 10 |
| 36 | /oradata/OD01.dbf | 500 | 407 | 93 | 93 | 0 | 407 |
| 5 | /oradata/example01.dbf | 139 | 0 | 139 | 139 | 0 | 0 |
| 54 | /oradata/TCLKING.dbf | 5 | 0 | 5 | 5 | 0 | 0 |
| 56 | /oradata/undotbs03.dbf | 1000 | 996 | 4 | 4 | 0 | 996 |
| 55 | /oradata/HWM01.dbf | 5000 | 4963 | 37 | 37 | 0 | 4963 |
| 49 | /oradata/DP23.dbf | 10 | 7 | 3 | 3 | 0 | 7 |
| 7 | /oradata/odm01.dbf | 20 | 11 | 9 | 9 | 0 | 11 |
| 9 | /oradata/users01.dbf | 83 | 0 | 83 | 82 | -1 | 1 |
| 46 | /oradata/RPTI01.dbf | 1024 | 802 | 222 | 221 | -1 | 803 |
| 45 | /oradata/RPTD01.dbf | 1024 | 923 | 101 | 100 | -1 | 924 |
| 38 | /oradata/FBI.dbf | 200 | 79 | 121 | 120 | -1 | 80 |
?
?
?
?
?
對想收縮的表空間中的表及索引進行rebuild
建立測試表空間
SQL> create tablespace HWM datafile ‘/oradata/HWM01.dbf’ size 5000M;
??Tablespace created;
?
SQL> alter tablespace HWM add datafile '/oradata/HWM02.dbf' size 5000M;
Tablespace altered
move表空間的long類型
LONG類型的數據超難管理,不能通過move來傳輸,也不能通過諸如insert t1 select long_col from t2的方式(或者使用游標可以解決這個問題)請注意在設計中盡量避免使用LONG類型。
檢查當前表空間中的LONG類型字段。
select?/*+use_hash(ds,dtc)*/
ds.tablespace_name,ds.owner||'.'||ds.segment_name,ds.segment_type,
dtc.DATA_TYPE,dtc.COLUMN_NAME
from?dba_tab_columns dtc , dba_segments ds
where?dtc.TABLE_NAME = ds.segment_name?
and?dtc.OWNER = ds.owner?
and?ds.tablespace_name?not?in?('SYSTEM','CWMLITE','EXAMPLE','UNDOTBS2','HWM')
and?data_type =?'LONG'
| tablespace | segmentname | segtype | datatype | colname |
| CTL | CTL.ETL_LOG | TABLE | LONG | EXECUTE_SQL |
| CTL | CTL.PLAN_TABLE | TABLE | LONG | OTHER |
| DWD | DW.PLAN_TABLE | TABLE | LONG | OTHER |
| CTL | OD.PLAN_TABLE | TABLE | LONG | OTHER |
| FBI | FBI.PLAN_TABLE | TABLE | LONG | OTHER |
?
對long類型的數據處理的一個簡單的方法實將LONG類型字段直接修改為LOB類型。
select?/*+use_hash(ds,dtc)*/
'alter table '||ds.owner||'.'||ds.segment_name||' modify '||dtc.COLUMN_NAME||' clob;'
from?dba_tab_columns dtc , dba_segments ds
where?dtc.TABLE_NAME = ds.segment_name?
and?dtc.OWNER = ds.owner?
and?ds.tablespace_name?not?in?('SYSTEM','CWMLITE','EXAMPLE','UNDOTBS2','HWM')
and?data_type =?'LONG'
| 修改類型語句 |
| alter table CTL.ETL_LOG modify EXECUTE_SQL clob; |
| alter table CTL.PLAN_TABLE modify OTHER clob; |
| alter table DW.PLAN_TABLE modify OTHER clob; |
| alter table OD.PLAN_TABLE modify OTHER clob; |
| alter table FBI.PLAN_TABLE modify OTHER clob; |
SQL> alter table CTL.ETL_LOG modify EXECUTE_SQL clob;
?
Table altered
?
SQL> alter table CTL.PLAN_TABLE modify OTHER clob;
?
Table altered
?
SQL> alter table DW.PLAN_TABLE modify OTHER clob;
?
Table altered
?
SQL> alter table OD.PLAN_TABLE modify OTHER clob;
?
Table altered
?
SQL> alter table FBI.PLAN_TABLE modify OTHER clob;
?
Table altered
move表空間下的普通table及index
SQL> alter table tbname move tablespace newtbname;
Move一個表到另外一個表空間時,索引不會跟著一塊move,而且會失效。在創建失效的索引之前,使用到索引的查詢語句將會報錯。失效的索引需要使用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;
?
select??ds.tablespace_name,'alter table '||ds.owner||'.'||ds.segment_name||' move tablespace HWM;'
from?dba_segments ds?
where?ds.tablespace_name?not?in('SYSTEM','CWMLITE','EXAMPLE','UNDOTBS2',
???'HWM','XDB','WKSYS','CTXSYS','ODM_MTR','USERS','DRSYS','HTEC','HAPPYTREE')
??and?ds.segment_type =?'TABLE';
SQL> alter table ODS.SM_PRODUCT_SPEC_SHOW move tablespace HWM;
?
Table altered
?
SQL> alter table DW.D_PRODUCT_INFO move tablespace HWM;
?
Table altered
?
?
select??ds.tablespace_name,'alter INDEX '||ds.owner||'.'||ds.segment_name||' rebuild tablespace HWM;'
from?dba_segments ds?
where?ds.tablespace_name?not?in('SYSTEM','CWMLITE','EXAMPLE','UNDOTBS2',
???'HWM','XDB','WKSYS','CTXSYS','ODM_MTR','USERS','DRSYS','HTEC','HAPPYTREE')
??and?ds.segment_type =?'INDEX'
…
SQL> alter INDEX CTL.IDX_TL_ADJUSTMENT_CONFIRMDATE rebuild tablespace HWM;
?
Index altered
?
SQL> alter INDEX CTL.IDX_TL_ADJUSTMENT_ORDER rebuild tablespace HWM;
?
Index altered
…
move表空間下的分區table及index
和普通表一樣,索引也會失效,區別的僅僅是語法而已。
分區表move基本語法
如果是單級分區,則使用關鍵字partition,如果是多級分區,則使用subpartition替代partition。如果分區或分區索引比較大,可以使用并行move或rebuild,parallel(degree 2)。
重建全局索引
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;
?
Move分區表
select?cname
from?(
select??rownum?rm,'alter table '||ds.owner||'.'||ds.segment_name||' move partition '||ds.partition_name||' tablespace HWM;'?cname
from?dba_segments ds?
where?ds.tablespace_name?not?in('SYSTEM','CWMLITE','EXAMPLE','UNDOTBS2',
???'HWM','XDB','WKSYS','CTXSYS','ODM_MTR','USERS','DRSYS','HTEC','HAPPYTREE')
??and?ds.segment_type =?'TABLE PARTITION'
) c
where?rm?between?1?and?100;
循環執行上述語句,直到選不出結果。
SQL> alter table ODS.CR_PS_INVENTORY_ITEM move partition CR_PS_INVENTORY_ITEM_P070603 tablespace HWM;
?
Table altered
?
SQL> alter table ODS.CR_PS_INVENTORY_ITEM move partition CR_PS_INVENTORY_ITEM_P070604 tablespace HWM;
?
Table altered
?
重建全局索引
????Oracle的全局索引也存儲在dba_segments中,并以index標志,而且其重建方式跟普通索引一致,所以在執行忘回導入的時候需要按照move?普通表;move分區表;move全局索引;move分區索引;move lob對象的順序進行。
重建分區索引
視圖dba_part_indexes存儲分區表的本地索引,查詢發現當前系統中不存在本地索引,可以忽略。
select?*?from?dba_part_indexes t?where?t.owner?not?in?('SYSTEM','SH')
move表空間下的LOB類型
在建立含有Lob字典的表時,oracle會自動為Lob字段建立兩個單獨的segment,一個用來存放數據(segment_type=LOBSEGMENT),另一個用來存放索引(segment_type=LOBINDEX)。默認他們會存儲在和表一起的表空間。
我們對表move時,LOB類型字段和該字段索引不會跟著move,必須使用單據的語句來執行該字段的move,語法如下:
Alter table t321 move tablespace HWM;
Later table t321 move lob(en) store as (tablespace HWM);
select??'alter table '||dtc.owner||'.'||dtc.TABLE_NAME||' move lob('||dtc.COLUMN_NAME||') store as(tablespace HWM);'
from?dba_tab_columns dtc
where?dtc.OWNER??in('CTL','DW','RPT','OD','ODS','TODS','FBI','DP22','DP23','TCLKING')
??and?dtc.DATA_TYPE?like?'%LOB'
SQL> alter table DP22.D_KPI move lob(KPIFORM) store as(tablespace HWM);
?
Table altered
?
SQL> alter table DP22.D_KPI move lob(KPIFORMDSPN) store as(tablespace HWM);
?
Table altered
?
執行完上述操作步驟后,我們檢查tablespace的空間使用情況可以發現,所有相關數據文件的hwm都已經變為0,也就是說所有的空間都已經變為未分配狀態。但這時如果我們將數據文件dump出去,會發現原來的數據還在,只不過在數據字典中將其標識為未分配。
?
Move對象的逆順序
普通表對象
將普通表對象和分區表對象按照其owner的不同從HWM臨時表空間move到其默認的表空間中區。
select??ds.tablespace_name,'alter table '||ds.owner||'.'||ds.segment_name||' move tablespace '||du.default_tablespace||';'
from?dba_segments ds , dba_users du
where?ds.owner = du.username
??and?ds.owner?in?('CTL','DW','RPT','OD','ODS','TODS','FBI','DP22','DP23','TCLKING')
??and?ds.tablespace_name =?'HWM'
??and?ds.segment_type =?'TABLE';
?
SQL> alter table TODS.CR_PARTY_RELATIONSHIP move tablespace TODSD;
?
Table altered
?
SQL> alter table TODS.CR_PARTY_RELATIONSHIP_TYPE move tablespace TODSD;
?
Table altered
分區表對象
select?cname
from?(
select??rownum?rm,'alter table '||ds.owner||'.'||ds.segment_name||' move partition '||ds.partition_name||' tablespace '||du.default_tablespace||';'?cname
from?dba_segments ds , dba_users du
where?ds.owner = du.username
??and?ds.owner?in?('CTL','DW','RPT','OD','ODS','TODS','FBI','DP22','DP23','TCLKING')
??and?ds.tablespace_name =?'HWM'
??and?ds.segment_type =?'TABLE PARTITION'
) c
where?rm?between?1?and?500;
?
反復執行上述過程,直到沒有記錄可以選擇。
?
SQL> alter table ODS.CR_PS_INVENTORY_ITEM move partition CR_PS_INVENTORY_ITEM_P080513 tablespace ODSD;
?
Table altered
?
SQL> alter table ODS.CR_PS_INVENTORY_ITEM move partition CR_PS_INVENTORY_ITEM_P080514 tablespace ODSD;
?
Table altered
索引對象
????索引對象存儲的tablespace的命令標準為username+’I’,如果類似的表空間不存在,我們就將索引數據存儲到用戶的默認表空間中。所以我們可以使用下面的語句將index rebuild到對應的表空間中。
select??'alter INDEX '||ds.owner||'.'||ds.segment_name||' rebuild tablespace '||nvl(dt.tablespace_name,du.default_tablespace)||';'
from?dba_segments ds , dba_users du, dba_tablespaces dt
where?ds.owner = du.username
??and?dt.tablespace_name(+) = du.username||'I'
??and?ds.owner?in?('CTL','DW','RPT','OD','ODS','TODS','FBI','DP22','DP23','TCLKING')
??and?ds.tablespace_name =?'HWM'
??and?ds.segment_type =?'INDEX'
LOB類型
Lob類型數據隨著table對象存儲在對象owner的默認表空間中。
?
select??'alter table '||dtc.owner||'.'||dtc.TABLE_NAME||' move lob('||dtc.COLUMN_NAME||') store as(tablespace '||du.default_tablespace||');'?
from?dba_tab_columns dtc,dba_users du
where?dtc.OWNER = du.username
??and?dtc.OWNER??in('CTL','DW','RPT','OD','ODS','TODS','FBI','DP22','DP23','TCLKING')
??and?dtc.DATA_TYPE?like?'%LOB'
?
SQL> alter table FBI.TIME_FORMAT move lob(FORMAT) store as(tablespace FBI);
?
Table altered
?
SQL> alter table FBI.URLTABLE move lob(DETAIL) store as(tablespace FBI);
?
Table altered
?
SQL> alter table OD.PLAN_TABLE move lob(OTHER) store as(tablespace OD);
?
Table altered
?
收縮空閑表空間
首先,如果沒有分配的空間不足100M,則不考慮收縮。
收縮目標:當前數據文件大小 - (沒分配空間-?100M)×0.8?
?
select?/*+ ordered use_hash(a,c) */
??'alter database datafile '''||a.file_name||''' resize '
???||round(a.filesize - (a.filesize - c.hwmsize-100) *0.8)||'M;',
??a.filesize,
??c.hwmsize
from?
(
select?file_id,file_name,round(bytes/1024/1024) filesize?from?dba_data_files
) a,
(
select?file_id,round(max(block_id)*8/1024) HWMsize?from?dba_extents
group?by?file_id) c
where?a.file_id = c.file_id
??and?a.filesize - c.hwmsize >?100
?
| 收縮語句 | 文件大小 | 收縮目標 |
| alter database datafile '/oradata/HWM02.dbf' resize 2671M; | 5000 | 1989 |
| alter database datafile '/oradata/ODSD01.dbf' resize 598M; | 2048 | 136 |
| alter database datafile '/oradata/ODSD02.dbf' resize 592M; | 2048 | 128 |
| alter database datafile '/oradata/ODSD03.dbf' resize 591M; | 2048 | 127 |
| alter database datafile '/oradata/ODSD04.dbf' resize 742M; | 2048 | 316 |
| alter database datafile '/oradata/ODSD05.dbf' resize 594M; | 2048 | 130 |
| alter database datafile '/oradata/ODSD06.dbf' resize 597M; | 2048 | 134 |
| alter database datafile '/oradata/ODSD07.dbf' resize 598M; | 2048 | 135 |
| alter database datafile '/oradata/ODSD08.dbf' resize 472M; | 1470 | 122 |
| alter database datafile '/oradata/ODSD09.dbf' resize 587M; | 2048 | 122 |
| alter database datafile '/oradata/ODSD10.dbf' resize 595M; | 2048 | 132 |
| alter database datafile '/oradata/ODSI01.dbf' resize 507M; | 1783 | 88 |
| alter database datafile '/oradata/ODSI02.dbf' resize 505M; | 1774 | 88 |
| alter database datafile '/oradata/ODSI03.dbf' resize 529M; | 1772 | 118 |
| alter database datafile '/oradata/ODSI04.dbf' resize 517M; | 1763 | 105 |
| alter database datafile '/oradata/ODSI05.dbf' resize 525M; | 1775 | 113 |
| alter database datafile '/oradata/TODSD01.dbf' resize 497M; | 1154 | 233 |
| alter database datafile '/oradata/TODSD02.dbf' resize 561M; | 1485 | 230 |
| alter database datafile '/oradata/TODSD03.dbf' resize 465M; | 1051 | 218 |
| alter database datafile '/oradata/TODSD04.dbf' resize 431M; | 878 | 219 |
| alter database datafile '/oradata/TODSD05.dbf' resize 598M; | 1542 | 262 |
| alter database datafile '/oradata/TODSI01.dbf' resize 385M; | 1238 | 72 |
| alter database datafile '/oradata/TODSI02.dbf' resize 365M; | 1183 | 60 |
| alter database datafile '/oradata/CTL01.dbf' resize 146M; | 197 | 33 |
| alter database datafile '/oradata/DWD01.dbf' resize 770M; | 2550 | 225 |
| alter database datafile '/oradata/DWI01.dbf' resize 386M; | 1238 | 73 |
| alter database datafile '/oradata/OD01.dbf' resize 152M; | 254 | 27 |
| alter database datafile '/oradata/TODSI03.dbf' resize 288M; | 850 | 48 |
| alter database datafile '/oradata/TODSI04.dbf' resize 324M; | 1034 | 46 |
| alter database datafile '/oradata/TODSI05.dbf' resize 343M; | 977 | 84 |
| alter database datafile '/oradata/DWI02.dbf' resize 356M; | 1094 | 72 |
| alter database datafile '/oradata/DWI03.dbf' resize 366M; | 1131 | 75 |
| alter database datafile '/oradata/RPTD01.dbf' resize 231M; | 365 | 98 |
| alter database datafile '/oradata/RPTI01.dbf' resize 300M; | 462 | 159 |
| alter database datafile '/oradata/ODSI06.dbf' resize 505M; | 1737 | 97 |
| alter database datafile '/oradata/ODSD11.dbf' resize 535M; | 1757 | 129 |
| alter database datafile '/oradata/undotbs03.dbf' resize 176M; | 283 | 49 |
?
?
檢查磁盤當前剩余空間
$ bdf
/dev/vg01/lvol1????133120000 33173720 99166120???25% /oradata
?
小結
執行整個步驟之前,/oradata磁盤下的剩余空間不足6G,執行步驟之后我們看到,目前系統中有將近100G的剩余空間^_^。
效果明顯。
總結
以上是生活随笔為你收集整理的oracle数据库表空间文件收缩实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用movetable收缩表空间
- 下一篇: linux cmake编译源码,linu