如何收縮表空間大小


轉摘:

oracle數據庫表空間文件收縮實例

1.查看數據文件的使用情況

包括內容:數據文件大小,已經used空間,free空間,hwm信息

 1 select /*+ ordered use_hash(a,b,c) */
 2 a.file_id,a.file_name,a.filesize, b.freesize,
 3 (a.filesize-b.freesize) usedsize,
 4  c.hwmsize,
 5  c.hwmsize - (a.filesize-b.freesize) unsedsize_belowhwm,
 6  a.filesize - c.hwmsize canshrinksize 
 7 from 
 8 (
 9 select file_id,file_name,round(bytes/1024/1024) filesize from dba_data_files
10 ) a,
11 (
12 select file_id,round(sum(dfs.bytes)/1024/1024) freesize from dba_free_space dfs
13 group by file_id
14 ) b,
15 (
16 select file_id,round(max(block_id)*8/1024) HWMsize from dba_extents
17 group by file_id) c
18 where a.file_id = b.file_id
19   and a.file_id = c.file_id
20 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標記之間的差,就是還沒有分配出去的空間大小。

2.對想收縮的表空間中的表及索引進行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
建立測試案例

2.1move表空間的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'
View Code

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'
View Code

修改類型語句

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
View Code

2.2move表空間下的普通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';
View Code
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
View Code
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'
View Code
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
View Code

2.3move表空間下的分區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;

  2.3.1Move分區表
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;
View Code

  循環執行上述語句,直到選不出結果。

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
View Code

重建全局索引
    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');

2.3.2move表空間下的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'
View Code
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
View Code

  執行完上述操作步驟后,我們檢查tablespace的空間使用情況可以發現,所有相關數據文件的hwm都已經變為0,也就是說所有的空間都已經變為未分配狀態。但這時如果我們將數據文件dump出去,會發現原來的數據還在,只不過在數據字典中將其標識為未分配。

2.4Move對象的逆順序

2.4.1普通表對象  

  將普通表對象和分區表對象按照其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';
View Code
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
View Code

 

2.4.2分區表對象
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;
View Code

反復執行上述過程,直到沒有記錄可以選擇。

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
View Code
  2.4.3索引對象   

  索引對象存儲的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'
View Code
2.4.4LOB類型

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'
View Code
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
View Code

3.收縮空閑表空間

首先,如果沒有分配的空間不足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
收縮表空間

 

select 
owner
,segment_name
,segment_type
,tablespace_name
from dba_extents
where file_id=6
and 193673
between block_id and block_id + blocks - 1
;
查義最大數據塊對應的表

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM